diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 19a2f002c75..1d9a542b348 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,18 @@ +2007-06-18 Kai Tietz + + * 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 * embedspu.sh: Parse _SPUEAR_ symbol values as hex. diff --git a/binutils/NEWS b/binutils/NEWS index 81c61146d04..3eceac03a0d 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -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 diff --git a/binutils/rclex.c b/binutils/rclex.c index edcf2cece6b..ef0961b61ca 100644 --- a/binutils/rclex.c +++ b/binutils/rclex.c @@ -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 | ). */ + 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; diff --git a/binutils/windres.c b/binutils/windres.c index 90918a6e905..da8e33f39ad 100644 --- a/binutils/windres.c +++ b/binutils/windres.c @@ -673,6 +673,7 @@ usage (FILE *stream, int status) -D --define [=] Define SYM when preprocessing rc file\n\ -U --undefine Undefine SYM when preprocessing rc file\n\ -v --verbose Verbose - tells you what it's doing\n\ + -c --codepage= Specify default codepage\n\ -l --language= 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; diff --git a/binutils/winduni.c b/binutils/winduni.c index c4f4b1bce9f..f1bd58acf3b 100644 --- a/binutils/winduni.c +++ b/binutils/winduni.c @@ -47,10 +47,11 @@ 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); } } diff --git a/binutils/winduni.h b/binutils/winduni.h index f22e25221ad..82c3022831a 100644 --- a/binutils/winduni.h +++ b/binutils/winduni.h @@ -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;