From 1aeeffdc52c245315db24e48b09092bb682e5a3e Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 24 Jul 2005 22:14:41 +0000 Subject: [PATCH] Added C99 variadic macros git-svn-id: svn://svn.cc65.org/cc65/trunk@3547 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/macrotab.c | 9 +++-- src/cc65/macrotab.h | 27 +++++++------- src/cc65/preproc.c | 90 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/src/cc65/macrotab.c b/src/cc65/macrotab.c index 20866ef90..365e7a27a 100644 --- a/src/cc65/macrotab.c +++ b/src/cc65/macrotab.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2000-2005, Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -82,6 +82,7 @@ Macro* NewMacro (const char* Name) M->MaxArgs = 0; InitCollection (&M->FormalArgs); InitStrBuf (&M->Replacement); + M->Variadic = 0; memcpy (M->Name, Name, Len+1); /* Return the new macro */ diff --git a/src/cc65/macrotab.h b/src/cc65/macrotab.h index 957b8c404..91142e872 100644 --- a/src/cc65/macrotab.h +++ b/src/cc65/macrotab.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2000-2005, Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -46,7 +46,7 @@ /*****************************************************************************/ -/* data */ +/* data */ /*****************************************************************************/ @@ -54,19 +54,20 @@ /* Structure describing a macro */ typedef struct Macro Macro; struct Macro { - Macro* Next; /* Next macro with same hash value */ - int Expanding; /* Are we currently expanding this macro? */ - int ArgCount; /* Number of parameters, -1 = no parens */ - unsigned MaxArgs; /* Size of formal argument list */ - Collection FormalArgs; /* Formal argument list (char*) */ - StrBuf Replacement; /* Replacement text */ - char Name[1]; /* Name, dynamically allocated */ + Macro* Next; /* Next macro with same hash value */ + int Expanding; /* Are we currently expanding this macro? */ + int ArgCount; /* Number of parameters, -1 = no parens */ + unsigned MaxArgs; /* Size of formal argument list */ + Collection FormalArgs; /* Formal argument list (char*) */ + StrBuf Replacement; /* Replacement text */ + unsigned char Variadic; /* C99 variadic macro */ + char Name[1]; /* Name, dynamically allocated */ }; /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 5c0b9b83f..94a670977 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -205,6 +205,15 @@ static StrBuf* ME_GetActual (MacroExp* E, unsigned Index) +static int ME_ArgIsVariadic (const MacroExp* E) +/* Return true if the next actual argument we will add is a variadic one */ +{ + return (E->M->Variadic && + E->M->ArgCount == (int) CollCount (&E->ActualArgs) + 1); +} + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -362,21 +371,37 @@ static void ReadMacroArgs (MacroExp* E) unsigned Parens; /* Number of open parenthesis */ StrBuf Arg = STATIC_STRBUF_INITIALIZER; - /* Read the actual macro arguments and store pointers to these arguments - * into the array of actual arguments in the macro definition. - */ - Parens = 0; + /* Read the actual macro arguments */ + Parens = 0; while (1) { if (CurC == '(') { + /* Nested parenthesis */ SB_AppendChar (&Arg, CurC); NextChar (); ++Parens; - } else if (IsQuote (CurC)) { - CopyQuotedString (&Arg); - } else if (CurC == ',' || CurC == ')') { - if (Parens == 0) { + } else if (IsQuote (CurC)) { + + /* Quoted string - just copy */ + CopyQuotedString (&Arg); + + } else if (CurC == ',' || CurC == ')') { + + if (Parens) { + /* Comma or right paren inside nested parenthesis */ + if (CurC == ')') { + --Parens; + } + SB_AppendChar (&Arg, CurC); + NextChar (); + } else if (CurC == ',' && ME_ArgIsVariadic (E)) { + /* It's a comma, but we're inside a variadic macro argument, so + * just copy it and proceed. + */ + SB_AppendChar (&Arg, CurC); + NextChar (); + } else { /* End of actual argument. Remove whitespace from the end. */ while (IsSpace (SB_LookAtLast (&Arg))) { SB_Drop (&Arg, 1); @@ -398,13 +423,6 @@ static void ReadMacroArgs (MacroExp* E) /* Start the next param */ NextChar (); SB_Clear (&Arg); - } else { - /* Comma or right paren inside nested parenthesis */ - if (CurC == ')') { - --Parens; - } - SB_AppendChar (&Arg, CurC); - NextChar (); } } else if (IsSpace (CurC)) { /* Squeeze runs of blanks within an arg */ @@ -549,7 +567,6 @@ static void MacroArgSubst (MacroExp* E) NextChar (); SkipWhitespace (); if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) { - printf ("<%.*s>\n", SB_GetLen (Line), SB_GetConstBuf (Line)); PPError ("`#' is not followed by a macro parameter"); } else { /* Make a valid string from Replacement */ @@ -675,6 +692,7 @@ static void DefineMacro (void) ident Ident; Macro* M; Macro* Existing; + int C89; /* Read the macro name */ SkipWhitespace (); @@ -682,6 +700,9 @@ static void DefineMacro (void) return; } + /* Remember if we're in C89 mode */ + C89 = (IS_Get (&Standard) == STD_C89); + /* Get an existing macro definition with this name */ Existing = FindMacro (Ident); @@ -703,13 +724,40 @@ static void DefineMacro (void) if (CurC == ')') { break; } - if (MacName (Ident) == 0) { - return; - } + + /* The next token must be either an identifier, or - if not in + * C89 mode - the ellipsis. + */ + if (!C89 && CurC == '.') { + /* Ellipsis */ + NextChar (); + if (CurC != '.' || NextC != '.') { + PPError ("`...' expected"); + ClearLine (); + return; + } + NextChar (); + NextChar (); + strcpy (Ident, "__VA_ARGS__"); + M->Variadic = 1; + } else { + /* Must be macro argument name */ + if (MacName (Ident) == 0) { + return; + } + + /* __VA_ARGS__ is only allowed in C89 mode */ + if (!C89 && strcmp (Ident, "__VA_ARGS__") == 0) { + PPWarning ("`__VA_ARGS__' can only appear in the expansion " + "of a C99 variadic macro"); + } + } + + /* Add the macro argument */ AddMacroArg (M, Ident); SkipWhitespace (); - if (CurC != ',') { - break; + if (M->Variadic || CurC != ',') { + break; } NextChar (); }