From f214d0c44e08b1e454b7f02df7638a13dff1c5b3 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Thu, 28 Apr 2022 21:13:15 -0700 Subject: [PATCH] wrc: Support function macros where varargs are the only argument. Signed-off-by: Brendan Shanks Signed-off-by: Alexandre Julliard --- tools/wrc/ppl.l | 4 ++-- tools/wrc/ppy.y | 11 ++++++----- tools/wrc/wpp.c | 5 +++-- tools/wrc/wpp_private.h | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tools/wrc/ppl.l b/tools/wrc/ppl.l index 35c3fd6fb44..4748d735fa2 100644 --- a/tools/wrc/ppl.l +++ b/tools/wrc/ppl.l @@ -1071,9 +1071,9 @@ static void expand_macro(macexpstackentry_t *mep) assert(ppp->type == def_macro); 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; } diff --git a/tools/wrc/ppy.y b/tools/wrc/ppy.y index ac4423d724f..ce3c409e735 100644 --- a/tools/wrc/ppy.y +++ b/tools/wrc/ppy.y @@ -112,6 +112,7 @@ static char *merge_text(char *s1, char *s2); */ static char **macro_args; /* Macro parameters array while parsing */ 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); } | tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); } | 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); } | 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); } ; -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 : margs { $$ = $1; } - | margs ',' tELLIPSIS { nmacro_args *= -1; } - | tELLIPSIS { macro_args = NULL; nmacro_args = 0; } + | margs ',' tELLIPSIS { macro_variadic = 1; } + | tELLIPSIS { macro_args = NULL; nmacro_args = 0; macro_variadic = 1; } ; margs : margs ',' tIDENT { $$ = add_new_marg($3); } diff --git a/tools/wrc/wpp.c b/tools/wrc/wpp.c index d8d5052870a..57baf44862b 100644 --- a/tools/wrc/wpp.c +++ b/tools/wrc/wpp.c @@ -239,7 +239,7 @@ pp_entry_t *pp_add_define(const char *def, const char *text) 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; 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->margs = args; ppp->nargs = nargs; + ppp->variadic = variadic; ppp->subst.mtext= exp; ppp->filename = xstrdup(pp_status.input ? pp_status.input : ""); ppp->linenumber = pp_status.input ? pp_status.line_number : 0; list_add_head( &pp_defines[idx], &ppp->entry ); 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) { switch(exp->type) diff --git a/tools/wrc/wpp_private.h b/tools/wrc/wpp_private.h index 435dbcc005a..9d92fa02fbb 100644 --- a/tools/wrc/wpp_private.h +++ b/tools/wrc/wpp_private.h @@ -80,6 +80,7 @@ typedef struct pp_entry { char *ident; /* The key */ char **margs; /* Macro arguments array or NULL if none */ int nargs; + int variadic; union { mtext_t *mtext; /* The substitution sequence or NULL if none */ char *text; @@ -156,7 +157,7 @@ typedef struct cval { pp_entry_t *pplookup(const char *ident); 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_open_include(const char *name, int type, const char *parent_name, char **newpath); void pp_push_if(pp_if_state_t s);