Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhutch <m.j.hutchinson@gmail.com>2015-12-16 01:31:47 +0300
committermhutch <m.j.hutchinson@gmail.com>2015-12-16 01:32:19 +0300
commite85c81fcc09c4af6e502615422d83006694fd617 (patch)
tree1ed5e37afc35ddf4eebfe93a49854f6d9c4a9d7e /main/src/addins/MonoDevelop.Gettext
parent8db8f6bb5018b55135469b4c6118e5fd2f1be62c (diff)
[Gettext] Implement unicode unescaping
Diffstat (limited to 'main/src/addins/MonoDevelop.Gettext')
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/StringEscaping.cs56
1 files changed, 52 insertions, 4 deletions
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/StringEscaping.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/StringEscaping.cs
index 8ae6882391..efe8b973e1 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/StringEscaping.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/StringEscaping.cs
@@ -237,11 +237,21 @@ namespace MonoDevelop.Gettext
sb.Append ('\t');
break;
case 'U':
- //FIXME UNICODE
- //break;
+ uint Uc;
+ if (!TryParseHex (text, i + 1, 8, out Uc) || NeedsEscaping (Uc)) {
+ throw new FormatException ("Invalid escape '\\" + text.Substring (i, 9) + "' in translatable string.");
+ }
+ sb.Append (char.ConvertFromUtf32 ((int)Uc));
+ i += 8;
+ break;
case 'u':
- //FIXME unicode
- //break;
+ uint uc;
+ if (!TryParseHex (text, i + 1, 4, out uc) || NeedsEscaping (uc)) {
+ throw new FormatException ("Invalid escape '\\" + text.Substring (i, 5) + "' in translatable string.");
+ }
+ sb.Append ((char)uc);
+ i += 4;
+ break;
case 'x':
//FIXME hex unicode
//break;
@@ -259,6 +269,44 @@ namespace MonoDevelop.Gettext
}
return sb.ToString ();
}
+
+ static bool NeedsEscaping (uint c)
+ {
+ //TODO: there are other chars we should error on?
+ if (c > char.MaxValue)
+ return false;
+ return char.IsControl ((char)c);
+ }
+
+ static bool TryParseHex (string str, int offset, int length, out uint val)
+ {
+ val = 0x0;
+
+ for (int i = offset; i < offset + length; i++) {
+ uint bits;
+ switch (str[i]) {
+ case '0': bits = 0; break;
+ case '1': bits = 1; break;
+ case '2': bits = 2; break;
+ case '3': bits = 3; break;
+ case '4': bits = 4; break;
+ case '5': bits = 5; break;
+ case '6': bits = 6; break;
+ case '7': bits = 7; break;
+ case '8': bits = 8; break;
+ case '9': bits = 9; break;
+ case 'A': case 'a': bits = 10; break;
+ case 'B': case 'b': bits = 11; break;
+ case 'C': case 'c': bits = 12; break;
+ case 'D': case 'd': bits = 13; break;
+ case 'E': case 'e': bits = 14; break;
+ case 'F': case 'f': bits = 15; break;
+ default: return false;
+ }
+ val = (val << 4) | bits;
+ }
+ return true;
+ }
public enum EscapeMode
{