diff options
author | Jose <jose@zeroc.com> | 2016-03-10 22:40:49 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2016-03-10 22:40:49 +0100 |
commit | e01092bc3d0c315e567a2f8dbd843cc1062e28ae (patch) | |
tree | b2109b4fe190145a8a467bab24f29f3078e5d1de /cpp/src/slice2cpp | |
parent | C# doc comment fix (diff) | |
download | ice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.tar.bz2 ice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.tar.xz ice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.zip |
Windows wide string literal fixes
Diffstat (limited to 'cpp/src/slice2cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 106 |
1 files changed, 90 insertions, 16 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 5df28c48df2..05de885e742 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -35,15 +35,50 @@ string u32CodePoint(unsigned int value) { ostringstream s; - s << "\\U"; - s << hex; - s.width(8); - s.fill('0'); - s << value; + // + // COMPILERFIX: + // With VC++ < 140 characters in the range of 0 to 0x9f cannot be represented + // with a universal character name (UCN). + // + if(value <= 0x9f) + { + switch(value) + { + case 0x22: + { + s << "\\\""; + break; + } + case 0x5c: + { + s << "\\\\"; + break; + } + default: + { + s << "\\"; + s << oct; + s.width(3); + s.fill('0'); + s << value; + break; + } + } + } + // + // UCN valid characters + // + else + { + s << "\\U"; + s << hex; + s.width(8); + s.fill('0'); + s << value; + } return s.str(); } - void writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out) { @@ -117,7 +152,6 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt // Wide strings // vector<unsigned char> u8buffer; // Buffer to convert multibyte characters - out << "L\""; for(size_t i = 0; i < value.size();) { @@ -125,10 +159,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt { if(static_cast<unsigned char>(value[i]) < 128) // Single byte character { - // - // Print as unicode if not in basic source character set - // - out << u32CodePoint(static_cast<unsigned int>(value[i])); + out << u32CodePoint(static_cast<unsigned char>(value[i])); } else { @@ -145,22 +176,65 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt writeU8Buffer(u8buffer, out); u8buffer.clear(); } - + switch(value[i]) { + case '\\': + { + string s = "\\"; + size_t j = i + 1; + for(; j < value.size(); ++j) + { + if(value[j] != '\\') + { + break; + } + s += "\\"; + } + + // + // An even number of slash \ will escape the backslash and + // the codepoint will be interpreted as its charaters + // + // \\U00000041 - ['\\', 'U', '0', '0', '0', '0', '0', '0', '4', '1'] + // \\\U00000041 - ['\\', 'A'] (41 is the codepoint for 'A') + // + if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u')) + { + // + // Convert codepoint to UTF8 bytes and write the escaped bytes + // + out << s.substr(0, s.size() - 1); + + size_t sz = value[j] == 'U' ? 8 : 4; + string codepoint = value.substr(j + 1, sz); + assert(codepoint.size() == sz); + + IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16); + out << u32CodePoint(static_cast<unsigned int>(v)); + + i = j + 1 + sz; + } + else + { + out << s; + i = j; + } + continue; + } case '"': { out << "\\"; break; } } - + out << value[i]; // Print normally if in basic source character set } i++; - + } - + // // Write any pedding characters in the utf8 buffer // @@ -273,7 +347,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt break; } } - + out << value[i]; // Print normally if in basic source character set } ++i; |