diff options
author | Jose <jose@zeroc.com> | 2016-03-10 23:48:38 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2016-03-10 23:48:38 +0100 |
commit | 71c75b16f3d7a0bf4888420c7d24219217615e7f (patch) | |
tree | cc26d4f07203264dd610659529ae4d69da40bfe9 /cpp/src/slice2cpp/Gen.cpp | |
parent | C# doc comment fix (diff) | |
parent | Windows wide string literal fixes (diff) | |
download | ice-71c75b16f3d7a0bf4888420c7d24219217615e7f.tar.bz2 ice-71c75b16f3d7a0bf4888420c7d24219217615e7f.tar.xz ice-71c75b16f3d7a0bf4888420c7d24219217615e7f.zip |
Merge branch '3.6'
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 116 |
1 files changed, 95 insertions, 21 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index cd1edb526fc..de179f26d55 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -82,20 +82,55 @@ isConstexprType(const TypePtr& type) } string -u32CodePoint(unsigned int value) +u32CodePoint(unsigned int value, bool cpp11) { 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(!cpp11 && 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) +writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out, bool cpp11) { vector<unsigned int> u32buffer; IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion); @@ -116,7 +151,7 @@ writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c) { - out << u32CodePoint(*c); + out << u32CodePoint(*c, cpp11); } } @@ -167,7 +202,6 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt // Wide strings or C++11 narrow string // vector<unsigned char> u8buffer; // Buffer to convert multibyte characters - out << (wide ? "L\"" : "u8\""); for(size_t i = 0; i < value.size();) { @@ -175,10 +209,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]), cpp11); } else { @@ -192,31 +223,74 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt // if(!u8buffer.empty()) { - writeU8Buffer(u8buffer, out); + writeU8Buffer(u8buffer, out, cpp11); 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), cpp11); + + 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 // if(!u8buffer.empty()) { - writeU8Buffer(u8buffer, out); + writeU8Buffer(u8buffer, out, cpp11); u8buffer.clear(); } out << "\""; @@ -323,7 +397,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt break; } } - + out << value[i]; // Print normally if in basic source character set } ++i; |