[PATCH v2 1/2] wrc: Support function macros where varargs are the only argument.

Brendan Shanks bshanks at codeweavers.com
Thu Apr 28 23:13:15 CDT 2022


Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---

v2: wrc needed support added for parsing function macros where '...' is
the only argument.
Negative 'args' was being used to represent a macro using varargs, but
this obviously fails when there are no named arguments.

Like with other variable argument macros, expansion still doesn't work.

 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 : "<internal or cmdline>");
 	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);
-- 
2.35.1




More information about the wine-devel mailing list