- Implemented MESSAGETABLE resource type.
- Usertype resources that cause a type-clash with defined resources are now detected and a warning is generated. Some types should be rerouted through other code so that they will be (re-)interpreted. - Bugfix: Line-continuation in strings in resources include a newline. This `feature' got deleted with the builtin preprocessor, but has been put back into place (see last changes comment from version 1.1.0). - Bugfix: The preprocessor now correctly will see "\\\r\n" as a line- continuation. - Bugfix: Assemblers on some platforms do not use 16bit quantities for `.word'. This directive is now changed into `.short'. - All types that accept inline data definitions (a la RCDATA) now also accept a file specification. This unifies the structure a bit.
This commit is contained in:
parent
910e4df2ab
commit
c107f714d0
|
@ -1,3 +1,21 @@
|
|||
---------------------------------------------------------------------------
|
||||
Version 1.1.4 (07-Jun-2000)
|
||||
|
||||
Bertho Stultiens <bertho@akhphd.au.dk>
|
||||
- Implemented MESSAGETABLE resource type.
|
||||
- Usertype resources that cause a type-clash with defined resources
|
||||
are now detected and a warning is generated. Some types should be
|
||||
rerouted through other code so that they will be (re-)interpreted.
|
||||
- Bugfix: Line-continuation in strings in resources include a newline.
|
||||
This `feature' got deleted with the builtin preprocessor, but has been
|
||||
put back into place (see last changes comment from version 1.1.0).
|
||||
- Bugfix: The preprocessor now correctly will see "\\\r\n" as a line-
|
||||
continuation.
|
||||
- Bugfix: Assemblers on some platforms do not use 16bit quantities
|
||||
for `.word'. This directive is now changed into `.short'.
|
||||
- All types that accept inline data definitions (a la RCDATA) now
|
||||
also accept a file specification. This unifies the structure a bit.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Version 1.1.3 (21-May-2000)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Release 1.1.3 of wrc (21-May-2000), the wine resource compiler.
|
||||
Release 1.1.4 of wrc (07-Jun-2000), the wine resource compiler.
|
||||
|
||||
See the file CHANGES for differences between the version and what has been
|
||||
corrected in the current version.
|
||||
|
@ -165,10 +165,10 @@ CHARACTERISTICS 876
|
|||
Resource types supported
|
||||
------------------------
|
||||
All types are supported except for:
|
||||
- MESSAGETABLE (RT_MESSAGETABLE)
|
||||
- RT_VXD
|
||||
- RT_PLUGPLAY
|
||||
- RT_HTML
|
||||
- RT_DLGINCLUDE
|
||||
|
||||
These types will be implemented as soon as I get a proper specification of
|
||||
the layout.
|
||||
|
@ -283,6 +283,8 @@ though):
|
|||
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
|
||||
--------------------------
|
||||
|
|
|
@ -469,6 +469,7 @@ static void dump_user(user_t *usr)
|
|||
*/
|
||||
static void dump_messagetable(messagetable_t *msg)
|
||||
{
|
||||
dump_memopt(msg->memopt);
|
||||
dump_lvc(&(msg->data->lvc));
|
||||
dump_raw_data(msg->data);
|
||||
}
|
||||
|
|
|
@ -1361,15 +1361,25 @@ static res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
|
|||
* msg - The messagetable descriptor
|
||||
* Output : New .res format structure
|
||||
* Description :
|
||||
* Remarks :
|
||||
* Remarks : The data has been converted to the appropriate endian
|
||||
* after is was parsed.
|
||||
*****************************************************************************
|
||||
*/
|
||||
static res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
|
||||
{
|
||||
int restag;
|
||||
res_t *res;
|
||||
assert(name != NULL);
|
||||
assert(msg != NULL);
|
||||
warning("Messagetable not yet implemented");
|
||||
return NULL;
|
||||
|
||||
res = new_res();
|
||||
restag = put_res_header(res, WRC_RT_MESSAGETABLE, NULL, name, msg->memopt, &(msg->data->lvc));
|
||||
put_raw_data(res, msg->data, 0);
|
||||
/* Set ResourceSize */
|
||||
SetResSize(res, restag);
|
||||
if(win32)
|
||||
put_pad(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -617,10 +617,10 @@ cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
|
|||
* number of steps specified in the aniheader_t structure). The "seq "uence
|
||||
* tag can be ommitted, in which case the sequence is equal to the sequence
|
||||
* of "icon"s found in the file. Also "rate" may be ommitted, in which case
|
||||
* the deafult from the aniheader_t structure is used.
|
||||
* the default from the aniheader_t structure is used.
|
||||
*
|
||||
* A animated cursor puts `.cur' formatted files into each "icon" tag, whereas
|
||||
* animated icons contain `.ico' formatted files.
|
||||
* An animated cursor puts `.cur' formatted files into each "icon" tag,
|
||||
* whereas animated icons contain `.ico' formatted files.
|
||||
*
|
||||
* Note about the code: Yes, it can be shorter/compressed. Some tags can be
|
||||
* dealt with in the same code. However, this version shows what is going on
|
||||
|
@ -903,10 +903,72 @@ ver_words_t *add_ver_words(ver_words_t *w, int i)
|
|||
return w;
|
||||
}
|
||||
|
||||
messagetable_t *new_messagetable(raw_data_t *rd)
|
||||
messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
|
||||
{
|
||||
messagetable_t *msg = (messagetable_t *)xmalloc(sizeof(messagetable_t));
|
||||
DWORD nblk;
|
||||
DWORD i;
|
||||
WORD lo;
|
||||
WORD hi;
|
||||
|
||||
msg->data = rd;
|
||||
msg->memopt = *memopt;
|
||||
free(memopt);
|
||||
nblk = *(DWORD *)rd->data;
|
||||
lo = WRC_LOWORD(nblk);
|
||||
hi = WRC_HIWORD(nblk);
|
||||
|
||||
/* FIXME:
|
||||
* This test will fail for all n*2^16 blocks in the messagetable.
|
||||
* However, no sane person would want to have so many blocks
|
||||
* and have a table of megabytes attached.
|
||||
* So, I will assume that we have less than 2^16 blocks in the table
|
||||
* and all will just work out fine. Otherwise, we would need to test
|
||||
* the ID, offset and length (and flag) fields to be very sure.
|
||||
*/
|
||||
if(hi && lo)
|
||||
internal_error(__FILE__, __LINE__, "Messagetable contains more than 65535 blocks; cannot determine endian");
|
||||
if(!hi && !lo)
|
||||
yyerror("Invalid messagetable block count 0");
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if(!hi && lo && byteorder != WRC_BO_LITTLE)
|
||||
#else
|
||||
if(hi && !lo && byteorder != WRC_BO_BIG)
|
||||
#endif
|
||||
{
|
||||
msgtab_block_t *mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]);
|
||||
nblk = BYTESWAP_DWORD(nblk);
|
||||
for(i = 0; i < nblk; i++)
|
||||
{
|
||||
msgtab_entry_t *mep;
|
||||
DWORD id;
|
||||
|
||||
mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo);
|
||||
mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi);
|
||||
mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset);
|
||||
mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset);
|
||||
for(id = mbp[i].idlo; id <= mbp[i].idhi; id++)
|
||||
{
|
||||
mep->length = BYTESWAP_WORD(mep->length);
|
||||
mep->flags = BYTESWAP_WORD(mep->flags);
|
||||
if(mep->flags & 1)
|
||||
{
|
||||
WORD *wp = (WORD *)&mep[1];
|
||||
int l = mep->length/2 - 2; /* Length included header */
|
||||
int n;
|
||||
|
||||
if(mep->length & 1)
|
||||
yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length);
|
||||
for(n = 0; n < l; n++)
|
||||
wp[n] = BYTESWAP_WORD(wp[n]);
|
||||
|
||||
}
|
||||
mep = (msgtab_entry_t *)(((char *)mep) + mep->length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt);
|
|||
bitmap_t *new_bitmap(raw_data_t *rd, int *memopt);
|
||||
ver_words_t *new_ver_words(int i);
|
||||
ver_words_t *add_ver_words(ver_words_t *w, int i);
|
||||
messagetable_t *new_messagetable(raw_data_t *rd);
|
||||
messagetable_t *new_messagetable(raw_data_t *rd, int *memopt);
|
||||
dlginit_t *new_dlginit(raw_data_t *rd, int *memopt);
|
||||
void copy_raw_data(raw_data_t *dst, raw_data_t *src, int offs, int len);
|
||||
int *new_int(int i);
|
||||
|
|
|
@ -394,7 +394,8 @@ L\" {
|
|||
<yylstr>\\r addwchar('\r');
|
||||
<yylstr>\\t addwchar('\t');
|
||||
<yylstr>\\v addwchar('\v');
|
||||
<yylstr>\\. if(yytext[1] != '\n') addwchar(yytext[1]);
|
||||
<yylstr>\\(\n|.) addwchar(yytext[1]);
|
||||
<yylstr>\\\r\n addwchar(yytext[2]);
|
||||
<yylstr>\"\" addcchar('\"'); /* "bla""bla" -> "bla\"bla" */
|
||||
<yylstr>\\\"\" addcchar('\"'); /* "bla\""bla" -> "bla\"bla" */
|
||||
<yylstr>\"{ws}+\" ; /* "bla" "bla" -> "blabla" */
|
||||
|
@ -437,7 +438,8 @@ L\" {
|
|||
<yystr>\\r addcchar('\r');
|
||||
<yystr>\\t addcchar('\t');
|
||||
<yystr>\\v addcchar('\v');
|
||||
<yystr>\\. if(yytext[1] != '\n') addcchar(yytext[1]);
|
||||
<yystr>\\(\n|.) addcchar(yytext[1]);
|
||||
<yystr>\\\r\n addcchar(yytext[2]);
|
||||
<yystr>[^\\\n\"]+ {
|
||||
char *yptr = yytext;
|
||||
while(*yptr)
|
||||
|
|
|
@ -637,7 +637,7 @@ font : tFONT loadmemopts file_raw { $$ = new_font($3, $2); }
|
|||
* The fontdir is generated if it was not present and
|
||||
* fonts are defined in the source.
|
||||
*/
|
||||
fontdir : tFONTDIR loadmemopts raw_data { $$ = new_fontdir($3, $2); }
|
||||
fontdir : tFONTDIR loadmemopts file_raw { $$ = new_fontdir($3, $2); }
|
||||
;
|
||||
|
||||
/* ------------------------------ MessageTable ------------------------------ */
|
||||
|
@ -645,23 +645,74 @@ fontdir : tFONTDIR loadmemopts raw_data { $$ = new_fontdir($3, $2); }
|
|||
* to get everything in one source. Might be a future project.
|
||||
*/
|
||||
messagetable
|
||||
: tMESSAGETABLE filename {
|
||||
: tMESSAGETABLE loadmemopts file_raw {
|
||||
if(!win32)
|
||||
yywarning("MESSAGETABLE not supported in 16-bit mode");
|
||||
$$ = new_messagetable(load_file($2));
|
||||
$$ = new_messagetable($3, $2);
|
||||
}
|
||||
;
|
||||
|
||||
/* ------------------------------ RCData ------------------------------ */
|
||||
rcdata : tRCDATA loadmemopts raw_data { $$ = new_rcdata($3, $2); }
|
||||
rcdata : tRCDATA loadmemopts file_raw { $$ = new_rcdata($3, $2); }
|
||||
;
|
||||
|
||||
/* ------------------------------ DLGINIT ------------------------------ */
|
||||
dlginit : tDLGINIT loadmemopts raw_data { $$ = new_dlginit($3, $2); }
|
||||
dlginit : tDLGINIT loadmemopts file_raw { $$ = new_dlginit($3, $2); }
|
||||
;
|
||||
|
||||
/* ------------------------------ UserType ------------------------------ */
|
||||
userres : usertype loadmemopts file_raw { $$ = new_user($1, $3, $2); }
|
||||
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
|
||||
if(pedantic && byteorder == WRC_BO_BIG)
|
||||
#endif
|
||||
yywarning("Byteordering is not little-endian and type cannot be interpreted");
|
||||
$$ = new_user($1, $3, $2);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
usertype: tNUMBER {
|
||||
|
|
|
@ -293,8 +293,9 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
* Note: Gcc keeps the line-continuations in, for example, strings
|
||||
* intact. However, I prefer to remove them all so that the next
|
||||
* scanner will not need to reduce the continuation state.
|
||||
*
|
||||
* <*>\\\n newline(0);
|
||||
*/
|
||||
<*>\\\n newline(0);
|
||||
|
||||
/*
|
||||
* Detect the leading # of a preprocessor directive.
|
||||
|
@ -320,7 +321,9 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_pp>{ws}*line{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tLINE;} else {yy_pp_state(pp_eol);}
|
||||
<pp_pp>{ws}+ if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tGCCLINE;} else {yy_pp_state(pp_eol);}
|
||||
<pp_pp>{ws}*[a-z]+ pperror("Invalid preprocessor token '%s'", pptext);
|
||||
<pp_pp>\n newline(1); yy_pop_state(); return tNL; /* This could be the null-token */
|
||||
<pp_pp>\r?\n newline(1); yy_pop_state(); return tNL; /* This could be the null-token */
|
||||
<pp_pp>\\\r?\n newline(0);
|
||||
<pp_pp>\\\r? pperror("Preprocessor junk '%s'", pptext);
|
||||
<pp_pp>. return *pptext;
|
||||
|
||||
/*
|
||||
|
@ -331,14 +334,16 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_inc,pp_line>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
|
||||
<pp_inc,pp_line>{ws}+ ;
|
||||
<pp_inc,pp_line>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_inc,pp_line>. pperror(yy_current_state() == pp_inc ? "Trailing junk in #include" : "Trailing junk in #line");
|
||||
<pp_inc,pp_line>\\\r?\n newline(0);
|
||||
<pp_inc,pp_line>(\\\r?)|(.) pperror(yy_current_state() == pp_inc ? "Trailing junk in #include" : "Trailing junk in #line");
|
||||
|
||||
/*
|
||||
* Ignore all input when a false clause is parsed
|
||||
*/
|
||||
<pp_ignore>[^#/\\\n]+ ;
|
||||
<pp_ignore>\n newline(1);
|
||||
<pp_ignore>. ;
|
||||
<pp_ignore>\\\r?\n newline(0);
|
||||
<pp_ignore>(\\\r?)|(.) ;
|
||||
|
||||
/*
|
||||
* Handle #if and #elif.
|
||||
|
@ -362,6 +367,8 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_if>"<=" return tLTE;
|
||||
<pp_if>">=" return tGTE;
|
||||
<pp_if>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_if>\\\r?\n newline(0);
|
||||
<pp_if>\\\r? pperror("Junk in conditional expression");
|
||||
<pp_if>{ws}+ ;
|
||||
<pp_if>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
|
||||
<pp_if>\" pperror("String constants not allowed in conditionals");
|
||||
|
@ -374,7 +381,8 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_ifd>{cident} pplval.cptr = xstrdup(pptext); return tIDENT;
|
||||
<pp_ifd>{ws}+ ;
|
||||
<pp_ifd>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_ifd>. pperror("Identifier expected");
|
||||
<pp_ifd>\\\r?\n newline(0);
|
||||
<pp_ifd>(\\\r?)|(.) pperror("Identifier expected");
|
||||
|
||||
/*
|
||||
* Handle the special 'defined' keyword.
|
||||
|
@ -384,6 +392,7 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_defined>{cident} yy_pop_state(); pplval.cptr = xstrdup(pptext); return tIDENT;
|
||||
<pp_defined>{ws}+ ;
|
||||
<pp_defined>(\()|(\)) return *pptext;
|
||||
<pp_defined>\\\r?\n newline(0);
|
||||
<pp_defined>(\\.)|(\n)|(.) pperror("Identifier expected");
|
||||
|
||||
/*
|
||||
|
@ -394,8 +403,9 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
*/
|
||||
<pp_eol>[^/\\\n]+ if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
|
||||
<pp_eol>\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
|
||||
<pp_eol>(\\)|(\/[^/*]) if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
|
||||
<pp_eol>(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
|
||||
<pp_eol>\n newline(1); yy_pop_state(); if(yy_current_state() != pp_ignore) { return tNL; }
|
||||
<pp_eol>\\\r?\n newline(0);
|
||||
|
||||
/*
|
||||
* Handle left side of #define
|
||||
|
@ -403,14 +413,16 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_def>{cident}\( pplval.cptr = xstrdup(pptext); pplval.cptr[ppleng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO;
|
||||
<pp_def>{cident} pplval.cptr = xstrdup(pptext); yy_pp_state(pp_define); return tDEFINE;
|
||||
<pp_def>{ws}+ ;
|
||||
<pp_def>(\n)|(.) perror("Identifier expected");
|
||||
<pp_def>\\\r?\n newline(0);
|
||||
<pp_def>(\\\r?)|(\n)|(.) perror("Identifier expected");
|
||||
|
||||
/*
|
||||
* Scan the substitution of a define
|
||||
*/
|
||||
<pp_define>[^'"/\\\n]+ pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_define>(\\)|(\/[^/*]) pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_define>\\\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_define>(\\\r?)|(\/[^/*]) pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_define>\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_define>\\\r?\n newline(0);
|
||||
<pp_define>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_define>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
|
||||
<pp_define>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
|
||||
|
@ -423,7 +435,8 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_macro>{cident} pplval.cptr = xstrdup(pptext); return tIDENT;
|
||||
<pp_macro>, return ',';
|
||||
<pp_macro>"..." return tELIPSIS;
|
||||
<pp_macro>(\n)|(.)|(\.\.?) pperror("Argument identifier expected");
|
||||
<pp_macro>(\\\r?)|(\n)|(.)|(\.\.?) pperror("Argument identifier expected");
|
||||
<pp_macro>\\\r?\n newline(0);
|
||||
|
||||
/*
|
||||
* Scan the substitution of a macro
|
||||
|
@ -433,8 +446,9 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_mbody>\#\# return tCONCAT;
|
||||
<pp_mbody>\# return tSTRINGIZE;
|
||||
<pp_mbody>[0-9][^'"#/\\\n]* pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_mbody>(\\)|(\/[^/*'"#\\\n]*) pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_mbody>\\\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_mbody>(\\\r?)|(\/[^/*'"#\\\n]*) pplval.cptr = xstrdup(pptext); return tLITERAL;
|
||||
<pp_mbody>\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_mbody>\\\r?\n newline(0);
|
||||
<pp_mbody>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_mbody>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
|
||||
<pp_mbody>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
|
||||
|
@ -453,8 +467,8 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
if(yy_top_state() != pp_macscan)
|
||||
newline(0);
|
||||
}
|
||||
<pp_macign>{ws}*\\\n newline(0);
|
||||
<pp_macign>{ws}+|{ws}*\\|. {
|
||||
<pp_macign>{ws}*\\\r?\n newline(0);
|
||||
<pp_macign>{ws}+|{ws}*\\\r?|. {
|
||||
macexpstackentry_t *mac = pop_macro();
|
||||
yy_pop_state();
|
||||
put_buffer(mac->ppp->ident, strlen(mac->ppp->ident));
|
||||
|
@ -489,7 +503,8 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<pp_macscan>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
|
||||
<pp_macscan>"/*" yy_push_state(pp_comment); add_text_to_macro(" ", 1);
|
||||
<pp_macscan>\n line_number++; char_number = 1; add_text_to_macro(pptext, ppleng);
|
||||
<pp_macscan>([^/(),\\\n"']+)|(\/[^/*(),\\\n'"]*)|(.) add_text_to_macro(pptext, ppleng);
|
||||
<pp_macscan>([^/(),\\\n"']+)|(\/[^/*(),\\\n'"]*)|(\\\r?)|(.) add_text_to_macro(pptext, ppleng);
|
||||
<pp_macscan>\\\r?\n newline(0);
|
||||
|
||||
/*
|
||||
* Comment handling (almost all start-conditions)
|
||||
|
@ -551,6 +566,30 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
pplval.cptr = get_string();
|
||||
return tIQSTRING;
|
||||
}
|
||||
<pp_dqs>\\\r?\n {
|
||||
/*
|
||||
* This is tricky; we need to remove the line-continuation
|
||||
* from preprocessor strings, but OTOH retain them in all
|
||||
* other strings. This is because the resource grammar is
|
||||
* even more braindead than initially analysed and line-
|
||||
* continuations in strings introduce, sigh, newlines in
|
||||
* the output. There goes the concept of non-breaking, non-
|
||||
* spacing whitespace.
|
||||
*/
|
||||
switch(yy_top_state())
|
||||
{
|
||||
case pp_pp:
|
||||
case pp_define:
|
||||
case pp_mbody:
|
||||
case pp_inc:
|
||||
case pp_line:
|
||||
newline(0);
|
||||
break;
|
||||
default:
|
||||
add_string(pptext, ppleng);
|
||||
newline(-1);
|
||||
}
|
||||
}
|
||||
<pp_iqs,pp_dqs,pp_sqs>\\. add_string(pptext, ppleng);
|
||||
<pp_iqs,pp_dqs,pp_sqs>\n {
|
||||
newline(1);
|
||||
|
@ -604,12 +643,14 @@ includelogicentry_t *includelogiclist = NULL;
|
|||
<INITIAL,pp_macexp>[^a-zA-Z_#'"/\\\n \r\t\f\v]+|(\/|\\)[^a-zA-Z_/*'"\\\n \r\t\v\f]* seen_junk++; put_buffer(pptext, ppleng);
|
||||
<INITIAL,pp_macexp>{ws}+ put_buffer(pptext, ppleng);
|
||||
<INITIAL>\n newline(1);
|
||||
<INITIAL>\\\r?\n newline(0);
|
||||
<INITIAL>\\\r? seen_junk++; put_buffer(pptext, ppleng);
|
||||
|
||||
/*
|
||||
* Special catcher for macro argmument expansion to prevent
|
||||
* newlines to propagate to the output or admin.
|
||||
*/
|
||||
<pp_macexp>(\n)|(.) put_buffer(pptext, ppleng);
|
||||
<pp_macexp>(\n)|(.)|(\\\r?(\n|.)) put_buffer(pptext, ppleng);
|
||||
|
||||
/*
|
||||
* This is a 'catch-all' rule to discover errors in the scanner
|
||||
|
@ -657,12 +698,20 @@ int ppwrap(void)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
* Output newlines or set them as continuations
|
||||
*
|
||||
* Input: -1 - Don't count this one, but update local position (see pp_dqs)
|
||||
* 0 - Line-continuation seen and cache output
|
||||
* 1 - Newline seen and flush output
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void newline(int dowrite)
|
||||
{
|
||||
line_number++;
|
||||
char_number = 1;
|
||||
|
||||
if(dowrite == -1)
|
||||
return;
|
||||
|
||||
ncontinuations++;
|
||||
if(dowrite)
|
||||
{
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#define WRC_MAJOR_VERSION 1
|
||||
#define WRC_MINOR_VERSION 1
|
||||
#define WRC_MICRO_VERSION 3
|
||||
#define WRC_RELEASEDATE "(21-May-2000)"
|
||||
#define WRC_MICRO_VERSION 4
|
||||
#define WRC_RELEASEDATE "(07-Jun-2000)"
|
||||
|
||||
#define WRC_STRINGIZE(a) #a
|
||||
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH WRC 1 "May 21, 2000" "Version 1.1.3" "Wine Resource Compiler"
|
||||
.TH WRC 1 "June 07, 2000" "Version 1.1.4" "Wine Resource Compiler"
|
||||
.SH NAME
|
||||
wrc \- Wine Resource Compiler
|
||||
.SH SYNOPSIS
|
||||
|
@ -187,9 +187,7 @@ expanded them correctly
|
|||
.PP
|
||||
There is no support for:
|
||||
.br
|
||||
\- MESSAGETABLE (parsed, but not generated)
|
||||
.br
|
||||
\- RT_VXD, RT_PLUGPLAY and RT_HTML (unknown format)
|
||||
\- RT_DLGINCLUDE, RT_VXD, RT_PLUGPLAY and RT_HTML (unknown format)
|
||||
.br
|
||||
\- PUSHBOX control is unsupported due to lack of original functionality.
|
||||
.PP
|
||||
|
@ -197,6 +195,11 @@ Fonts are parsed and generated, but there is no support for the
|
|||
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
|
||||
|
|
|
@ -437,7 +437,23 @@ typedef struct user {
|
|||
raw_data_t *data;
|
||||
} user_t;
|
||||
|
||||
/*
|
||||
* Messagetables
|
||||
*/
|
||||
typedef struct msgtab_block {
|
||||
DWORD idlo; /* Lowest id in the set */
|
||||
DWORD idhi; /* Highest is in the set */
|
||||
DWORD offset; /* Offset from resource start to first entry */
|
||||
} msgtab_block_t;
|
||||
|
||||
typedef struct msgtab_entry {
|
||||
WORD length; /* Length of the data in bytes */
|
||||
WORD flags; /* 0 for char, 1 for WCHAR */
|
||||
/* {char}|{WCHAR} data[...]; */
|
||||
} msgtab_entry_t;
|
||||
|
||||
typedef struct messagetable {
|
||||
DWORD memopt;
|
||||
raw_data_t *data;
|
||||
} messagetable_t;
|
||||
|
||||
|
|
|
@ -531,7 +531,7 @@ static void write_pe_segment(FILE *fp, resource_t *top)
|
|||
/* Version */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
/* # of id entries, # of name entries */
|
||||
fprintf(fp, "\t.word\t%d, %d\n", n_name_entries, n_id_entries);
|
||||
fprintf(fp, "\t.short\t%d, %d\n", n_name_entries, n_id_entries);
|
||||
|
||||
/* Write the type level of the tree */
|
||||
for(i = 0; i < rccount; i++)
|
||||
|
@ -578,7 +578,7 @@ static void write_pe_segment(FILE *fp, resource_t *top)
|
|||
fprintf(fp, "\t.long\t0\n"); /* Flags */
|
||||
fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
fprintf(fp, "\t.word\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
|
||||
fprintf(fp, "\t.short\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
|
||||
for(j = 0; j < rcp->count32; j++)
|
||||
{
|
||||
resource_t *rsc = rcp->rsc32array[j].rsc[0];
|
||||
|
@ -631,7 +631,7 @@ static void write_pe_segment(FILE *fp, resource_t *top)
|
|||
fprintf(fp, "\t.long\t0\n"); /* Flags */
|
||||
fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
fprintf(fp, "\t.word\t0, %d\n", r32cp->count);
|
||||
fprintf(fp, "\t.short\t0, %d\n", r32cp->count);
|
||||
|
||||
for(k = 0; k < r32cp->count; k++)
|
||||
{
|
||||
|
@ -726,7 +726,7 @@ static void write_ne_segment(FILE *fp, resource_t *top)
|
|||
fprintf(fp, "\t.globl\t%s%s\n", prefix, _NEResTab);
|
||||
|
||||
/* AlignmentShift */
|
||||
fprintf(fp, "\t.word\t%d\n", alignment_pwr);
|
||||
fprintf(fp, "\t.short\t%d\n", alignment_pwr);
|
||||
|
||||
/* TypeInfo */
|
||||
for(i = 0; i < rccount; i++)
|
||||
|
@ -735,15 +735,15 @@ static void write_ne_segment(FILE *fp, resource_t *top)
|
|||
|
||||
/* TypeId */
|
||||
if(rcp->type.type == name_ord)
|
||||
fprintf(fp, "\t.word\t0x%04x\n", rcp->type.name.i_name | 0x8000);
|
||||
fprintf(fp, "\t.short\t0x%04x\n", rcp->type.name.i_name | 0x8000);
|
||||
else
|
||||
fprintf(fp, "\t.word\t%s_%s_typename - %s%s\n",
|
||||
fprintf(fp, "\t.short\t%s_%s_typename - %s%s\n",
|
||||
prefix,
|
||||
rcp->type.name.s_name->str.cstr,
|
||||
prefix,
|
||||
_NEResTab);
|
||||
/* ResourceCount */
|
||||
fprintf(fp, "\t.word\t%d\n", rcp->count);
|
||||
fprintf(fp, "\t.short\t%d\n", rcp->count);
|
||||
/* Reserved */
|
||||
fprintf(fp, "\t.long\t0\n");
|
||||
/* NameInfo */
|
||||
|
@ -758,32 +758,32 @@ static void write_ne_segment(FILE *fp, resource_t *top)
|
|||
* All other things are as the MS doc describes (alignment etc.)
|
||||
*/
|
||||
/* Offset */
|
||||
fprintf(fp, "\t.word\t(%s%s_data - %s%s) >> %d\n",
|
||||
fprintf(fp, "\t.short\t(%s%s_data - %s%s) >> %d\n",
|
||||
prefix,
|
||||
rcp->rscarray[j]->c_name,
|
||||
prefix,
|
||||
_NEResTab,
|
||||
alignment_pwr);
|
||||
/* Length */
|
||||
fprintf(fp, "\t.word\t%d\n",
|
||||
fprintf(fp, "\t.short\t%d\n",
|
||||
rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx);
|
||||
/* Flags */
|
||||
fprintf(fp, "\t.word\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);
|
||||
fprintf(fp, "\t.short\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);
|
||||
/* Id */
|
||||
if(rcp->rscarray[j]->name->type == name_ord)
|
||||
fprintf(fp, "\t.word\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
|
||||
fprintf(fp, "\t.short\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
|
||||
else
|
||||
fprintf(fp, "\t.word\t%s%s_name - %s%s\n",
|
||||
fprintf(fp, "\t.short\t%s%s_name - %s%s\n",
|
||||
prefix,
|
||||
rcp->rscarray[j]->c_name,
|
||||
prefix,
|
||||
_NEResTab);
|
||||
/* Handle and Usage */
|
||||
fprintf(fp, "\t.word\t0, 0\n");
|
||||
fprintf(fp, "\t.short\t0, 0\n");
|
||||
}
|
||||
}
|
||||
/* EndTypes */
|
||||
fprintf(fp, "\t.word\t0\n");
|
||||
fprintf(fp, "\t.short\t0\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue