2006-05-02 Robert Jordan <robertj@gmx.net>
authorRobert Jordan <robertj@gmx.net>
Tue, 2 May 2006 23:00:47 +0000 (23:00 -0000)
committerRobert Jordan <robertj@gmx.net>
Tue, 2 May 2006 23:00:47 +0000 (23:00 -0000)
* monoresgen.cs (TxtResourceReader/Writer): Support escapes
(\n, \r, \t, \\) in input and output. Fixes bug #78270 and
an internal TODO.

svn path=/trunk/mcs/; revision=60197

mcs/tools/resgen/ChangeLog [changed mode: 0755->0644]
mcs/tools/resgen/monoresgen.cs

old mode 100755 (executable)
new mode 100644 (file)
index 38fc051..84b9b83
@@ -1,3 +1,9 @@
+2006-05-02  Robert Jordan  <robertj@gmx.net>
+
+       * monoresgen.cs (TxtResourceReader/Writer): Support escapes
+       (\n, \r, \t, \\) in input and output. Fixes bug #78270 and
+       an internal TODO.
+
 2006-04-11  Gert Driesen  <gert.driesen@telenet.be>
            Raja R Harinath  <rharinath@novell.com>
 
index 1ba94915b76d3d11b8d03b4e589e2868032cd133..6579a9967bd65783627e72cb73f87b8620527287 100644 (file)
@@ -8,12 +8,6 @@
  *     Gonzalo Paniagua Javier (gonzalo@ximian.com)
  */
 
-/*
- * TODO:
- * * escape/unescape in the .txt reader/writer to be able to roundtrip values with newlines
- *   (unlike the MS ResGen utility)
- */
-
 using System;
 using System.Text;
 using System.IO;
@@ -195,9 +189,34 @@ class TxtResourceWriter : IResourceWriter {
                throw new Exception ("Objects not valid in a text resource file");
        }
        
-       /* FIXME: handle newlines */
        public void AddResource (string name, string value) {
-               s.WriteLine ("{0}={1}", name, value);
+               s.WriteLine ("{0}={1}", name, Escape (value));
+       }
+
+       // \n -> \\n ...
+       static string Escape (string value)
+       {
+               StringBuilder b = new StringBuilder ();
+               for (int i = 0; i < value.Length; i++) {
+                       switch (value [i]) {
+                       case '\n':
+                               b.Append ("\\n");
+                               break;
+                       case '\r':
+                               b.Append ("\\r");
+                               break;
+                       case '\t':
+                               b.Append ("\\t");
+                               break;
+                       case '\\':
+                               b.Append ("\\\\");
+                               break;
+                       default:
+                               b.Append (value [i]);
+                               break;
+                       }
+               }
+               return b.ToString ();
        }
        
        public void Close () {
@@ -245,9 +264,51 @@ class TxtResourceReader : IResourceReader {
                        val = val.Trim ();
                        if (key.Length == 0) 
                                throw new Exception ("Key is empty at line " + line_num);
+
+                       val = Unescape (val);
+                       if (val == null)
+                               throw new Exception (String.Format ("Unsupported escape character in value of key '{0}'.", key));
+
+
                        data.Add (key, val);
                }
        }
+
+       // \\n -> \n ...
+       static string Unescape (string value)
+       {
+               StringBuilder b = new StringBuilder ();
+
+               for (int i = 0; i < value.Length; i++) {
+                       if (value [i] == '\\') {
+                               if (i == value.Length - 1)
+                                       return null;
+
+                               i++;
+                               switch (value [i]) {
+                               case 'n':
+                                       b.Append ('\n');
+                                       break;
+                               case 'r':
+                                       b.Append ('\r');
+                                       break;
+                               case 't':
+                                       b.Append ('\t');
+                                       break;
+                               case '\\':
+                                       b.Append ('\\');
+                                       break;
+                               default:
+                                       return null;
+                               }
+
+                       } else {
+                               b.Append (value [i]);
+                       }
+               }
+
+               return b.ToString ();
+       }
        
        IEnumerator IEnumerable.GetEnumerator () {
                return ((IResourceReader) this).GetEnumerator();