public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [bintutils windres]: Allow \0 in stringtable strings
@ 2011-10-18 18:21 Kai Tietz
  2011-10-24  9:05 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Kai Tietz @ 2011-10-18 18:21 UTC (permalink / raw)
  To: Binutils; +Cc: Nick Clifton

[-- Attachment #1: Type: text/plain, Size: 8433 bytes --]

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 #2: strtab4.rc --]
[-- Type: application/octet-stream, Size: 125 bytes --]

// cpparg -DTEST=1

#include "windows.h"

LANGUAGE 0, 0

STRINGTABLE MOVEABLE PURE DISCARDABLE
BEGIN
  1 "hello\0 world"
END

[-- Attachment #3: strtab4.rsd --]
[-- Type: application/octet-stream, Size: 480 bytes --]

 0000 00000000 20000000 ffff0000 ffff0000  .... ...........
 0010 00000000 00000000 00000000 00000000  ................
 0020 38000000 20000000 ffff0600 ffff0100  8... ...........
 0030 00000000 30100000 00000000 00000000  ....0...........
 0040 00000c00 68006500 6c006c00 6f000000  ....h.e.l.l.o...
 0050 20007700 6f007200 6c006400 00000000   .w.o.r.l.d.....
 0060 00000000 00000000 00000000 00000000  ................
 0070 00000000 00000000                    ........        

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [bintutils windres]: Allow \0 in stringtable strings
  2011-10-18 18:21 [bintutils windres]: Allow \0 in stringtable strings Kai Tietz
@ 2011-10-24  9:05 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2011-10-24  9:05 UTC (permalink / raw)
  To: Kai Tietz; +Cc: Binutils

Hi Kai,

> 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.

Approved - please apply.

Cheers
   Nick


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-10-24  9:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-18 18:21 [bintutils windres]: Allow \0 in stringtable strings Kai Tietz
2011-10-24  9:05 ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).