wrc: Support function macros where varargs are the only argument.
Signed-off-by: Brendan Shanks <bshanks@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d280e8b9b7
commit
f214d0c44e
|
@ -1071,9 +1071,9 @@ static void expand_macro(macexpstackentry_t *mep)
|
||||||
assert(ppp->type == def_macro);
|
assert(ppp->type == def_macro);
|
||||||
assert(ppp->expanding == 0);
|
assert(ppp->expanding == 0);
|
||||||
|
|
||||||
if((ppp->nargs >= 0 && nargs != ppp->nargs) || (ppp->nargs < 0 && nargs < -ppp->nargs))
|
if((!ppp->variadic && nargs != ppp->nargs) || (ppp->variadic && nargs < ppp->nargs))
|
||||||
{
|
{
|
||||||
ppy_error("Too %s macro arguments (%d)", nargs < abs(ppp->nargs) ? "few" : "many", nargs);
|
ppy_error("Too %s macro arguments (%d)", nargs < ppp->nargs ? "few" : "many", nargs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ static char *merge_text(char *s1, char *s2);
|
||||||
*/
|
*/
|
||||||
static char **macro_args; /* Macro parameters array while parsing */
|
static char **macro_args; /* Macro parameters array while parsing */
|
||||||
static int nmacro_args;
|
static int nmacro_args;
|
||||||
|
static int macro_variadic; /* Macro arguments end with (or consist entirely of) '...' */
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -267,7 +268,7 @@ preprocessor
|
||||||
| tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
|
| tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
|
||||||
| tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); }
|
| tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); }
|
||||||
| tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
|
| tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
|
||||||
pp_add_macro($1, macro_args, nmacro_args, $5);
|
pp_add_macro($1, macro_args, nmacro_args, macro_variadic, $5);
|
||||||
}
|
}
|
||||||
| tLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
| tLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||||
| tGCCLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
| tGCCLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||||
|
@ -305,16 +306,16 @@ text : tLITERAL { $$ = $1; }
|
||||||
| text tSQSTRING { $$ = merge_text($1, $2); }
|
| text tSQSTRING { $$ = merge_text($1, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; }
|
res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; macro_variadic = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; }
|
allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; macro_variadic = 0; }
|
||||||
| emargs { $$ = nmacro_args; }
|
| emargs { $$ = nmacro_args; }
|
||||||
;
|
;
|
||||||
|
|
||||||
emargs : margs { $$ = $1; }
|
emargs : margs { $$ = $1; }
|
||||||
| margs ',' tELLIPSIS { nmacro_args *= -1; }
|
| margs ',' tELLIPSIS { macro_variadic = 1; }
|
||||||
| tELLIPSIS { macro_args = NULL; nmacro_args = 0; }
|
| tELLIPSIS { macro_args = NULL; nmacro_args = 0; macro_variadic = 1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
margs : margs ',' tIDENT { $$ = add_new_marg($3); }
|
margs : margs ',' tIDENT { $$ = add_new_marg($3); }
|
||||||
|
|
|
@ -239,7 +239,7 @@ pp_entry_t *pp_add_define(const char *def, const char *text)
|
||||||
return ppp;
|
return ppp;
|
||||||
}
|
}
|
||||||
|
|
||||||
pp_entry_t *pp_add_macro(char *id, char *args[], int nargs, mtext_t *exp)
|
pp_entry_t *pp_add_macro(char *id, char *args[], int nargs, int variadic, mtext_t *exp)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
pp_entry_t *ppp;
|
pp_entry_t *ppp;
|
||||||
|
@ -258,13 +258,14 @@ pp_entry_t *pp_add_macro(char *id, char *args[], int nargs, mtext_t *exp)
|
||||||
ppp->type = def_macro;
|
ppp->type = def_macro;
|
||||||
ppp->margs = args;
|
ppp->margs = args;
|
||||||
ppp->nargs = nargs;
|
ppp->nargs = nargs;
|
||||||
|
ppp->variadic = variadic;
|
||||||
ppp->subst.mtext= exp;
|
ppp->subst.mtext= exp;
|
||||||
ppp->filename = xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
ppp->filename = xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
||||||
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
||||||
list_add_head( &pp_defines[idx], &ppp->entry );
|
list_add_head( &pp_defines[idx], &ppp->entry );
|
||||||
if(pp_status.debug)
|
if(pp_status.debug)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs);
|
fprintf(stderr, "Added macro (%s, %d) <%s(%d%s)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs, variadic ? ",va" : "");
|
||||||
for(; exp; exp = exp->next)
|
for(; exp; exp = exp->next)
|
||||||
{
|
{
|
||||||
switch(exp->type)
|
switch(exp->type)
|
||||||
|
|
|
@ -80,6 +80,7 @@ typedef struct pp_entry {
|
||||||
char *ident; /* The key */
|
char *ident; /* The key */
|
||||||
char **margs; /* Macro arguments array or NULL if none */
|
char **margs; /* Macro arguments array or NULL if none */
|
||||||
int nargs;
|
int nargs;
|
||||||
|
int variadic;
|
||||||
union {
|
union {
|
||||||
mtext_t *mtext; /* The substitution sequence or NULL if none */
|
mtext_t *mtext; /* The substitution sequence or NULL if none */
|
||||||
char *text;
|
char *text;
|
||||||
|
@ -156,7 +157,7 @@ typedef struct cval {
|
||||||
|
|
||||||
pp_entry_t *pplookup(const char *ident);
|
pp_entry_t *pplookup(const char *ident);
|
||||||
pp_entry_t *pp_add_define(const char *def, const char *text);
|
pp_entry_t *pp_add_define(const char *def, const char *text);
|
||||||
pp_entry_t *pp_add_macro(char *ident, char *args[], int nargs, mtext_t *exp);
|
pp_entry_t *pp_add_macro(char *ident, char *args[], int nargs, int variadic, mtext_t *exp);
|
||||||
void pp_del_define(const char *name);
|
void pp_del_define(const char *name);
|
||||||
void *pp_open_include(const char *name, int type, const char *parent_name, char **newpath);
|
void *pp_open_include(const char *name, int type, const char *parent_name, char **newpath);
|
||||||
void pp_push_if(pp_if_state_t s);
|
void pp_push_if(pp_if_state_t s);
|
||||||
|
|
Loading…
Reference in New Issue