summaryrefslogtreecommitdiff
path: root/cpp/src/slice2cpp/Gen.cpp
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2016-03-10 22:40:49 +0100
committerJose <jose@zeroc.com>2016-03-10 22:40:49 +0100
commite01092bc3d0c315e567a2f8dbd843cc1062e28ae (patch)
treeb2109b4fe190145a8a467bab24f29f3078e5d1de /cpp/src/slice2cpp/Gen.cpp
parentC# doc comment fix (diff)
downloadice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.tar.bz2
ice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.tar.xz
ice-e01092bc3d0c315e567a2f8dbd843cc1062e28ae.zip
Windows wide string literal fixes
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r--cpp/src/slice2cpp/Gen.cpp106
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;