- Bugfix: Corrected "off by one" error in the linenumber while parsing
resource.
- Bugfix: A segfault would occur if messagetables were parsed without
memory options attached. Also added buffer-overflow safeguard while
converting between byteorders.
- Finished remapping usertype resources onto standars types by tricking
the parser into accepting a different token. The remapping can be
disabled with a new commandline option '-m'.
- Resolved some warning about chars used as index on SGI O2 machine
(the ctype isXXX() routines are macros there).
diff --git a/dlls/user/Makefile.in b/dlls/user/Makefile.in
index 2c64b38..f3668a5 100644
--- a/dlls/user/Makefile.in
+++ b/dlls/user/Makefile.in
@@ -4,7 +4,7 @@
VPATH = @srcdir@
MODULE = user32
SOVERSION = 1.0
-WRCEXTRA = -w16
+WRCEXTRA = -w16 -m
ALTNAMES = user keyboard ddeml display mouse
SPEC_SRCS = \
diff --git a/tools/wrc/CHANGES b/tools/wrc/CHANGES
index bc0aa7a..1a9ffc6 100644
--- a/tools/wrc/CHANGES
+++ b/tools/wrc/CHANGES
@@ -1,4 +1,19 @@
---------------------------------------------------------------------------
+Version 1.1.5 (12-Jun-2000)
+
+Bertho Stultiens <bertho@akhphd.au.dk>
+- Bugfix: Corrected "off by one" error in the linenumber while parsing
+ resource.
+- Bugfix: A segfault would occur if messagetables were parsed without
+ memory options attached. Also added buffer-overflow safeguard while
+ converting between byteorders.
+- Finished remapping usertype resources onto standars types by tricking
+ the parser into accepting a different token. The remapping can be
+ disabled with a new commandline option '-m'.
+- Resolved some warning about chars used as index on SGI O2 machine
+ (the ctype isXXX() routines are macros there).
+
+---------------------------------------------------------------------------
Version 1.1.4 (07-Jun-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
diff --git a/tools/wrc/README.wrc b/tools/wrc/README.wrc
index 9074f85..c787d5b 100644
--- a/tools/wrc/README.wrc
+++ b/tools/wrc/README.wrc
@@ -1,4 +1,4 @@
-Release 1.1.4 of wrc (07-Jun-2000), the wine resource compiler.
+Release 1.1.5 of wrc (12-Jun-2000), the wine resource compiler.
See the file CHANGES for differences between the version and what has been
corrected in the current version.
@@ -42,6 +42,7 @@
-I path Set include search dir to path (multiple -I allowed)
-l lan Set default language to lan (default is neutral {0, 0})
-L Leave case of embedded filenames as is
+ -m Do not remap numerical resource IDs
-n Do not generate .s file
-N Do not preprocess input
-o file Output to file (default is infile.[res|s|h]
@@ -283,8 +284,6 @@
different action for win32 and win16
- PUSHBOX control is unsupported. The MS docs use it plenty, but neither
MS' nor Borland's compiler supports it.
-- Usertype resources with a type-clash are not handled correctly. These
- should map onto other resources.
Reporting bugs and patches
--------------------------
diff --git a/tools/wrc/dumpres.c b/tools/wrc/dumpres.c
index 56185fe..f5caba6 100644
--- a/tools/wrc/dumpres.c
+++ b/tools/wrc/dumpres.c
@@ -237,7 +237,7 @@
{
printf("- ");
for(i = 0; i < 16; i++)
- printf("%c", isprint(d->data[n-16+i]) ? d->data[n-16+i] : '.');
+ printf("%c", isprint(d->data[n-16+i] & 0xff) ? d->data[n-16+i] : '.');
printf("\n%08x: ", n);
}
else
@@ -250,7 +250,7 @@
if(!j)
j = 16;
for(i = 0; i < j; i++)
- printf("%c", isprint(d->data[n-j+i]) ? d->data[n-j+i] : '.');
+ printf("%c", isprint(d->data[n-j+i] & 0xff) ? d->data[n-j+i] : '.');
printf("\n");
}
diff --git a/tools/wrc/genres.c b/tools/wrc/genres.c
index 6ab36cc..c544c7c 100644
--- a/tools/wrc/genres.c
+++ b/tools/wrc/genres.c
@@ -1746,7 +1746,7 @@
buf[0] = '\0';
for(i = 0; *sptr && i < MAXNAMELEN; i++)
{
- if((unsigned)*sptr < 0x80 && isprint((char)*sptr))
+ if((unsigned)*sptr < 0x80 && isprint(*sptr & 0xff))
buf[i] = *sptr++;
else
warning("Resourcename (str_unicode) contain unprintable characters or invalid translation, ignored");
@@ -1761,7 +1761,7 @@
buf[0] = '\0';
for(i = 0; *cptr && i < MAXNAMELEN; i++)
{
- if((unsigned)*cptr < 0x80 && isprint(*cptr))
+ if((unsigned)*cptr < 0x80 && isprint(*cptr & 0xff))
buf[i] = *cptr++;
else
warning("Resourcename (str_char) contain unprintable characters, ignored");
diff --git a/tools/wrc/newstruc.c b/tools/wrc/newstruc.c
index 7584d80..cc5a426 100644
--- a/tools/wrc/newstruc.c
+++ b/tools/wrc/newstruc.c
@@ -903,6 +903,7 @@
return w;
}
+#define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r))
messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
{
messagetable_t *msg = (messagetable_t *)xmalloc(sizeof(messagetable_t));
@@ -912,8 +913,17 @@
WORD hi;
msg->data = rd;
- msg->memopt = *memopt;
- free(memopt);
+ if(memopt)
+ {
+ msg->memopt = *memopt;
+ free(memopt);
+ }
+ else
+ msg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
+
+ if(rd->size < sizeof(DWORD))
+ yyerror("Invalid messagetable, size too small");
+
nblk = *(DWORD *)rd->data;
lo = WRC_LOWORD(nblk);
hi = WRC_HIWORD(nblk);
@@ -939,6 +949,8 @@
{
msgtab_block_t *mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]);
nblk = BYTESWAP_DWORD(nblk);
+ if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp)))
+ yyerror("Messagetable's blocks are outside of defined data");
for(i = 0; i < nblk; i++)
{
msgtab_entry_t *mep;
@@ -952,7 +964,9 @@
{
mep->length = BYTESWAP_WORD(mep->length);
mep->flags = BYTESWAP_WORD(mep->flags);
- if(mep->flags & 1)
+ if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length))
+ yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id);
+ if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */
{
WORD *wp = (WORD *)&mep[1];
int l = mep->length/2 - 2; /* Length included header */
@@ -971,6 +985,7 @@
return msg;
}
+#undef MSGTAB_BAD_PTR
void copy_raw_data(raw_data_t *dst, raw_data_t *src, int offs, int len)
{
diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l
index 0f531b3..1d7b434 100644
--- a/tools/wrc/parser.l
+++ b/tools/wrc/parser.l
@@ -518,7 +518,7 @@
char_number = 1;
}
yywarning("Unmatched text '%c' (0x%02x) YY_START=%d stripslevel=%d",
- isprint(*yytext) ? *yytext : '.', *yytext, YY_START,stripslevel);
+ isprint(*yytext & 0xff) ? *yytext : '.', *yytext, YY_START,stripslevel);
}
%%
diff --git a/tools/wrc/parser.y b/tools/wrc/parser.y
index 1c6c973..4215982 100644
--- a/tools/wrc/parser.y
+++ b/tools/wrc/parser.y
@@ -188,6 +188,7 @@
static string_t *make_filename(string_t *s);
static resource_t *build_fontdirs(resource_t *tail);
static resource_t *build_fontdir(resource_t **fnt, int nfnt);
+static int rsrcid_to_token(int lookahead);
%}
%union{
@@ -411,7 +412,7 @@
*/
preprocessor
: '#' { want_nl = 1; } tNUMBER tSTRING any_nums tNL {
- line_number = $3 - 1;
+ line_number = $3;
input_name = $4->str.cstr;
/* fprintf(stderr, "Now at %s:%d\n", input_name, line_number); */
}
@@ -437,18 +438,18 @@
/* Parse top level resource definitions etc. */
resource
- : nameid resource_definition {
- $$ = $2;
+ : nameid usrcvt resource_definition {
+ $$ = $3;
if($$)
{
$$->name = $1;
if($1->type == name_ord)
{
- chat("Got %s (%d)",get_typename($2),$1->name.i_name);
+ chat("Got %s (%d)",get_typename($3),$1->name.i_name);
}
else if($1->type == name_str)
{
- chat("Got %s (%s)",get_typename($2),$1->name.s_name->str.cstr);
+ chat("Got %s (%s)",get_typename($3),$1->name.s_name->str.cstr);
}
}
}
@@ -475,6 +476,13 @@
;
/*
+ * Remapping of numerical resource types
+ * (see also comment of called function below)
+ */
+usrcvt : /* Empty */ { yychar = rsrcid_to_token(yychar); }
+ ;
+
+/*
* Get a valid name/id
*/
nameid : expr {
@@ -662,48 +670,6 @@
/* ------------------------------ UserType ------------------------------ */
userres : usertype loadmemopts file_raw {
- if($1->type == name_ord)
- {
- switch($1->name.i_name)
- {
- case WRC_RT_CURSOR: /* Bad idea; cursors should generate directories */
- case WRC_RT_ANICURSOR:
- case WRC_RT_ICON:
- case WRC_RT_ANIICON: /* Bad idea; icons should generate directories */
- case WRC_RT_BITMAP:
- case WRC_RT_FONT: /* Bad idea; fonts should generate directories */
- case WRC_RT_FONTDIR:
- case WRC_RT_RCDATA: /* This cannot be interpreted anyway */
- case WRC_RT_MESSAGETABLE: /* This case is involked by mc.exe */
- case WRC_RT_DLGINIT: /* No real layout available */
-
- /* These should never be invoked because they have their own layout */
- case WRC_RT_ACCELERATOR:
- case WRC_RT_MENU:
- case WRC_RT_DIALOG:
- case WRC_RT_STRING:
- case WRC_RT_TOOLBAR:
- case WRC_RT_VERSION:
- yywarning("Usertype uses special type-ID %d (wrc cannot yet re-interpret the data)", $1->name.i_name);
- goto douser;
-
- case WRC_RT_GROUP_CURSOR:
- case WRC_RT_GROUP_ICON:
- yywarning("Usertype uses reserved type-ID %d, which is auto-generated", $1->name.i_name);
- goto douser;
-
- case WRC_RT_DLGINCLUDE:
- case WRC_RT_PLUGPLAY:
- case WRC_RT_VXD:
- case WRC_RT_HTML:
- yywarning("Usertype uses reserved type-ID %d, which is not supported by wrc", $1->name.i_name);
- default:
- goto douser;
- }
- }
- else
- {
- douser:
#ifdef WORDS_BIGENDIAN
if(pedantic && byteorder != WRC_BO_LITTLE)
#else
@@ -712,7 +678,6 @@
yywarning("Byteordering is not little-endian and type cannot be interpreted");
$$ = new_user($1, $3, $2);
}
- }
;
usertype: tNUMBER {
@@ -2041,7 +2006,7 @@
static name_id_t *convert_ctlclass(name_id_t *cls)
{
- char *cc;
+ char *cc = NULL;
int iclass;
if(cls->type == name_ord)
@@ -2213,7 +2178,7 @@
if(key->type != str_char)
yyerror("Key code must be an ascii string");
- if((flags & WRC_AF_VIRTKEY) && (!isupper(key->str.cstr[0]) && !isdigit(key->str.cstr[0])))
+ if((flags & WRC_AF_VIRTKEY) && (!isupper(key->str.cstr[0] & 0xff) && !isdigit(key->str.cstr[0] & 0xff)))
yyerror("VIRTKEY code is not equal to ascii value");
if(key->str.cstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
@@ -2821,3 +2786,131 @@
return lst;
}
+/*
+ * This gets invoked to determine whether the next resource
+ * is to be of a standard-type (e.g. bitmaps etc.), or should
+ * be a user-type resource. This function is required because
+ * there is the _possibility_ of a lookahead token in the
+ * parser, which is generated from the "expr" state in the
+ * "nameid" parsing.
+ *
+ * The general resource format is:
+ * <identifier> <type> <flags> <resourcebody>
+ *
+ * The <identifier> can either be tIDENT or "expr". The latter
+ * will always generate a lookahead, which is the <type> of the
+ * resource to parse. Otherwise, we need to get a new token from
+ * the scanner to determine the next step.
+ *
+ * The problem arrises when <type> is numerical. This case should
+ * map onto default resource-types and be parsed as such instead
+ * of being mapped onto user-type resources.
+ *
+ * The trick lies in the fact that yacc (bison) doesn't care about
+ * intermediate changes of the lookahead while reducing a rule. We
+ * simply replace the lookahead with a token that will result in
+ * a shift to the appropriate rule for the specific resource-type.
+ */
+static int rsrcid_to_token(int lookahead)
+{
+ int token;
+ char *type = "?";
+
+ /* Get a token if we don't have one yet */
+ if(lookahead == YYEMPTY)
+ lookahead = YYLEX;
+
+ /* Only numbers are possibly interesting */
+ switch(lookahead)
+ {
+ case tNUMBER:
+ case tLNUMBER:
+ break;
+ default:
+ return lookahead;
+ }
+
+ token = lookahead;
+
+ switch(yylval.num)
+ {
+ case WRC_RT_CURSOR:
+ type = "CURSOR";
+ token = tCURSOR;
+ break;
+ case WRC_RT_ICON:
+ type = "ICON";
+ token = tICON;
+ break;
+ case WRC_RT_BITMAP:
+ type = "BITMAP";
+ token = tBITMAP;
+ break;
+ case WRC_RT_FONT:
+ type = "FONT";
+ token = tFONT;
+ break;
+ case WRC_RT_FONTDIR:
+ type = "FONTDIR";
+ token = tFONTDIR;
+ break;
+ case WRC_RT_RCDATA:
+ type = "RCDATA";
+ token = tRCDATA;
+ break;
+ case WRC_RT_MESSAGETABLE:
+ type = "MESSAGETABLE";
+ token = tMESSAGETABLE;
+ break;
+ case WRC_RT_DLGINIT:
+ type = "DLGINIT";
+ token = tDLGINIT;
+ break;
+ case WRC_RT_ACCELERATOR:
+ type = "ACCELERATOR";
+ token = tACCELERATORS;
+ break;
+ case WRC_RT_MENU:
+ type = "MENU";
+ token = tMENU;
+ break;
+ case WRC_RT_DIALOG:
+ type = "DIALOG";
+ token = tDIALOG;
+ break;
+ case WRC_RT_VERSION:
+ type = "VERSION";
+ token = tVERSIONINFO;
+ break;
+ case WRC_RT_TOOLBAR:
+ type = "TOOLBAR";
+ token = tTOOLBAR;
+ break;
+
+ case WRC_RT_STRING:
+ type = "STRINGTABLE";
+ break;
+
+ case WRC_RT_ANICURSOR:
+ case WRC_RT_ANIICON:
+ case WRC_RT_GROUP_CURSOR:
+ case WRC_RT_GROUP_ICON:
+ yywarning("Usertype uses reserved type-ID %d, which is auto-generated", yylval.num);
+ return lookahead;
+
+ case WRC_RT_DLGINCLUDE:
+ case WRC_RT_PLUGPLAY:
+ case WRC_RT_VXD:
+ case WRC_RT_HTML:
+ yywarning("Usertype uses reserved type-ID %d, which is not supported by wrc", yylval.num);
+ default:
+ return lookahead;
+ }
+
+ if(remap)
+ return token;
+ else
+ yywarning("Usertype uses reserved type-ID %d, which is used by %s", yylval.num, type);
+ return lookahead;
+}
+
diff --git a/tools/wrc/ppl.l b/tools/wrc/ppl.l
index 4cf7716..004fa9e 100644
--- a/tools/wrc/ppl.l
+++ b/tools/wrc/ppl.l
@@ -656,7 +656,7 @@
* This is a 'catch-all' rule to discover errors in the scanner
* in an orderly manner.
*/
-<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext) ? *pptext : ' ', *pptext);
+<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext);
<<EOF>> {
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
@@ -954,7 +954,7 @@
/* Remove trailing whitespace from current expansion text */
while(curdef_idx)
{
- if(isspace(curdef_text[curdef_idx-1]))
+ if(isspace(curdef_text[curdef_idx-1] & 0xff))
curdef_idx--;
else
break;
@@ -968,7 +968,7 @@
n = curdef_idx - tag;
while(n)
{
- if(isspace(*cptr))
+ if(isspace(*cptr & 0xff))
{
cptr++;
n--;
@@ -1054,7 +1054,7 @@
/* Strip trailing whitespace from expansion */
for(k = curdef_idx, cptr = &curdef_text[curdef_idx-1]; k > 0; k--, cptr--)
{
- if(!isspace(*cptr))
+ if(!isspace(*cptr & 0xff))
break;
}
@@ -1069,7 +1069,7 @@
/* Strip leading whitespace from expansion */
for(n = 0, cptr = curdef_text; n < k; n++, cptr++)
{
- if(!isspace(*cptr))
+ if(!isspace(*cptr & 0xff))
break;
}
diff --git a/tools/wrc/ppy.y b/tools/wrc/ppy.y
index a4c5b5a..9acbb75 100644
--- a/tools/wrc/ppy.y
+++ b/tools/wrc/ppy.y
@@ -569,7 +569,7 @@
while(len)
{
/* FIXME: should delete space from head of string */
- if(isspace(mtp->subst.text[len-1]))
+ if(isspace(mtp->subst.text[len-1] & 0xff))
mtp->subst.text[--len] = '\0';
else
break;
@@ -588,7 +588,7 @@
int len = strlen(tail->subst.text);
while(len)
{
- if(isspace(tail->subst.text[len-1]))
+ if(isspace(tail->subst.text[len-1] & 0xff))
tail->subst.text[--len] = '\0';
else
break;
diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c
index 7255eaa..eea657c 100644
--- a/tools/wrc/wrc.c
+++ b/tools/wrc/wrc.c
@@ -78,6 +78,7 @@
" -I path Set include search dir to path (multiple -I allowed)\n"
" -l lan Set default language to lan (default is neutral {0, 0})\n"
" -L Leave case of embedded filenames as is\n"
+ " -m Do not remap numerical resource IDs\n"
" -n Do not generate .s file\n"
" -N Do not preprocess input\n"
" -o file Output to file (default is infile.[res|s|h]\n"
@@ -233,6 +234,11 @@
*/
int no_preprocess = 0;
+/*
+ * Cleared when _not_ to remap resource types (-m option)
+ */
+int remap = 1;
+
char *output_name; /* The name given by the -o option */
char *input_name; /* The name given on the command-line */
char *header_name; /* The name given by the -H option */
@@ -279,7 +285,7 @@
strcat(cmdline, " ");
}
- while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEghH:I:l:LnNo:p:rstTVw:W")) != EOF)
+ while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEghH:I:l:LmnNo:p:rstTVw:W")) != EOF)
{
switch(optc)
{
@@ -352,6 +358,9 @@
case 'L':
leave_case = 1;
break;
+ case 'm':
+ remap = 0;
+ break;
case 'n':
create_s = 0;
break;
diff --git a/tools/wrc/wrc.h b/tools/wrc/wrc.h
index cf4b3f3..b16b2ca 100644
--- a/tools/wrc/wrc.h
+++ b/tools/wrc/wrc.h
@@ -16,8 +16,8 @@
#define WRC_MAJOR_VERSION 1
#define WRC_MINOR_VERSION 1
-#define WRC_MICRO_VERSION 4
-#define WRC_RELEASEDATE "(07-Jun-2000)"
+#define WRC_MICRO_VERSION 5
+#define WRC_RELEASEDATE "(09-Jun-2000)"
#define WRC_STRINGIZE(a) #a
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
@@ -55,6 +55,7 @@
extern int byteorder;
extern int preprocess_only;
extern int no_preprocess;
+extern int remap;
extern char *prefix;
extern char *output_name;
diff --git a/tools/wrc/wrc.man b/tools/wrc/wrc.man
index 81c2556..f05175a 100644
--- a/tools/wrc/wrc.man
+++ b/tools/wrc/wrc.man
@@ -1,4 +1,4 @@
-.TH WRC 1 "June 07, 2000" "Version 1.1.4" "Wine Resource Compiler"
+.TH WRC 1 "June 12, 2000" "Version 1.1.5" "Wine Resource Compiler"
.SH NAME
wrc \- Wine Resource Compiler
.SH SYNOPSIS
@@ -105,6 +105,17 @@
Leave case of embedded filenames as is. All filenames are converted to
lower case before they are attemped to be opened without this option.
.TP
+.I \-m
+Do not remap numerical resource type-IDs onto standard resources. This will
+cause all numerical resource type\-IDs to be treated as user\-type resources
+and will not be checked nor byte\-reversed. Without this option, resources
+with, for example, type\-ID 2 are parsed as bitmaps and other type\-IDs will
+map onto their respective standard type.
+Use this option with caution because it can create problems when compiling for,
+for example, big\-endian platforms. The \fI\-m\fR option is usefull for
+source\-files that contain overlapping type\-IDs, or when the format of the
+resource is not 100% compliant.
+.TP
.I \-n
Do not generate an assembly outputfile (suppress generation of \fB.s\fR
file). Usefull if you are interested in a header file only.
@@ -195,11 +206,6 @@
generation of the FONTDIR yet. The user must supply the FONTDIR
resource in the source to match the FONT resources.
.PP
-Usertype resources that have a type-clash with other resources are not
-handled correctly. These should map onto the builtin resources as much
-as possible (especially icons, cursors and fonts because of directory
-generation and everything else that would require byte-order swapping).
-.PP
See the CHANGES and README.wrc files in the distribution for more
comments on bugs and fixes across the versions.
.SH AVAILABILITY