* rclex.c: (cpp_line): Add code_page pragma support.
authorNick Clifton <nickc@redhat.com>
Mon, 18 Jun 2007 15:30:33 +0000 (15:30 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 18 Jun 2007 15:30:33 +0000 (15:30 +0000)
* windres.c: (usage, long_options, main): Add new option --codepage or -c.
* winduni.c: (wind_default_codepage, wind_current_codepage): New.
  (unicode_from_ascii, ascii_from_unicode): Use wind_current_codepage as codepage parameter.
  (unicode_print): Print 4 characters for hexadecimal values in unicode strings.
* winduni.h:  (wind_default_codepage, wind_current_codepage): Export.
* doc/binutils.texi: Document new option.
* NEWS: Mention new feature.

binutils/ChangeLog
binutils/NEWS
binutils/rclex.c
binutils/windres.c
binutils/winduni.c
binutils/winduni.h

index 19a2f00..1d9a542 100644 (file)
@@ -1,3 +1,18 @@
+2007-06-18  Kai Tietz  <Kai.Tietz@onevision.com>
+
+       * rclex.c: (cpp_line): Add code_page pragma support.
+       * windres.c: (usage, long_options, main): Add new option
+       --codepage or -c.
+       * winduni.c: (wind_default_codepage, wind_current_codepage): New.
+       (unicode_from_ascii, ascii_from_unicode): Use
+       wind_current_codepage as codepage parameter.
+       (unicode_print): Print 4 characters for hexadecimal values in
+       unicode strings.
+       * winduni.h:  (wind_default_codepage, wind_current_codepage):
+       Export.
+       * doc/binutils.texi: Document new option.
+       * NEWS: Mention new feature.
+
 2007-06-18  Brian D. Watt <bwatt@us.ibm.com>
 
        * embedspu.sh: Parse _SPUEAR_ symbol values as hex.
index 81c6114..3eceac0 100644 (file)
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add codepage support to the windres tool.
+
 * Add --extract-symbol command line option to objcopy, which will
   strip everything out of an ordinary object file or executable except
   for its symbol table.  Files containing just symbols can be useful
index edcf2ce..ef0961b 100644 (file)
@@ -142,11 +142,64 @@ cpp_line (void)
   const char *s = rclex_tok;
   int line;
   char *send, *fn;
+  size_t len, mlen;
 
   ++s;
   while (ISSPACE (*s))
     ++s;
   
+  /* Check for #pragma code_page ( DEFAULT | <nr>).  */
+  len = strlen (s);
+  mlen = strlen ("pragma");
+  if (len > mlen && memcmp (s, "pragma", mlen) == 0 && ISSPACE (s[mlen]))
+    {
+      const char *end;
+
+      s += mlen + 1;
+      while (ISSPACE (*s))
+       ++s;
+      len = strlen (s);
+      mlen = strlen ("code_page");
+      if (len <= mlen || memcmp (s, "code_page", mlen) != 0)
+       /* FIXME: We ought to issue a warning message about an unrecognised pragma.  */
+       return;
+      s += mlen;
+      while (ISSPACE (*s))
+       ++s;
+      if (*s != '(')
+       /* FIXME: We ought to issue an error message about a malformed pragma.  */
+       return;
+      ++s;
+      while (ISSPACE (*s))
+       ++s;
+      if (*s == 0 || (end = strchr (s, ')')) == NULL)
+       /* FIXME: We ought to issue an error message about a malformed pragma.  */
+       return;
+      len = (size_t) (end - s);
+      fn = xmalloc (len + 1);
+      if (len)
+       memcpy (fn, s, len);
+      fn[len] = 0;
+      while (len > 0 && (fn[len - 1] > 0 && fn[len - 1] <= 0x20))
+       fn[--len] = 0;
+      if (! len || (len == strlen ("DEFAULT") && strcasecmp (fn, "DEFAULT") == 0))
+       wind_current_codepage = wind_default_codepage;
+      else if (len > 0)
+       {
+         rc_uint_type ncp;
+
+         if (fn[0] == '0' && (fn[1] == 'x' || fn[1] == 'X'))
+             ncp = (rc_uint_type) strtol (fn + 2, NULL, 16);
+         else
+             ncp = (rc_uint_type) strtol (fn, NULL, 10);
+         if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
+           fatal (_("invalid value specified for pragma code_page.\n"));
+         wind_current_codepage = ncp;
+       }
+      free (fn);
+      return;
+    }
+
   line = strtol (s, &send, 0);
   if (*send != '\0' && ! ISSPACE (*send))
     return;
index 90918a6..da8e33f 100644 (file)
@@ -673,6 +673,7 @@ usage (FILE *stream, int status)
   -D --define <sym>[=<val>]    Define SYM when preprocessing rc file\n\
   -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
   -v --verbose                 Verbose - tells you what it's doing\n\
+  -c --codepage=<codepage>     Specify default codepage\n\
   -l --language=<val>          Set language when reading rc file\n\
      --use-temp-file           Use a temporary file instead of popen to read\n\
                                the preprocessor output\n\
@@ -749,6 +750,7 @@ static const struct option long_options[] =
   {"define", required_argument, 0, 'D'},
   {"undefine", required_argument, 0, 'U'},
   {"verbose", no_argument, 0, 'v'},
+  {"codepage", required_argument, 0, 'c'},
   {"language", required_argument, 0, 'l'},
   {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
   {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
@@ -809,11 +811,25 @@ main (int argc, char **argv)
   language = 0x409;   /* LANG_ENGLISH, SUBLANG_ENGLISH_US.  */
   use_temp_file = 0;
 
-  while ((c = getopt_long (argc, argv, "f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
+  while ((c = getopt_long (argc, argv, "c:f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
                           (int *) 0)) != EOF)
     {
       switch (c)
        {
+       case 'c':
+         {
+           rc_uint_type ncp;
+
+           if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X'))
+             ncp = (rc_uint_type) strtol (optarg + 2, NULL, 16);
+           else
+             ncp = (rc_uint_type) strtol (optarg, NULL, 10);
+           if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
+             fatal (_("invalid codepage specified.\n"));
+           wind_default_codepage = wind_current_codepage = ncp;
+         }
+         break;
+
        case 'i':
          input_filename = optarg;
          break;
index c4f4b1b..f1bd58a 100644 (file)
 
 static rc_uint_type wind_WideCharToMultiByte (rc_uint_type, const unichar *, char *, rc_uint_type);
 static rc_uint_type wind_MultiByteToWideChar (rc_uint_type, const char *, unichar *, rc_uint_type);
-
-/* Prototypes.  */
 static int unichar_isascii (const unichar *, rc_uint_type);
 
+/* Convert an ASCII string to a unicode string.  We just copy it,
+   expanding chars to shorts, rather than doing something intelligent.  */
 #if !defined (_WIN32) && !defined (__CYGWIN__)
 
 /* Codepages mapped.  */
@@ -175,13 +176,21 @@ static const wind_language_t languages[] =
 
 #endif
 
+/* Specifies the default codepage to be used for unicode
+   transformations.  By default this is CP_ACP.  */
+rc_uint_type wind_default_codepage = CP_ACP;
+
+/* Specifies the currently used codepage for unicode
+   transformations.  By default this is CP_ACP.  */
+rc_uint_type wind_current_codepage = CP_ACP;
+
 /* Convert an ASCII string to a unicode string.  We just copy it,
    expanding chars to shorts, rather than doing something intelligent.  */
 
 void
 unicode_from_ascii (rc_uint_type *length, unichar **unicode, const char *ascii)
 {
-  unicode_from_codepage (length, unicode, ascii, 0 /*CP_ACP*/);
+  unicode_from_codepage (length, unicode, ascii, wind_current_codepage);
 }
 
 /* Convert an unicode string to an ASCII string.  We just copy it,
@@ -191,7 +200,7 @@ unicode_from_ascii (rc_uint_type *length, unichar **unicode, const char *ascii)
 void
 ascii_from_unicode (rc_uint_type *length, const unichar *unicode, char **ascii)
 {
-  codepage_from_unicode (length, unicode, ascii, 0/*CP_ACP*/);
+  codepage_from_unicode (length, unicode, ascii, wind_current_codepage);
 }
 
 /* Print the unicode string UNICODE to the file E.  LENGTH is the
@@ -267,7 +276,7 @@ unicode_print (FILE *e, const unichar *unicode, rc_uint_type length)
       else if ((ch & 0xff) == ch)
        fprintf (e, "\\%03o", (unsigned int) ch);
       else
-       fprintf (e, "\\x%x", (unsigned int) ch);
+       fprintf (e, "\\x%04x", (unsigned int) ch);
     }
 }
 
index f22e252..82c3022 100644 (file)
@@ -96,6 +96,14 @@ extern void unicode_print_quoted (FILE *, const unichar *, rc_uint_type);
 #define CP_OEM  1      /* Default OEM code page. */
 #endif
 
+/* Specifies the default codepage to be used for unicode
+   transformations.  By default this is CP_ACP.  */
+extern rc_uint_type wind_default_codepage;
+
+/* Specifies the currently used codepage for unicode
+   transformations.  By default this is CP_ACP.  */
+extern rc_uint_type wind_current_codepage;
+
 typedef struct wind_language_t
 {
   unsigned id;