mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 02:30:44 +00:00
Fixed two issues with macros:
* A newline between the macro name and the argument list of a function like macro was not accepted. * An unterminated macro argument list was not always detected. git-svn-id: svn://svn.cc65.org/cc65/trunk@4621 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
44852e317e
commit
af27ae6d79
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2009, Ullrich von Bassewitz */
|
/* (C) 1998-2010, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -335,12 +335,31 @@ static void NewStyleComment (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void SkipWhitespace (void)
|
static int SkipWhitespace (int SkipLines)
|
||||||
/* Skip white space in the input stream. */
|
/* Skip white space in the input stream. Do also skip newlines if SkipLines
|
||||||
|
* is true. Return zero if nothing was skipped, otherwise return a
|
||||||
|
* value != zero.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
while (IsSpace (CurC)) {
|
int Skipped = 0;
|
||||||
|
while (1) {
|
||||||
|
if (IsSpace (CurC)) {
|
||||||
NextChar ();
|
NextChar ();
|
||||||
|
Skipped = 1;
|
||||||
|
} else if (CurC == '\0' && SkipLines) {
|
||||||
|
/* End of line, read next */
|
||||||
|
if (NextLine () != 0) {
|
||||||
|
Skipped = 1;
|
||||||
|
} else {
|
||||||
|
/* End of input */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* No more white space */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Skipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -455,12 +474,11 @@ static void ReadMacroArgs (MacroExp* E)
|
|||||||
NextChar ();
|
NextChar ();
|
||||||
SB_Clear (&Arg);
|
SB_Clear (&Arg);
|
||||||
}
|
}
|
||||||
} else if (IsSpace (CurC)) {
|
} else if (SkipWhitespace (1)) {
|
||||||
/* Squeeze runs of blanks within an arg */
|
/* Squeeze runs of blanks within an arg */
|
||||||
if (SB_NotEmpty (&Arg)) {
|
if (SB_NotEmpty (&Arg)) {
|
||||||
SB_AppendChar (&Arg, ' ');
|
SB_AppendChar (&Arg, ' ');
|
||||||
}
|
}
|
||||||
SkipWhitespace ();
|
|
||||||
} else if (CurC == '/' && NextC == '*') {
|
} else if (CurC == '/' && NextC == '*') {
|
||||||
if (SB_NotEmpty (&Arg)) {
|
if (SB_NotEmpty (&Arg)) {
|
||||||
SB_AppendChar (&Arg, ' ');
|
SB_AppendChar (&Arg, ' ');
|
||||||
@ -472,14 +490,11 @@ static void ReadMacroArgs (MacroExp* E)
|
|||||||
}
|
}
|
||||||
NewStyleComment ();
|
NewStyleComment ();
|
||||||
} else if (CurC == '\0') {
|
} else if (CurC == '\0') {
|
||||||
/* End of line inside macro argument list - read next line */
|
/* End of input inside macro argument list */
|
||||||
if (SB_NotEmpty (&Arg)) {
|
PPError ("Unterminated argument list invoking macro `%s'", E->M->Name);
|
||||||
SB_AppendChar (&Arg, ' ');
|
|
||||||
}
|
|
||||||
if (NextLine () == 0) {
|
|
||||||
ClearLine ();
|
ClearLine ();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Just copy the character */
|
/* Just copy the character */
|
||||||
SB_AppendChar (&Arg, CurC);
|
SB_AppendChar (&Arg, CurC);
|
||||||
@ -521,10 +536,7 @@ static void MacroArgSubst (MacroExp* E)
|
|||||||
Arg = ME_GetActual (E, ArgIdx);
|
Arg = ME_GetActual (E, ArgIdx);
|
||||||
|
|
||||||
/* Copy any following whitespace */
|
/* Copy any following whitespace */
|
||||||
HaveSpace = IsSpace (CurC);
|
HaveSpace = SkipWhitespace (0);
|
||||||
if (HaveSpace) {
|
|
||||||
SkipWhitespace ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If a ## operator follows, we have to insert the actual
|
/* If a ## operator follows, we have to insert the actual
|
||||||
* argument as is, otherwise it must be macro replaced.
|
* argument as is, otherwise it must be macro replaced.
|
||||||
@ -561,7 +573,7 @@ static void MacroArgSubst (MacroExp* E)
|
|||||||
/* ## operator. */
|
/* ## operator. */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
NextChar ();
|
NextChar ();
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
|
|
||||||
/* Since we need to concatenate the token sequences, remove
|
/* Since we need to concatenate the token sequences, remove
|
||||||
* any whitespace that was added to target, since it must come
|
* any whitespace that was added to target, since it must come
|
||||||
@ -597,7 +609,7 @@ static void MacroArgSubst (MacroExp* E)
|
|||||||
* macro parameter.
|
* macro parameter.
|
||||||
*/
|
*/
|
||||||
NextChar ();
|
NextChar ();
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) {
|
if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) {
|
||||||
PPError ("`#' is not followed by a macro parameter");
|
PPError ("`#' is not followed by a macro parameter");
|
||||||
} else {
|
} else {
|
||||||
@ -684,10 +696,7 @@ static void ExpandMacro (StrBuf* Target, Macro* M)
|
|||||||
/* Check if this is a function like macro */
|
/* Check if this is a function like macro */
|
||||||
if (M->ArgCount >= 0) {
|
if (M->ArgCount >= 0) {
|
||||||
|
|
||||||
int Whitespace = IsSpace (CurC);
|
int Whitespace = SkipWhitespace (1);
|
||||||
if (Whitespace) {
|
|
||||||
SkipWhitespace ();
|
|
||||||
}
|
|
||||||
if (CurC != '(') {
|
if (CurC != '(') {
|
||||||
/* Function like macro but no parameter list */
|
/* Function like macro but no parameter list */
|
||||||
SB_AppendStr (Target, M->Name);
|
SB_AppendStr (Target, M->Name);
|
||||||
@ -734,7 +743,7 @@ static void DefineMacro (void)
|
|||||||
int C89;
|
int C89;
|
||||||
|
|
||||||
/* Read the macro name */
|
/* Read the macro name */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (!MacName (Ident)) {
|
if (!MacName (Ident)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -761,7 +770,7 @@ static void DefineMacro (void)
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Skip white space and check for end of parameter list */
|
/* Skip white space and check for end of parameter list */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (CurC == ')') {
|
if (CurC == ')') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -805,7 +814,7 @@ static void DefineMacro (void)
|
|||||||
/* If we had an ellipsis, or the next char is not a comma, we've
|
/* If we had an ellipsis, or the next char is not a comma, we've
|
||||||
* reached the end of the macro argument list.
|
* reached the end of the macro argument list.
|
||||||
*/
|
*/
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (M->Variadic || CurC != ',') {
|
if (M->Variadic || CurC != ',') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -822,7 +831,7 @@ static void DefineMacro (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Skip whitespace before the macro replacement */
|
/* Skip whitespace before the macro replacement */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
|
|
||||||
/* Insert the macro into the macro table and allocate the ActualArgs array */
|
/* Insert the macro into the macro table and allocate the ActualArgs array */
|
||||||
InsertMacro (M);
|
InsertMacro (M);
|
||||||
@ -871,26 +880,25 @@ static unsigned Pass1 (StrBuf* Source, StrBuf* Target)
|
|||||||
/* Loop removing ws and comments */
|
/* Loop removing ws and comments */
|
||||||
IdentCount = 0;
|
IdentCount = 0;
|
||||||
while (CurC != '\0') {
|
while (CurC != '\0') {
|
||||||
if (IsSpace (CurC)) {
|
if (SkipWhitespace (0)) {
|
||||||
/* Squeeze runs of blanks */
|
/* Squeeze runs of blanks */
|
||||||
if (!IsSpace (SB_LookAtLast (Target))) {
|
if (!IsSpace (SB_LookAtLast (Target))) {
|
||||||
SB_AppendChar (Target, ' ');
|
SB_AppendChar (Target, ' ');
|
||||||
}
|
}
|
||||||
SkipWhitespace ();
|
|
||||||
} else if (IsSym (Ident)) {
|
} else if (IsSym (Ident)) {
|
||||||
if (Preprocessing && strcmp (Ident, "defined") == 0) {
|
if (Preprocessing && strcmp (Ident, "defined") == 0) {
|
||||||
/* Handle the "defined" operator */
|
/* Handle the "defined" operator */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
HaveParen = 0;
|
HaveParen = 0;
|
||||||
if (CurC == '(') {
|
if (CurC == '(') {
|
||||||
HaveParen = 1;
|
HaveParen = 1;
|
||||||
NextChar ();
|
NextChar ();
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
}
|
}
|
||||||
if (IsSym (Ident)) {
|
if (IsSym (Ident)) {
|
||||||
SB_AppendChar (Target, IsMacro (Ident)? '1' : '0');
|
SB_AppendChar (Target, IsMacro (Ident)? '1' : '0');
|
||||||
if (HaveParen) {
|
if (HaveParen) {
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (CurC != ')') {
|
if (CurC != ')') {
|
||||||
PPError ("`)' expected");
|
PPError ("`)' expected");
|
||||||
} else {
|
} else {
|
||||||
@ -1018,7 +1026,7 @@ static int PushIf (int Skip, int Invert, int Cond)
|
|||||||
static void DoError (void)
|
static void DoError (void)
|
||||||
/* Print an error */
|
/* Print an error */
|
||||||
{
|
{
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (CurC == '\0') {
|
if (CurC == '\0') {
|
||||||
PPError ("Invalid #error directive");
|
PPError ("Invalid #error directive");
|
||||||
} else {
|
} else {
|
||||||
@ -1090,7 +1098,7 @@ static int DoIfDef (int skip, int flag)
|
|||||||
{
|
{
|
||||||
ident Ident;
|
ident Ident;
|
||||||
|
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (MacName (Ident) == 0) {
|
if (MacName (Ident) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -1112,7 +1120,7 @@ static void DoInclude (void)
|
|||||||
PreprocessLine ();
|
PreprocessLine ();
|
||||||
|
|
||||||
/* Skip blanks */
|
/* Skip blanks */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
|
|
||||||
/* Get the next char and check for a valid file name terminator. Setup
|
/* Get the next char and check for a valid file name terminator. Setup
|
||||||
* the include directory spec (SYS/USR) by looking at the terminator.
|
* the include directory spec (SYS/USR) by looking at the terminator.
|
||||||
@ -1169,7 +1177,7 @@ static void DoPragma (void)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Skip blanks following the #pragma directive */
|
/* Skip blanks following the #pragma directive */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
|
|
||||||
/* Copy the remainder of the line into MLine removing comments and ws */
|
/* Copy the remainder of the line into MLine removing comments and ws */
|
||||||
SB_Clear (MLine);
|
SB_Clear (MLine);
|
||||||
@ -1193,7 +1201,7 @@ static void DoUndef (void)
|
|||||||
{
|
{
|
||||||
ident Ident;
|
ident Ident;
|
||||||
|
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (MacName (Ident)) {
|
if (MacName (Ident)) {
|
||||||
UndefineMacro (Ident);
|
UndefineMacro (Ident);
|
||||||
}
|
}
|
||||||
@ -1204,7 +1212,7 @@ static void DoUndef (void)
|
|||||||
static void DoWarning (void)
|
static void DoWarning (void)
|
||||||
/* Print a warning */
|
/* Print a warning */
|
||||||
{
|
{
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (CurC == '\0') {
|
if (CurC == '\0') {
|
||||||
PPError ("Invalid #warning directive");
|
PPError ("Invalid #warning directive");
|
||||||
} else {
|
} else {
|
||||||
@ -1229,7 +1237,7 @@ void Preprocess (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Skip white space at the beginning of the line */
|
/* Skip white space at the beginning of the line */
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
|
|
||||||
/* Check for stuff to skip */
|
/* Check for stuff to skip */
|
||||||
Skip = 0;
|
Skip = 0;
|
||||||
@ -1238,7 +1246,7 @@ void Preprocess (void)
|
|||||||
/* Check for preprocessor lines lines */
|
/* Check for preprocessor lines lines */
|
||||||
if (CurC == '#') {
|
if (CurC == '#') {
|
||||||
NextChar ();
|
NextChar ();
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
if (CurC == '\0') {
|
if (CurC == '\0') {
|
||||||
/* Ignore the empty preprocessor directive */
|
/* Ignore the empty preprocessor directive */
|
||||||
continue;
|
continue;
|
||||||
@ -1383,7 +1391,7 @@ void Preprocess (void)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SkipWhitespace ();
|
SkipWhitespace (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreprocessLine ();
|
PreprocessLine ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user