This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, this patch adds feature to windres that a string in a stringtable can contain \0 elements. This feature was requested by ReactOS people, as such things are necessary in real-world Windows applications. ChangeLog 2011-10-18 Kai Tietz <ktietz@redhat.com> * winduni.h (unicode_from_ascii_len): New prototype. * winduni.c (unicode_from_ascii_len): New function. * windres.h (define_stringtable): Add additional length argument. * windres.c (define_stringtable): Add length argument for string. * rcparse.y (res_unicode_sizedstring): New rule. (res_unicode_sizedstring_concat): Likewise. (string_data): Adjust rule. * testsuite/binutils-all/windres/strtab4.rc: New test. * testsuite/binutils-all/windres/strtab4.rsd: Likewise. Tested and build for x86_64-w64-mingw32, i686-w64-mingw32, and i686-pc-cygwin. Ok for apply? Regards, Kai Index: rcparse.y =================================================================== RCS file: /cvs/src/src/binutils/rcparse.y,v retrieving revision 1.31 diff -u -r1.31 rcparse.y --- rcparse.y 11 Oct 2011 15:56:28 -0000 1.31 +++ rcparse.y 18 Oct 2011 18:11:13 -0000 @@ -164,7 +164,7 @@ %type <s> file_name %type <uni> res_unicode_string resname res_unicode_string_concat %type <ss> sizedstring -%type <suni> sizedunistring +%type <suni> sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat %type <i> sizednumexpr sizedposnumexpr %left '|' @@ -1260,20 +1260,20 @@ stringtable: STRINGTABLE suboptions BEG - { sub_res_info = $2; } - string_data END + { sub_res_info = $2; rcparse_rcdata (); } + string_data END { rcparse_normal (); } ; string_data: /* empty */ - | string_data numexpr res_unicode_string_concat + | string_data numexpr res_unicode_sizedstring_concat { - define_stringtable (&sub_res_info, $2, $3); + define_stringtable (&sub_res_info, $2, $3.s, $3.length); rcparse_discard_strings (); } - | string_data numexpr ',' res_unicode_string_concat + | string_data numexpr ',' res_unicode_sizedstring_concat { - define_stringtable (&sub_res_info, $2, $4); + define_stringtable (&sub_res_info, $2, $4.s, $4.length); rcparse_discard_strings (); } | string_data error @@ -1718,6 +1718,43 @@ } ; +res_unicode_sizedstring: + sizedunistring + { + $$ = $1; + } + | sizedstring + { + unichar *h = NULL; + rc_uint_type l = 0; + unicode_from_ascii_len (&l, &h, $1.s, $1.length); + $$.s = h; + $$.length = l; + } + ; + +/* Concat string */ +res_unicode_sizedstring_concat: + res_unicode_sizedstring + { + $$ = $1; + } + | + res_unicode_sizedstring_concat res_unicode_sizedstring + { + rc_uint_type l1 = $1.length; + rc_uint_type l2 = $2.length; + unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); + if (l1 != 0) + memcpy (h, $1.s, l1 * sizeof (unichar)); + if (l2 != 0) + memcpy (h + l1, $2.s, l2 * sizeof (unichar)); + h[l1 + l2] = 0; + $$.length = l1 + l2; + $$.s = h; + } + ; + sizedstring: SIZEDSTRING { Index: resrc.c =================================================================== RCS file: /cvs/src/src/binutils/resrc.c,v retrieving revision 1.38 diff -u -r1.38 resrc.c --- resrc.c 11 Oct 2011 15:56:28 -0000 1.38 +++ resrc.c 18 Oct 2011 18:11:14 -0000 @@ -1591,8 +1591,9 @@ void define_stringtable (const rc_res_res_info *resinfo, - rc_uint_type stringid, const unichar *string) + rc_uint_type stringid, const unichar *string, int len) { + unichar *h; rc_res_id id; rc_res_resource *r; @@ -1616,9 +1617,12 @@ r->res_info = *resinfo; } - - r->u.stringtable->strings[stringid & 0xf].length = unichar_len (string); - r->u.stringtable->strings[stringid & 0xf].string = unichar_dup (string); + h = (unichar *) res_alloc ((len + 1) * sizeof (unichar)); + if (len) + memcpy (h, string, len * sizeof (unichar)); + h[len] = 0; + r->u.stringtable->strings[stringid & 0xf].length = (rc_uint_type) len; + r->u.stringtable->strings[stringid & 0xf].string = h; } void Index: windres.h =================================================================== RCS file: /cvs/src/src/binutils/windres.h,v retrieving revision 1.18 diff -u -r1.18 windres.h --- windres.h 11 Oct 2011 15:56:28 -0000 1.18 +++ windres.h 18 Oct 2011 18:11:14 -0000 @@ -104,7 +104,7 @@ extern rc_rcdata_item *define_rcdata_string (const char *, rc_uint_type); extern rc_rcdata_item *define_rcdata_unistring (const unichar *, rc_uint_type); extern rc_rcdata_item *define_rcdata_number (rc_uint_type, int); -extern void define_stringtable (const rc_res_res_info *, rc_uint_type, const unichar *); +extern void define_stringtable (const rc_res_res_info *, rc_uint_type, const unichar *, int); extern void define_user_data (rc_res_id, rc_res_id, const rc_res_res_info *, rc_rcdata_item *); extern void define_toolbar (rc_res_id, rc_res_res_info *, rc_uint_type ,rc_uint_type ,rc_toolbar_item *); extern void define_user_file (rc_res_id, rc_res_id, const rc_res_res_info *, const char *); Index: winduni.c =================================================================== RCS file: /cvs/src/src/binutils/winduni.c,v retrieving revision 1.14 diff -u -r1.14 winduni.c --- winduni.c 2 Sep 2009 07:22:32 -0000 1.14 +++ winduni.c 18 Oct 2011 18:11:14 -0000 @@ -194,6 +194,94 @@ unicode_from_codepage (length, unicode, ascii, wind_current_codepage); } +/* Convert an ASCII string with length A_LENGTH to a unicode string. We just + copy it, expanding chars to shorts, rather than doing something intelligent. + This routine converts also \0 within a string. */ + +void +unicode_from_ascii_len (rc_uint_type *length, unichar **unicode, const char *ascii, rc_uint_type a_length) +{ + char *tmp, *p; + rc_uint_type tlen, elen, idx = 0; + + *unicode = NULL; + + if (!a_length) + { + if (length) + *length = 0; + return; + } + + /* Make sure we have zero terminated string. */ + p = tmp = (char *) alloca (a_length + 1); + memcpy (tmp, ascii, a_length); + tmp[a_length] = 0; + + while (a_length > 0) + { + unichar *utmp, *up; + + tlen = strlen (p); + + if (tlen > a_length) + tlen = a_length; + if (*p == 0) + { + /* Make room for one more character. */ + utmp = (unichar *) res_alloc (sizeof (unichar) * (idx + 1)); + if (idx > 0) + { + memcpy (utmp, *unicode, idx * sizeof (unichar)); + } + *unicode = utmp; + utmp[idx++] = 0; + --a_length; + p++; + continue; + } + utmp = NULL; + elen = 0; + elen = wind_MultiByteToWideChar (wind_current_codepage, p, NULL, 0); + if (elen) + { + utmp = ((unichar *) res_alloc (elen + sizeof (unichar) * 2)); + wind_MultiByteToWideChar (wind_current_codepage, p, utmp, elen); + elen /= sizeof (unichar); + elen --; + } + else + { + /* Make room for one more character. */ + utmp = (unichar *) res_alloc (sizeof (unichar) * (idx + 1)); + if (idx > 0) + { + memcpy (utmp, *unicode, idx * sizeof (unichar)); + } + *unicode = utmp; + utmp[idx++] = ((unichar) *p) & 0xff; + --a_length; + p++; + continue; + } + p += tlen; + a_length -= tlen; + + up = (unichar *) res_alloc (sizeof (unichar) * (idx + elen)); + if (idx > 0) + memcpy (up, *unicode, idx * sizeof (unichar)); + + *unicode = up; + if (elen) + memcpy (&up[idx], utmp, sizeof (unichar) * elen); + + idx += elen; + } + + if (length) + *length = idx; +} + /* Convert an unicode string to an ASCII string. We just copy it, shrink shorts to chars, rather than doing something intelligent. Shorts with not within the char range are replaced by '_'. */ Index: winduni.h =================================================================== RCS file: /cvs/src/src/binutils/winduni.h,v retrieving revision 1.8 diff -u -r1.8 winduni.h --- winduni.h 2 Sep 2009 07:22:32 -0000 1.8 +++ winduni.h 18 Oct 2011 18:11:14 -0000 @@ -126,6 +126,7 @@ /* Convert an Codepage string to a unicode string. */ extern void unicode_from_codepage (rc_uint_type *, unichar **, const char *, rc_uint_type); +extern void unicode_from_ascii_len (rc_uint_type *, unichar **, const char *, rc_uint_type ); /* Convert an unicode string to an codepage string. */ extern void codepage_from_unicode (rc_uint_type *, const unichar *, char **, rc_uint_type);
Attachment:
strtab4.rc
Description: Binary data
Attachment:
strtab4.rsd
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |