- 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