UCS2 *Parser::Parse_String(bool pathname, bool require) { UCS2 *New = NULL; int len = 0; EXPECT CASE(STRING_LITERAL_TOKEN) New = String_To_UCS2(Token.Token_String, pathname); EXIT END_CASE CASE(STR_TOKEN) New = Parse_Str(pathname); EXIT END_CASE CASE(VSTR_TOKEN) New = Parse_VStr(pathname); EXIT END_CASE CASE(CONCAT_TOKEN) New = Parse_Concat(pathname); EXIT END_CASE CASE(CHR_TOKEN) New = Parse_Chr(pathname); EXIT END_CASE CASE(DATETIME_TOKEN) New = Parse_Datetime(pathname); EXIT END_CASE CASE(SUBSTR_TOKEN) New = Parse_Substr(pathname); EXIT END_CASE CASE(STRUPR_TOKEN) New = Parse_Strupr(pathname); EXIT END_CASE CASE(STRLWR_TOKEN) New = Parse_Strlwr(pathname); EXIT END_CASE CASE(STRING_ID_TOKEN) len = UCS2_strlen(reinterpret_cast<UCS2 *>(Token.Data)) + 1; New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String")); POV_MEMMOVE(reinterpret_cast<void *>(New), reinterpret_cast<void *>(Token.Data), len * sizeof(UCS2)); EXIT END_CASE OTHERWISE if(require) Expectation_Error("string expression"); else { UNGET EXIT } END_CASE END_EXPECT return New; }
UCS2 *Parser::Parse_String(bool pathname, bool require) { UCS2 *New = nullptr; int len = 0; const UCS2String* pString; const StringValue* stringValue = nullptr; EXPECT CASE(STRING_LITERAL_TOKEN) /// @todo Add back support for non-ASCII string encodings. stringValue = dynamic_cast<const StringValue*>(mToken.raw.value.get()); POV_PARSER_ASSERT(stringValue != nullptr); if (pathname) { // Historically, escape sequences were ignored when parsing for a filename. // As of POV-Ray v3.8, this has been changed. if (sceneData->EffectiveLanguageVersion() >= 380) { if (stringValue->IsAmbiguous()) { #if POV_BACKSLASH_IS_PATH_SEPARATOR Warning("Backslash encountered while parsing for a filename." " As of POV-Ray v3.8, this is interpreted as an escape sequence just like in any other string literal." " If this is supposed to be a path separator, use a forward slash instead."); #endif } pString = &stringValue->GetData(); } else { if (stringValue->IsAmbiguous()) { #if POV_BACKSLASH_IS_PATH_SEPARATOR Warning("Backslash encountered while parsing for a filename." " In legacy (pre-v3.8) scenes, this is NOT interpreted as the start of an escape sequence." " However, for future compatibility it is recommended to use a forward slash as path separator instead."); #else Warning("Backslash encountered while parsing for a filename." " In legacy (pre-v3.8) scenes, this is NOT interpreted as the start of an escape sequence."); #endif } pString = &stringValue->GetFileName(); } } else { pString = &stringValue->GetData(); } len = pString->size() + 1; New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String")); std::memcpy(reinterpret_cast<void *>(New), reinterpret_cast<const void *>(pString->c_str()), len * sizeof(UCS2)); EXIT END_CASE CASE(STR_TOKEN) New = Parse_Str(pathname); EXIT END_CASE CASE(VSTR_TOKEN) New = Parse_VStr(pathname); EXIT END_CASE CASE(CONCAT_TOKEN) New = Parse_Concat(pathname); EXIT END_CASE CASE(CHR_TOKEN) New = Parse_Chr(pathname); EXIT END_CASE CASE(DATETIME_TOKEN) New = Parse_Datetime(pathname); EXIT END_CASE CASE(SUBSTR_TOKEN) New = Parse_Substr(pathname); EXIT END_CASE CASE(STRUPR_TOKEN) New = Parse_Strupr(pathname); EXIT END_CASE CASE(STRLWR_TOKEN) New = Parse_Strlwr(pathname); EXIT END_CASE CASE(STRING_ID_TOKEN) len = UCS2_strlen(CurrentTokenDataPtr<UCS2*>()) + 1; New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String")); std::memcpy(reinterpret_cast<void *>(New), CurrentTokenDataPtr<void*>(), len * sizeof(UCS2)); EXIT END_CASE OTHERWISE if(require) Expectation_Error("string expression"); else { UNGET EXIT } END_CASE END_EXPECT return New; }