Fixed a bug

git-svn-id: svn://svn.cc65.org/cc65/trunk@91 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-06-21 21:02:44 +00:00
parent e27fafbea3
commit 04ee693c00
8 changed files with 619 additions and 517 deletions

View File

@@ -800,7 +800,7 @@ static int primary (struct expent* lval)
* and returning int. * and returning int.
*/ */
Warning (WARN_FUNC_WITHOUT_PROTO); Warning (WARN_FUNC_WITHOUT_PROTO);
Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF); Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
lval->e_tptr = Sym->Type; lval->e_tptr = Sym->Type;
lval->e_flags = E_MGLOBAL | E_MCONST | E_TGLAB; lval->e_flags = E_MGLOBAL | E_MCONST | E_TGLAB;
lval->e_name = (unsigned long) Sym->Name; lval->e_name = (unsigned long) Sym->Name;

View File

@@ -57,10 +57,14 @@
/* Input line stuff */ /* Input line stuff */
static char LineBuf [LINESIZE]; static char LineBuf [LINESIZE];
char* line = LineBuf; char* line = LineBuf;
char* lptr = LineBuf; const char* lptr = LineBuf;
/* Current and next input character */
char CurC = '\0';
char NextC = '\0';
/* Maximum count of nested includes */ /* Maximum count of nested includes */
#define MAX_INC_NESTING 20 #define MAX_INC_NESTING 16
/* Struct that describes an input file */ /* Struct that describes an input file */
typedef struct IFile IFile; typedef struct IFile IFile;
@@ -73,6 +77,9 @@ struct IFile {
char Name[1]; /* Name of file (dynamically allocated) */ char Name[1]; /* Name of file (dynamically allocated) */
}; };
/* Main file input data */
static const IFile* MainFile = 0;
/* List of input files */ /* List of input files */
static unsigned IFileTotal = 0; /* Total number of files */ static unsigned IFileTotal = 0; /* Total number of files */
static IFile* IFileList = 0; /* Single linked list of all files */ static IFile* IFileList = 0; /* Single linked list of all files */
@@ -108,6 +115,7 @@ static IFile* NewIFile (const char* Name, FILE* F)
IF->Active = Input; IF->Active = Input;
Input = IF; Input = IF;
++IFileCount; ++IFileCount;
++IFileTotal;
/* Return the new struct */ /* Return the new struct */
return IF; return IF;
@@ -132,7 +140,7 @@ void OpenMainFile (const char* Name)
} }
/* Setup a new IFile structure */ /* Setup a new IFile structure */
NewIFile (Name, F); MainFile = NewIFile (Name, F);
} }
@@ -187,6 +195,55 @@ static void CloseIncludeFile (void)
/* Make this file inactive and the last one active again */ /* Make this file inactive and the last one active again */
Input = Input->Active; Input = Input->Active;
/* Adjust the counter */
--IFileCount;
}
void ClearLine (void)
/* Clear the current input line */
{
line[0] = '\0';
lptr = line;
CurC = '\0';
NextC = '\0';
}
void InitLine (const char* Buf)
/* Initialize lptr from Buf and read CurC and NextC from the new input line */
{
lptr = Buf;
CurC = lptr[0];
if (CurC != '\0') {
NextC = lptr[1];
} else {
NextC = '\0';
}
}
void NextChar (void)
/* Read the next character from the input stream and make CurC and NextC
* valid. If end of line is reached, both are set to NUL, no more lines
* are read by this function.
*/
{
if (lptr[0] != '\0') {
++lptr;
CurC = lptr[0];
if (CurC != '\0') {
NextC = lptr[1];
} else {
NextC = '\0';
}
} else {
CurC = NextC = '\0';
}
} }
@@ -255,26 +312,24 @@ int NextLine (void)
} }
} }
/* Got a line */ /* Got a line. Initialize the current and next characters. */
InitLine (line);
/* Done */
return 1; return 1;
} }
void ClearLine (void)
/* Clear the current input line */
{
line [0] = '\0';
lptr = line;
}
const char* GetCurrentFile (void) const char* GetCurrentFile (void)
/* Return the name of the current input file */ /* Return the name of the current input file */
{ {
if (Input == 0) { if (Input == 0) {
if (MainFile) {
return MainFile->Name;
} else {
return "(outside file scope)"; return "(outside file scope)";
}
} else { } else {
return Input->Name; return Input->Name;
} }
@@ -290,39 +345,3 @@ unsigned GetCurrentLine (void)
int nch (void)
/* Get the next char in input stream (the one behind the current one) */
{
if (*lptr == '\0') {
return 0;
} else {
return lptr[1] & 0xFF;
}
}
int cgch (void)
/* Get the current character in the input stream and advance line
* pointer (unless already at end of line).
*/
{
if (*lptr == '\0') {
return (0);
} else {
return (*lptr++ & 0xFF);
}
}
int gch (void)
/* Get the current character in the input stream and advance line
* pointer (no end of line check is performed).
*/
{
return (*lptr++ & 0xFF);
}

View File

@@ -50,7 +50,11 @@
/* Input line stuff */ /* Input line stuff */
extern char* line; extern char* line;
extern char* lptr; extern const char* lptr; /* ### Remove this */
/* Current and next input character */
extern char CurC;
extern char NextC;
@@ -66,33 +70,27 @@ void OpenMainFile (const char* Name);
void OpenIncludeFile (const char* Name, unsigned DirSpec); void OpenIncludeFile (const char* Name, unsigned DirSpec);
/* Open an include file and insert it into the tables. */ /* Open an include file and insert it into the tables. */
int NextLine (void);
/* Get a line from the current input. Returns 0 on end of file. */
void ClearLine (void); void ClearLine (void);
/* Clear the current input line */ /* Clear the current input line */
void InitLine (const char* Buf);
/* Initialize lptr from Buf and read CurC and NextC from the new input line */
void NextChar (void);
/* Read the next character from the input stream and make CurC and NextC
* valid. If end of line is reached, both are set to NUL, no more lines
* are read by this function.
*/
int NextLine (void);
/* Get a line from the current input. Returns 0 on end of file. */
const char* GetCurrentFile (void); const char* GetCurrentFile (void);
/* Return the name of the current input file */ /* Return the name of the current input file */
unsigned GetCurrentLine (void); unsigned GetCurrentLine (void);
/* Return the line number in the current input file */ /* Return the line number in the current input file */
int nch (void);
/* Get the next char in input stream (the one behind the current one) */
int cgch (void);
/* Get the current character in the input stream and advance line
* pointer (unless already at end of line).
*/
int gch (void);
/* Get the current character in the input stream and advance line
* pointer (no end of line check is performed).
*/
/* End of input.h */ /* End of input.h */

View File

@@ -40,7 +40,6 @@
#include "error.h" #include "error.h"
#include "litpool.h" #include "litpool.h"
#include "symtab.h" #include "symtab.h"
#include "preproc.h"
#include "scanner.h" #include "scanner.h"
#include "codegen.h" #include "codegen.h"
#include "expr.h" #include "expr.h"
@@ -55,7 +54,7 @@
/* Tokens for the #pragmas */ /* Tokens for the #pragmas */
enum { typedef enum {
PR_BSSSEG, PR_BSSSEG,
PR_CODESEG, PR_CODESEG,
PR_DATASEG, PR_DATASEG,
@@ -65,16 +64,54 @@ enum {
PR_STATICLOCALS, PR_STATICLOCALS,
PR_ZPSYM, PR_ZPSYM,
PR_ILLEGAL PR_ILLEGAL
} pragma_t;
/* Pragma table */
static const struct Pragma {
const char* Key; /* Keyword */
pragma_t Tok; /* Token */
} Pragmas[] = {
{ "bssseg", PR_BSSSEG },
{ "codeseg", PR_CODESEG },
{ "dataseg", PR_DATASEG },
{ "regvaraddr", PR_REGVARADDR },
{ "rodataseg", PR_RODATASEG },
{ "signedchars", PR_SIGNEDCHARS },
{ "staticlocals", PR_STATICLOCALS },
{ "zpsym", PR_ZPSYM },
}; };
/* Number of pragmas */
#define PRAGMA_COUNT (sizeof(Pragmas) / sizeof(Pragmas[0]))
/*****************************************************************************/ /*****************************************************************************/
/* code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
static int CmpKey (const void* Key, const void* Elem)
/* Compare function for bsearch */
{
return strcmp ((const char*) Key, ((const struct Pragma*) Elem)->Key);
}
static pragma_t FindPragma (const char* Key)
/* Find a pragma and return the token. Return PR_ILLEGAL if the keyword is
* not a valid pragma.
*/
{
struct Pragma* P;
P = bsearch (Key, Pragmas, PRAGMA_COUNT, sizeof (Pragmas[0]), CmpKey);
return P? P->Tok : PR_ILLEGAL;
}
static void StringPragma (void (*Func) (const char*)) static void StringPragma (void (*Func) (const char*))
/* Handle a pragma that expects a string parameter */ /* Handle a pragma that expects a string parameter */
{ {
@@ -113,19 +150,7 @@ static void FlagPragma (unsigned char* Flag)
void DoPragma (void) void DoPragma (void)
/* Handle pragmas */ /* Handle pragmas */
{ {
static const struct tok_elt Pragmas [] = { pragma_t Pragma;
{ "bssseg", PR_BSSSEG },
{ "codeseg", PR_CODESEG },
{ "dataseg", PR_DATASEG },
{ "regvaraddr", PR_REGVARADDR },
{ "rodataseg", PR_RODATASEG },
{ "signedchars", PR_SIGNEDCHARS },
{ "staticlocals", PR_STATICLOCALS },
{ "zpsym", PR_ZPSYM },
{ 0, PR_ILLEGAL },
};
int Pragma;
/* Skip the token itself */ /* Skip the token itself */
NextToken (); NextToken ();
@@ -137,7 +162,7 @@ void DoPragma (void)
} }
/* Do we know this pragma? */ /* Do we know this pragma? */
Pragma = searchtok (CurTok.Ident, Pragmas); Pragma = FindPragma (CurTok.Ident);
if (Pragma == PR_ILLEGAL) { if (Pragma == PR_ILLEGAL) {
/* According to the ANSI standard, we're not allowed to generate errors /* According to the ANSI standard, we're not allowed to generate errors
* for unknown pragmas, however, we're allowed to warn - and we will * for unknown pragmas, however, we're allowed to warn - and we will

View File

@@ -29,7 +29,8 @@
static int Pass1 (char* from, char* to); static int Pass1 (const char* From, char* To);
/* Preprocessor pass 1. Remove whitespace and comments. */
@@ -81,63 +82,76 @@ static void keepstr (const char* S)
static void comment (void) static void Comment (void)
/* Remove comment from line. */ /* Remove a C comment from line. */
{ {
/* Remember the current line number, so we can output better error
* messages if the comment is not terminated in the current file.
*/
unsigned StartingLine = GetCurrentLine(); unsigned StartingLine = GetCurrentLine();
gch (); /* Skip the start of comment chars */
gch (); NextChar ();
while (*lptr != '*' || nch () != '/') { NextChar ();
if (*lptr == '\0') {
/* Skip the comment */
while (CurC != '*' || NextC != '/') {
if (CurC == '\0') {
if (NextLine () == 0) { if (NextLine () == 0) {
PPError (ERR_EOF_IN_COMMENT, StartingLine); PPError (ERR_EOF_IN_COMMENT, StartingLine);
return; return;
} }
} else { } else {
if (*lptr == '/' && nch() == '*') { if (CurC == '/' && NextC == '*') {
PPWarning (WARN_NESTED_COMMENT); PPWarning (WARN_NESTED_COMMENT);
} }
++lptr; NextChar ();
} }
} }
gch ();
gch (); /* Skip the end of comment chars */
NextChar ();
NextChar ();
} }
static void skipblank (void) static void SkipBlank (void)
/* Skip blanks and tabs in the input stream. */ /* Skip blanks and tabs in the input stream. */
{ {
while (IsBlank (*lptr)) { while (IsBlank (CurC)) {
++lptr; NextChar ();
} }
} }
static char* CopyQuotedString (int Quote, char* Target) static char* CopyQuotedString (char* Target)
/* Copy a single or double quoted string from lptr to Target. Return the /* Copy a single or double quoted string from the input to Target. Return the
* new target pointer. Target will not be terminated after the copy. * new target pointer. Target will not be terminated after the copy.
*/ */
{ {
/* Copy the starting quote */ /* Remember the quote character, copy it to the target buffer and skip it */
*Target++ = gch(); char Quote = CurC;
*Target++ = CurC;
NextChar ();
/* Copy the characters inside the string */ /* Copy the characters inside the string */
while (*lptr != '\0' && *lptr != Quote) { while (CurC != '\0' && CurC != Quote) {
/* Keep an escaped char */ /* Keep an escaped char */
if (*lptr == '\\') { if (CurC == '\\') {
*Target++ = gch(); *Target++ = CurC;
NextChar ();
} }
/* Copy the character */ /* Copy the character */
*Target++ = cgch(); *Target++ = CurC;
NextChar ();
} }
/* If we had a terminating quote, copy it */ /* If we had a terminating quote, copy it */
if (*lptr) { if (CurC != '\0') {
*Target++ = gch(); *Target++ = CurC;
NextChar ();
} }
/* Return the new target pointer */ /* Return the new target pointer */
@@ -152,10 +166,10 @@ static char* CopyQuotedString (int Quote, char* Target)
static int macname (char *sname) static int MacName (char* Ident)
/* Get macro symbol name. If error, print message and clear line. */ /* Get macro symbol name. If error, print message and clear line. */
{ {
if (issym (sname) == 0) { if (IsSym (Ident) == 0) {
PPError (ERR_IDENT_EXPECTED); PPError (ERR_IDENT_EXPECTED);
ClearLine (); ClearLine ();
return 0; return 0;
@@ -169,20 +183,19 @@ static int macname (char *sname)
static void ExpandMacroArgs (Macro* M) static void ExpandMacroArgs (Macro* M)
/* Preprocessor pass 2. Perform macro substitution. */ /* Preprocessor pass 2. Perform macro substitution. */
{ {
int C;
ident Ident; ident Ident;
const char* Replacement; const char* Replacement;
char* SavePtr; const char* SavePtr;
/* Save the current line pointer and setup the new ones */ /* Save the current line pointer and setup the new ones */
SavePtr = lptr; SavePtr = lptr;
lptr = M->Replacement; InitLine (M->Replacement);
/* Copy the macro replacement checking for parameters to replace */ /* Copy the macro replacement checking for parameters to replace */
while ((C = *lptr) != '\0') { while (CurC != '\0') {
/* If the next token is an identifier, check for a macro arg */ /* If the next token is an identifier, check for a macro arg */
if (IsIdent (C)) { if (IsIdent (CurC)) {
symname (Ident); SymName (Ident);
Replacement = FindMacroArg (M, Ident); Replacement = FindMacroArg (M, Ident);
if (Replacement) { if (Replacement) {
/* Macro arg, keep the replacement */ /* Macro arg, keep the replacement */
@@ -191,9 +204,9 @@ static void ExpandMacroArgs (Macro* M)
/* No macro argument, keep the original identifier */ /* No macro argument, keep the original identifier */
keepstr (Ident); keepstr (Ident);
} }
} else if (C == '#' && IsIdent (nch ())) { } else if (CurC == '#' && IsIdent (NextC)) {
++lptr; NextChar ();
symname (Ident); SymName (Ident);
Replacement = FindMacroArg (M, Ident); Replacement = FindMacroArg (M, Ident);
if (Replacement) { if (Replacement) {
keepch ('\"'); keepch ('\"');
@@ -203,15 +216,16 @@ static void ExpandMacroArgs (Macro* M)
keepch ('#'); keepch ('#');
keepstr (Ident); keepstr (Ident);
} }
} else if (IsQuoteChar(C)) { } else if (IsQuoteChar (CurC)) {
mptr = CopyQuotedString (C, mptr); mptr = CopyQuotedString (mptr);
} else { } else {
*mptr++ = *lptr++; *mptr++ = CurC;
NextChar ();
} }
} }
/* Reset the line pointer */ /* Reset the line pointer */
lptr = SavePtr; InitLine (SavePtr);
} }
@@ -222,19 +236,18 @@ static int MacroCall (Macro* M)
unsigned ArgCount; /* Macro argument count */ unsigned ArgCount; /* Macro argument count */
unsigned ParCount; /* Number of open parenthesis */ unsigned ParCount; /* Number of open parenthesis */
char Buf[LINESIZE]; /* Argument buffer */ char Buf[LINESIZE]; /* Argument buffer */
char C;
const char* ArgStart; const char* ArgStart;
char* B; char* B;
/* Expect an argument list */ /* Expect an argument list */
skipblank (); SkipBlank ();
if (*lptr != '(') { if (CurC != '(') {
PPError (ERR_ILLEGAL_MACRO_CALL); PPError (ERR_ILLEGAL_MACRO_CALL);
return 0; return 0;
} }
/* Eat the left paren */ /* Eat the left paren */
++lptr; NextChar ();
/* Read the actual macro arguments and store pointers to these arguments /* Read the actual macro arguments and store pointers to these arguments
* into the array of actual arguments in the macro definition. * into the array of actual arguments in the macro definition.
@@ -244,52 +257,59 @@ static int MacroCall (Macro* M)
ArgStart = Buf; ArgStart = Buf;
B = Buf; B = Buf;
while (1) { while (1) {
C = *lptr; if (CurC == '(') {
if (C == '(') { /* Nested parenthesis */
*B++ = gch (); *B++ = CurC;
NextChar ();
++ParCount; ++ParCount;
} else if (IsQuoteChar(C)) { } else if (IsQuoteChar (CurC)) {
B = CopyQuotedString (C, B); B = CopyQuotedString (B);
} else if (C == ',' || C == ')') { } else if (CurC == ',' || CurC == ')') {
if (ParCount == 0) { if (ParCount == 0) {
/* End of actual argument */ /* End of actual argument */
gch ();
*B++ = '\0'; *B++ = '\0';
while (IsBlank(*ArgStart)) { while (IsBlank(*ArgStart)) {
++ArgStart; ++ArgStart;
} }
if (ArgCount < M->ArgCount) { if (ArgCount < M->ArgCount) {
M->ActualArgs[ArgCount++] = ArgStart; M->ActualArgs[ArgCount++] = ArgStart;
} else if (C != ')' || *ArgStart != '\0' || M->ArgCount > 0) { } else if (CurC != ')' || *ArgStart != '\0' || M->ArgCount > 0) {
/* Be sure not to count the single empty argument for a /* Be sure not to count the single empty argument for a
* macro that does not have arguments. * macro that does not have arguments.
*/ */
++ArgCount; ++ArgCount;
} }
/* Start the next one */ /* Check for end of macro param list */
ArgStart = B; if (CurC == ')') {
if (C == ')') { NextChar ();
break; break;
} }
/* Start the next param */
ArgStart = B;
NextChar ();
} else { } else {
*B++ = gch (); /* Comma or right paren inside nested parenthesis */
if (C == ')') { if (CurC == ')') {
--ParCount; --ParCount;
} }
*B++ = CurC;
NextChar ();
} }
} else if (IsBlank (C)) { } else if (IsBlank (CurC)) {
/* Squeeze runs of blanks */ /* Squeeze runs of blanks */
*B++ = ' '; *B++ = ' ';
skipblank (); SkipBlank ();
} else if (C == '\0') { } else if (CurC == '\0') {
/* End of line inside macro argument list - read next line */ /* End of line inside macro argument list - read next line */
if (NextLine () == 0) { if (NextLine () == 0) {
return 0; return 0;
} }
} else { } else {
/* Just copy the character */ /* Just copy the character */
*B++ = *lptr++; *B++ = CurC;
NextChar ();
} }
} }
@@ -337,8 +357,8 @@ static void addmac (void)
Macro* M; Macro* M;
/* Read the macro name */ /* Read the macro name */
skipblank (); SkipBlank ();
if (!macname (Ident)) { if (!MacName (Ident)) {
return; return;
} }
@@ -346,34 +366,36 @@ static void addmac (void)
M = NewMacro (Ident); M = NewMacro (Ident);
/* Check if this is a function like macro */ /* Check if this is a function like macro */
if (*lptr == '(') { if (CurC == '(') {
/* Skip the left paren */ /* Skip the left paren */
gch (); NextChar ();
/* Set the marker that this is a function like macro */ /* Set the marker that this is a function like macro */
M->ArgCount = 0; M->ArgCount = 0;
/* Read the formal parameter list */ /* Read the formal parameter list */
while (1) { while (1) {
skipblank (); SkipBlank ();
if (*lptr == ')') if (CurC == ')')
break; break;
if (macname (Ident) == 0) { if (MacName (Ident) == 0) {
return; return;
} }
AddMacroArg (M, Ident); AddMacroArg (M, Ident);
skipblank (); SkipBlank ();
if (*lptr != ',') if (CurC != ',')
break; break;
gch (); NextChar ();
} }
if (*lptr != ')') {
/* Check for a right paren and eat it if we find one */
if (CurC != ')') {
PPError (ERR_RPAREN_EXPECTED); PPError (ERR_RPAREN_EXPECTED);
ClearLine (); ClearLine ();
return; return;
} }
gch (); NextChar ();
} }
/* Insert the macro into the macro table and allocate the ActualArgs array */ /* Insert the macro into the macro table and allocate the ActualArgs array */
@@ -382,7 +404,7 @@ static void addmac (void)
/* Remove whitespace and comments from the line, store the preprocessed /* Remove whitespace and comments from the line, store the preprocessed
* line into Buf. * line into Buf.
*/ */
skipblank (); SkipBlank ();
saveptr = mptr; saveptr = mptr;
Pass1 (lptr, Buf); Pass1 (lptr, Buf);
mptr = saveptr; mptr = saveptr;
@@ -399,59 +421,63 @@ static void addmac (void)
static int Pass1 (char* from, char* to) static int Pass1 (const char* From, char* To)
/* Preprocessor pass 1. Remove whitespace and comments. */ /* Preprocessor pass 1. Remove whitespace and comments. */
{ {
int c;
int done; int done;
ident Ident; ident Ident;
int HaveParen; int HaveParen;
lptr = from; /* Initialize reading from "From" */
mptr = to; InitLine (From);
/* Target is "To" */
mptr = To;
/* Loop removing ws and comments */
done = 1; done = 1;
while ((c = *lptr) != 0) { while (CurC != '\0') {
if (IsBlank (c)) { if (IsBlank (CurC)) {
keepch (' '); keepch (' ');
skipblank (); SkipBlank ();
} else if (IsIdent (c)) { } else if (IsIdent (CurC)) {
symname (Ident); SymName (Ident);
if (Preprocessing && strcmp(Ident, "defined") == 0) { if (Preprocessing && strcmp(Ident, "defined") == 0) {
/* Handle the "defined" operator */ /* Handle the "defined" operator */
skipblank(); SkipBlank();
HaveParen = 0; HaveParen = 0;
if (*lptr == '(') { if (CurC == '(') {
HaveParen = 1; HaveParen = 1;
++lptr; NextChar ();
skipblank(); SkipBlank();
} }
if (!IsIdent(c)) { if (!IsIdent (CurC)) {
PPError (ERR_IDENT_EXPECTED); PPError (ERR_IDENT_EXPECTED);
*mptr++ = '0'; *mptr++ = '0';
} else { } else {
symname (Ident); SymName (Ident);
*mptr++ = IsMacro (Ident)? '1' : '0'; *mptr++ = IsMacro (Ident)? '1' : '0';
if (HaveParen) { if (HaveParen) {
skipblank(); SkipBlank();
if (*lptr != ')') { if (CurC != ')') {
PPError (ERR_RPAREN_EXPECTED); PPError (ERR_RPAREN_EXPECTED);
} else { } else {
++lptr; NextChar ();
} }
} }
} }
} else { } else {
if (MaybeMacro(c)) { if (MaybeMacro (Ident[0])) {
done = 0; done = 0;
} }
keepstr (Ident); keepstr (Ident);
} }
} else if (IsQuoteChar(c)) { } else if (IsQuoteChar (CurC)) {
mptr = CopyQuotedString (c, mptr); mptr = CopyQuotedString (mptr);
} else if (c == '/' && nch () == '*') { } else if (CurC == '/' && NextC == '*') {
keepch (' '); keepch (' ');
comment (); Comment ();
} else if (ANSI == 0 && c == '/' && nch () == '/') { } else if (ANSI == 0 && CurC == '/' && NextC == '/') {
keepch (' '); keepch (' ');
/* Beware: Because line continuation chars are handled when reading /* Beware: Because line continuation chars are handled when reading
* lines, we may only skip til the end of the source line, which * lines, we may only skip til the end of the source line, which
@@ -459,13 +485,14 @@ static int Pass1 (char* from, char* to)
* source line is denoted by a lf (\n) character. * source line is denoted by a lf (\n) character.
*/ */
do { do {
++lptr; NextChar ();
} while (*lptr != '\n' && *lptr != '\0'); } while (CurC != '\n' && CurC != '\0');
if (*lptr == '\n') { if (CurC == '\n') {
++lptr; NextChar ();
} }
} else { } else {
*mptr++ = *lptr++; *mptr++ = CurC;
NextChar ();
} }
} }
keepch ('\0'); keepch ('\0');
@@ -474,21 +501,25 @@ static int Pass1 (char* from, char* to)
static int Pass2 (char *from, char *to) static int Pass2 (const char* From, char* To)
/* Preprocessor pass 2. Perform macro substitution. */ /* Preprocessor pass 2. Perform macro substitution. */
{ {
int C;
int no_chg; int no_chg;
ident Ident; ident Ident;
Macro* M; Macro* M;
lptr = from; /* Initialize reading from "From" */
mptr = to; InitLine (From);
/* Target is "To" */
mptr = To;
/* Loop substituting macros */
no_chg = 1; no_chg = 1;
while ((C = *lptr) != '\0') { while (CurC != '\0') {
/* If we have an identifier, check if it's a macro */ /* If we have an identifier, check if it's a macro */
if (IsIdent (C)) { if (IsIdent (CurC)) {
symname (Ident); SymName (Ident);
M = FindMacro (Ident); M = FindMacro (Ident);
if (M) { if (M) {
ExpandMacro (M); ExpandMacro (M);
@@ -496,10 +527,11 @@ static int Pass2 (char *from, char *to)
} else { } else {
keepstr (Ident); keepstr (Ident);
} }
} else if (IsQuoteChar(C)) { } else if (IsQuoteChar(CurC)) {
mptr = CopyQuotedString (C, mptr); mptr = CopyQuotedString (mptr);
} else { } else {
*mptr++ = *lptr++; *mptr++ = CurC;
NextChar ();
} }
} }
return no_chg; return no_chg;
@@ -512,7 +544,6 @@ static void xlateline (void)
{ {
int cnt; int cnt;
int Done; int Done;
char *p;
Done = Pass1 (line, mline); Done = Pass1 (line, mline);
if (ExpandMacros == 0) { if (ExpandMacros == 0) {
@@ -521,7 +552,8 @@ static void xlateline (void)
} }
cnt = 5; cnt = 5;
do { do {
p = line; /* Swap mline and line */
char* p = line;
line = mline; line = mline;
mline = p; mline = p;
if (Done) if (Done)
@@ -529,7 +561,9 @@ static void xlateline (void)
Done = Pass2 (line, mline); Done = Pass2 (line, mline);
keepch ('\0'); keepch ('\0');
} while (--cnt); } while (--cnt);
lptr = line;
/* Reinitialize line parsing */
InitLine (line);
} }
@@ -539,8 +573,8 @@ static void doundef (void)
{ {
ident Ident; ident Ident;
skipblank (); SkipBlank ();
if (macname (Ident)) { if (MacName (Ident)) {
UndefineMacro (Ident); UndefineMacro (Ident);
} }
} }
@@ -574,11 +608,18 @@ static int doiff (int skip)
Token sv2 = NextTok; Token sv2 = NextTok;
/* Remove the #if from the line and add two semicolons as sentinels */ /* Remove the #if from the line and add two semicolons as sentinels */
skipblank (); SkipBlank ();
S = line; S = line;
while ((*S++ = *lptr++) != '\0') ; while (CurC != '\0') {
strcpy (S-1, ";;"); *S++ = CurC;
lptr = line; NextChar ();
}
*S++ = ';';
*S++ = ';';
*S = '\0';
/* Start over parsing from line */
InitLine (line);
/* Switch into special preprocessing mode */ /* Switch into special preprocessing mode */
Preprocessing = 1; Preprocessing = 1;
@@ -611,8 +652,8 @@ static int doifdef (int skip, int flag)
{ {
ident Ident; ident Ident;
skipblank (); SkipBlank ();
if (macname (Ident) == 0) { if (MacName (Ident) == 0) {
return 0; return 0;
} else { } else {
return setmflag (skip, flag, IsMacro(Ident)); return setmflag (skip, flag, IsMacro(Ident));
@@ -624,21 +665,17 @@ static int doifdef (int skip, int flag)
static void doinclude (void) static void doinclude (void)
/* Open an include file. */ /* Open an include file. */
{ {
unsigned Length;
char* End;
char* Name;
char RTerm; char RTerm;
unsigned DirSpec; unsigned DirSpec;
/* Skip blanks */ /* Skip blanks */
mptr = mline; SkipBlank ();
skipblank ();
/* 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.
*/ */
switch (cgch()) { switch (CurC) {
case '\"': case '\"':
RTerm = '\"'; RTerm = '\"';
@@ -654,26 +691,27 @@ static void doinclude (void)
PPError (ERR_INCLUDE_LTERM_EXPECTED); PPError (ERR_INCLUDE_LTERM_EXPECTED);
goto Done; goto Done;
} }
NextChar ();
/* Search for the right terminator */ /* Copy the filename into mline. Since mline has the same size as the
End = strchr (lptr, RTerm); * input line, we don't need to check for an overflow here.
if (End == 0) { */
mptr = mline;
while (CurC != '\0' && CurC != RTerm) {
*mptr++ = CurC;
NextChar ();
}
*mptr = '\0';
/* Check if we got a terminator */
if (CurC != RTerm) {
/* No terminator found */ /* No terminator found */
PPError (ERR_INCLUDE_RTERM_EXPECTED); PPError (ERR_INCLUDE_RTERM_EXPECTED);
goto Done; goto Done;
} }
/* Create a temp copy of the filename */
Length = End - lptr;
Name = xmalloc (Length + 1);
memcpy (Name, lptr, Length);
Name[Length] = '\0';
/* Open the include file */ /* Open the include file */
OpenIncludeFile (Name, DirSpec); OpenIncludeFile (mline, DirSpec);
/* Delete the temp filename copy */
xfree (Name);
Done: Done:
/* Clear the remaining line so the next input will come from the new /* Clear the remaining line so the next input will come from the new
@@ -687,8 +725,8 @@ Done:
static void doerror (void) static void doerror (void)
/* Print an error */ /* Print an error */
{ {
skipblank (); SkipBlank ();
if (*lptr == '\0') { if (CurC == '\0') {
PPError (ERR_INVALID_USER_ERROR); PPError (ERR_INVALID_USER_ERROR);
} else { } else {
PPError (ERR_USER_ERROR, lptr); PPError (ERR_USER_ERROR, lptr);
@@ -704,38 +742,38 @@ static void doerror (void)
/* stuff used to bum the keyword dispatching stuff */ /* stuff used to bum the keyword dispatching stuff */
enum { enum {
D_DEFINE, PP_DEFINE,
D_ELSE, PP_ELSE,
D_ENDIF, PP_ENDIF,
D_ERROR, PP_ERROR,
D_IF, PP_IF,
D_IFDEF, PP_IFDEF,
D_IFNDEF, PP_IFNDEF,
D_INCLUDE, PP_INCLUDE,
D_LINE, PP_LINE,
D_PRAGMA, PP_PRAGMA,
D_UNDEF, PP_UNDEF,
D_ILLEGAL, PP_ILLEGAL,
}; };
static const struct tok_elt pre_toks[] = { static const struct tok_elt pre_toks[] = {
{ "define", D_DEFINE }, { "define", PP_DEFINE },
{ "else", D_ELSE }, { "else", PP_ELSE },
{ "endif", D_ENDIF }, { "endif", PP_ENDIF },
{ "error", D_ERROR }, { "error", PP_ERROR },
{ "if", D_IF }, { "if", PP_IF },
{ "ifdef", D_IFDEF }, { "ifdef", PP_IFDEF },
{ "ifndef", D_IFNDEF }, { "ifndef", PP_IFNDEF },
{ "include", D_INCLUDE }, { "include", PP_INCLUDE },
{ "line", D_LINE }, { "line", PP_LINE },
{ "pragma", D_PRAGMA }, { "pragma", PP_PRAGMA },
{ "undef", D_UNDEF }, { "undef", PP_UNDEF },
{ 0, D_ILLEGAL } { 0, PP_ILLEGAL }
}; };
int searchtok (const char *sym, const struct tok_elt *toks) static int searchtok (const char *sym, const struct tok_elt *toks)
/* Search a token in a table */ /* Search a token in a table */
{ {
while (toks->toknam && strcmp (toks->toknam, sym)) while (toks->toknam && strcmp (toks->toknam, sym))
@@ -745,44 +783,40 @@ int searchtok (const char *sym, const struct tok_elt *toks)
void preprocess (void) void Preprocess (void)
/* Preprocess a line */ /* Preprocess a line */
{ {
int c;
int Skip; int Skip;
ident sname; ident Directive;
/* Process compiler directives, skip empty lines */
lptr = line;
/* Skip white space at the beginning of the line */ /* Skip white space at the beginning of the line */
skipblank (); SkipBlank ();
/* Check for stuff to skip */ /* Check for stuff to skip */
Skip = 0; Skip = 0;
while ((c = *lptr) == '\0' || c == '#' || Skip) { while (CurC == '\0' || CurC == '#' || Skip) {
/* Check for preprocessor lines lines */ /* Check for preprocessor lines lines */
if (c == '#') { if (CurC == '#') {
++lptr; NextChar ();
skipblank (); SkipBlank ();
if (*lptr == '\0') { if (CurC == '\0') {
/* ignore the empty preprocessor directive */ /* Ignore the empty preprocessor directive */
continue; continue;
} }
if (!issym (sname)) { if (!IsSym (Directive)) {
PPError (ERR_CPP_DIRECTIVE_EXPECTED); PPError (ERR_CPP_DIRECTIVE_EXPECTED);
ClearLine (); ClearLine ();
} else { } else {
switch (searchtok (sname, pre_toks)) { switch (searchtok (Directive, pre_toks)) {
case D_DEFINE: case PP_DEFINE:
if (!Skip) { if (!Skip) {
addmac (); addmac ();
} }
break; break;
case D_ELSE: case PP_ELSE:
if (s_ifdef[i_ifdef] & 2) { if (s_ifdef[i_ifdef] & 2) {
if (s_ifdef[i_ifdef] & 4) { if (s_ifdef[i_ifdef] & 4) {
Skip = !Skip; Skip = !Skip;
@@ -793,7 +827,7 @@ void preprocess (void)
} }
break; break;
case D_ENDIF: case PP_ENDIF:
if (i_ifdef >= 0) { if (i_ifdef >= 0) {
Skip = s_ifdef[i_ifdef--] & 1; Skip = s_ifdef[i_ifdef--] & 1;
} else { } else {
@@ -801,31 +835,31 @@ void preprocess (void)
} }
break; break;
case D_ERROR: case PP_ERROR:
if (!Skip) { if (!Skip) {
doerror (); doerror ();
} }
break; break;
case D_IF: case PP_IF:
Skip = doiff (Skip); Skip = doiff (Skip);
break; break;
case D_IFDEF: case PP_IFDEF:
Skip = doifdef (Skip, 1); Skip = doifdef (Skip, 1);
break; break;
case D_IFNDEF: case PP_IFNDEF:
Skip = doifdef (Skip, 0); Skip = doifdef (Skip, 0);
break; break;
case D_INCLUDE: case PP_INCLUDE:
if (!Skip) { if (!Skip) {
doinclude (); doinclude ();
} }
break; break;
case D_LINE: case PP_LINE:
/* Not allowed in strict ANSI mode */ /* Not allowed in strict ANSI mode */
if (ANSI) { if (ANSI) {
PPError (ERR_CPP_DIRECTIVE_EXPECTED); PPError (ERR_CPP_DIRECTIVE_EXPECTED);
@@ -833,7 +867,7 @@ void preprocess (void)
} }
break; break;
case D_PRAGMA: case PP_PRAGMA:
if (!Skip) { if (!Skip) {
/* Don't expand macros in this line */ /* Don't expand macros in this line */
ExpandMacros = 0; ExpandMacros = 0;
@@ -842,7 +876,7 @@ void preprocess (void)
} }
break; break;
case D_UNDEF: case PP_UNDEF:
if (!Skip) { if (!Skip) {
doundef (); doundef ();
} }
@@ -861,7 +895,7 @@ void preprocess (void)
} }
return; return;
} }
skipblank (); SkipBlank ();
} }
Done: Done:

View File

@@ -34,10 +34,7 @@ extern unsigned char Preprocessing;
int searchtok (const char *sym, const struct tok_elt* toks); void Preprocess (void);
/* Search a token in a table */
void preprocess (void);
/* Preprocess a line */ /* Preprocess a line */

View File

@@ -43,7 +43,7 @@ Token NextTok; /* The next token */
#define TT_EXT 1 /* cc65 extension */ #define TT_EXT 1 /* cc65 extension */
/* Token table */ /* Token table */
static struct Keyword { static const struct Keyword {
char* Key; /* Keyword name */ char* Key; /* Keyword name */
unsigned char Tok; /* The token */ unsigned char Tok; /* The token */
unsigned char Type; /* Token type */ unsigned char Type; /* Token type */
@@ -114,7 +114,7 @@ static int CmpKey (const void* Key, const void* Elem)
static int FindKey (char* Key) static int FindKey (const char* Key)
/* Find a keyword and return the token. Return IDENT if the token is not a /* Find a keyword and return the token. Return IDENT if the token is not a
* keyword. * keyword.
*/ */
@@ -130,20 +130,20 @@ static int FindKey (char* Key)
static int skipwhite (void) static int SkipWhite (void)
/* Skip white space in the input stream, reading and preprocessing new lines /* Skip white space in the input stream, reading and preprocessing new lines
* if necessary. Return 0 if end of file is reached, return 1 otherwise. * if necessary. Return 0 if end of file is reached, return 1 otherwise.
*/ */
{ {
while (1) { while (1) {
while (*lptr == 0) { while (CurC == 0) {
if (NextLine () == 0) { if (NextLine () == 0) {
return 0; return 0;
} }
preprocess (); Preprocess ();
} }
if (*lptr == ' ' || *lptr == '\r') { if (CurC == ' ' || CurC == '\r') {
++lptr; NextChar ();
} else { } else {
return 1; return 1;
} }
@@ -152,27 +152,27 @@ static int skipwhite (void)
void symname (char *s) void SymName (char* s)
/* Get symbol from input stream */ /* Get symbol from input stream */
{ {
unsigned k = 0; unsigned k = 0;
do { do {
if (k != MAX_IDENTLEN) { if (k != MAX_IDENTLEN) {
++k; ++k;
*s++ = *lptr; *s++ = CurC;
} }
++lptr; NextChar ();
} while (IsIdent (*lptr) || isdigit (*lptr)); } while (IsIdent (CurC) || isdigit (CurC));
*s = '\0'; *s = '\0';
} }
int issym (char *s) int IsSym (char *s)
/* Get symbol from input stream or return 0 if not a symbol. */ /* Get symbol from input stream or return 0 if not a symbol. */
{ {
if (IsIdent (*lptr)) { if (IsIdent (CurC)) {
symname (s); SymName (s);
return 1; return 1;
} else { } else {
return 0; return 0;
@@ -181,11 +181,11 @@ int issym (char *s)
static void unknown (unsigned char c) static void unknown (char C)
/* Error message for unknown character */ /* Error message for unknown character */
{ {
Error (ERR_INVALID_CHAR, c); Error (ERR_INVALID_CHAR, C);
gch (); /* Skip */ NextChar (); /* Skip */
} }
@@ -209,7 +209,7 @@ static void SetTok (int tok)
/* set nxttok and bump line ptr */ /* set nxttok and bump line ptr */
{ {
nxttok = tok; nxttok = tok;
++lptr; NextChar ();
} }
@@ -226,63 +226,73 @@ static int SignExtendChar (int C)
static int parsechar (int c) static int ParseChar (void)
/* Parse a character. Converts \n into EOL, etc. */ /* Parse a character. Converts \n into EOL, etc. */
{ {
int i; int i;
int val; unsigned val;
int C;
/* Check for escape chars */ /* Check for escape chars */
if (c == '\\') { if (CurC == '\\') {
switch (c = gch ()) { NextChar ();
switch (CurC) {
case 'b': case 'b':
c = '\b'; C = '\b';
break; break;
case 'f': case 'f':
c = '\f'; C = '\f';
break; break;
case 'r': case 'r':
c = '\r'; C = '\r';
break; break;
case 'n': case 'n':
c = '\n'; C = '\n';
break; break;
case 't': case 't':
c = '\t'; C = '\t';
break; break;
case '\"': case '\"':
c = '\"'; C = '\"';
break; break;
case '\'': case '\'':
c = '\''; C = '\'';
break; break;
case '\\': case '\\':
c = '\\'; C = '\\';
break; break;
case 'x': case 'x':
case 'X': case 'X':
/* Hex character constant */ /* Hex character constant */
val = hexval (gch ()) << 4; NextChar ();
c = val | hexval (gch ()); /* Do not translate */ val = hexval (CurC) << 4;
NextChar ();
C = val | hexval (CurC); /* Do not translate */
break; break;
case '0': case '0':
case '1': case '1':
/* Octal constant */ /* Octal constant */
i = 0; i = 0;
val = c - '0'; C = CurC - '0';
while ((c = *lptr) >= '0' && c <= '7' && i++ < 4) { while (NextC >= '0' && NextC <= '7' && i++ < 4) {
val = (val << 3) | (c - '0'); NextChar ();
gch (); C = (C << 3) | (CurC - '0');
} }
c = val; /* Do not translate */
break; break;
default: default:
Error (ERR_ILLEGAL_CHARCONST); Error (ERR_ILLEGAL_CHARCONST);
C = ' ';
break;
} }
} else {
C = CurC;
} }
/* Skip the character read */
NextChar ();
/* Do correct sign extension */ /* Do correct sign extension */
return SignExtendChar (c); return SignExtendChar (C);
} }
@@ -290,22 +300,25 @@ static int parsechar (int c)
static void CharConst (void) static void CharConst (void)
/* Parse a character constant. */ /* Parse a character constant. */
{ {
int c; int C;
/* Skip the quote */ /* Skip the quote */
++lptr; NextChar ();
/* Get character */ /* Get character */
c = parsechar (cgch ()); C = ParseChar ();
/* Check for closing quote */ /* Check for closing quote */
if (cgch () != '\'') { if (CurC != '\'') {
Error (ERR_QUOTE_EXPECTED); Error (ERR_QUOTE_EXPECTED);
} else {
/* Skip the quote */
NextChar ();
} }
/* Setup values and attributes */ /* Setup values and attributes */
nxttok = TOK_CCONST; nxttok = TOK_CCONST;
nxtval = SignExtendChar (ctrans (c)); /* Translate into target charset */ nxtval = SignExtendChar (ctrans (C)); /* Translate into target charset */
nxttype = type_int; /* Character constants have type int */ nxttype = type_int; /* Character constants have type int */
} }
@@ -318,24 +331,24 @@ static void StringConst (void)
nxttok = TOK_SCONST; nxttok = TOK_SCONST;
/* Be sure to concatenate strings */ /* Be sure to concatenate strings */
while (*lptr == '\"') { while (CurC == '\"') {
/* Skip the quote char */ /* Skip the quote char */
++lptr; NextChar ();
while (*lptr != '\"') { while (CurC != '\"') {
if (*lptr == 0) { if (CurC == '\0') {
Error (ERR_UNEXPECTED_NEWLINE); Error (ERR_UNEXPECTED_NEWLINE);
break; break;
} }
AddLiteralChar (parsechar (gch())); AddLiteralChar (ParseChar ());
} }
/* Skip closing quote char if there was one */ /* Skip closing quote char if there was one */
cgch (); NextChar ();
/* Skip white space, read new input */ /* Skip white space, read new input */
skipwhite (); SkipWhite ();
} }
@@ -348,7 +361,6 @@ static void StringConst (void)
void NextToken (void) void NextToken (void)
/* Get next token from input stream */ /* Get next token from input stream */
{ {
char c;
ident token; ident token;
/* Current token is the lookahead token */ /* Current token is the lookahead token */
@@ -358,15 +370,14 @@ void NextToken (void)
NextTok.Pos = GetCurrentLine(); NextTok.Pos = GetCurrentLine();
/* Skip spaces and read the next line if needed */ /* Skip spaces and read the next line if needed */
if (skipwhite () == 0) { if (SkipWhite () == 0) {
/* End of file reached */ /* End of file reached */
nxttok = TOK_CEOF; nxttok = TOK_CEOF;
return; return;
} }
/* Determine the next token from the lookahead */ /* Determine the next token from the lookahead */
c = *lptr; if (isdigit (CurC)) {
if (isdigit (c)) {
/* A number */ /* A number */
int HaveSuffix; /* True if we have a type suffix */ int HaveSuffix; /* True if we have a type suffix */
@@ -378,49 +389,48 @@ void NextToken (void)
base = 10; base = 10;
types = IT_INT | IT_LONG | IT_ULONG; types = IT_INT | IT_LONG | IT_ULONG;
if (c == '0') { if (CurC == '0') {
/* Octal or hex constants may also be of type unsigned int */ /* Octal or hex constants may also be of type unsigned int */
types = IT_INT | IT_UINT | IT_LONG | IT_ULONG; types = IT_INT | IT_UINT | IT_LONG | IT_ULONG;
/* gobble 0 and examin next char */ /* gobble 0 and examin next char */
if (toupper (*++lptr) == 'X') { NextChar ();
if (toupper (CurC) == 'X') {
base = 16; base = 16;
nxttype = type_uint; nxttype = type_uint;
++lptr; /* gobble "x" */ NextChar (); /* gobble "x" */
} else { } else {
base = 8; base = 8;
} }
} }
while (1) { while (1) {
c = *lptr; if (isdigit (CurC)) {
if (isdigit (c)) { k = k * base + (CurC - '0');
k = k * base + (c - '0'); } else if (base == 16 && isxdigit (CurC)) {
} else if (base == 16 && isxdigit (c)) { k = (k << 4) + hexval (CurC);
k = (k << 4) + hexval (c);
} else { } else {
break; /* not digit */ break; /* not digit */
} }
++lptr; /* gobble char */ NextChar (); /* gobble char */
} }
/* Check for a suffix */ /* Check for a suffix */
HaveSuffix = 1; HaveSuffix = 1;
c = toupper (*lptr); if (CurC == 'u' || CurC == 'U') {
if (c == 'U') {
/* Unsigned type */ /* Unsigned type */
++lptr; NextChar ();
if (toupper (*lptr) != 'L') { if (toupper (CurC) != 'L') {
types = IT_UINT | IT_ULONG; types = IT_UINT | IT_ULONG;
} else { } else {
++lptr; NextChar ();
types = IT_ULONG; types = IT_ULONG;
} }
} else if (c == 'L') { } else if (CurC == 'l' || CurC == 'L') {
/* Long type */ /* Long type */
++lptr; NextChar ();
if (toupper (*lptr) != 'U') { if (toupper (CurC) != 'U') {
types = IT_LONG | IT_ULONG; types = IT_LONG | IT_ULONG;
} else { } else {
++lptr; NextChar ();
types = IT_ULONG; types = IT_ULONG;
} }
} else { } else {
@@ -465,7 +475,7 @@ void NextToken (void)
return; return;
} }
if (issym (token)) { if (IsSym (token)) {
/* Check for a keyword */ /* Check for a keyword */
if ((nxttok = FindKey (token)) != TOK_IDENT) { if ((nxttok = FindKey (token)) != TOK_IDENT) {
@@ -506,10 +516,11 @@ void NextToken (void)
} }
/* Monstrous switch statement ahead... */ /* Monstrous switch statement ahead... */
switch (c) { switch (CurC) {
case '!': case '!':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_NE); SetTok (TOK_NE);
} else { } else {
nxttok = TOK_BOOL_NOT; nxttok = TOK_BOOL_NOT;
@@ -521,7 +532,8 @@ void NextToken (void)
break; break;
case '%': case '%':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_MOD_ASSIGN); SetTok (TOK_MOD_ASSIGN);
} else { } else {
nxttok = TOK_MOD; nxttok = TOK_MOD;
@@ -529,7 +541,8 @@ void NextToken (void)
break; break;
case '&': case '&':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '&': case '&':
SetTok (TOK_BOOL_AND); SetTok (TOK_BOOL_AND);
break; break;
@@ -554,7 +567,8 @@ void NextToken (void)
break; break;
case '*': case '*':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_MUL_ASSIGN); SetTok (TOK_MUL_ASSIGN);
} else { } else {
nxttok = TOK_STAR; nxttok = TOK_STAR;
@@ -562,7 +576,8 @@ void NextToken (void)
break; break;
case '+': case '+':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '+': case '+':
SetTok (TOK_INC); SetTok (TOK_INC);
break; break;
@@ -579,7 +594,8 @@ void NextToken (void)
break; break;
case '-': case '-':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '-': case '-':
SetTok (TOK_DEC); SetTok (TOK_DEC);
break; break;
@@ -595,11 +611,13 @@ void NextToken (void)
break; break;
case '.': case '.':
if (*++lptr == '.') { NextChar ();
if (*++lptr == '.') { if (CurC == '.') {
NextChar ();
if (CurC == '.') {
SetTok (TOK_ELLIPSIS); SetTok (TOK_ELLIPSIS);
} else { } else {
unknown (*lptr); unknown (CurC);
} }
} else { } else {
nxttok = TOK_DOT; nxttok = TOK_DOT;
@@ -607,7 +625,8 @@ void NextToken (void)
break; break;
case '/': case '/':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_DIV_ASSIGN); SetTok (TOK_DIV_ASSIGN);
} else { } else {
nxttok = TOK_DIV; nxttok = TOK_DIV;
@@ -623,12 +642,14 @@ void NextToken (void)
break; break;
case '<': case '<':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '=': case '=':
SetTok (TOK_LE); SetTok (TOK_LE);
break; break;
case '<': case '<':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_SHL_ASSIGN); SetTok (TOK_SHL_ASSIGN);
} else { } else {
nxttok = TOK_SHL; nxttok = TOK_SHL;
@@ -640,7 +661,8 @@ void NextToken (void)
break; break;
case '=': case '=':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_EQ); SetTok (TOK_EQ);
} else { } else {
nxttok = TOK_ASSIGN; nxttok = TOK_ASSIGN;
@@ -648,12 +670,14 @@ void NextToken (void)
break; break;
case '>': case '>':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '=': case '=':
SetTok (TOK_GE); SetTok (TOK_GE);
break; break;
case '>': case '>':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_SHR_ASSIGN); SetTok (TOK_SHR_ASSIGN);
} else { } else {
nxttok = TOK_SHR; nxttok = TOK_SHR;
@@ -677,7 +701,8 @@ void NextToken (void)
break; break;
case '^': case '^':
if (*++lptr == '=') { NextChar ();
if (CurC == '=') {
SetTok (TOK_XOR_ASSIGN); SetTok (TOK_XOR_ASSIGN);
} else { } else {
nxttok = TOK_XOR; nxttok = TOK_XOR;
@@ -689,7 +714,8 @@ void NextToken (void)
break; break;
case '|': case '|':
switch (*++lptr) { NextChar ();
switch (CurC) {
case '|': case '|':
SetTok (TOK_BOOL_OR); SetTok (TOK_BOOL_OR);
break; break;
@@ -710,8 +736,11 @@ void NextToken (void)
break; break;
case '#': case '#':
while (*++lptr == ' ') ; /* Skip it and following whitespace */ /* Skip it and following whitespace */
if (!issym (token) || strcmp (token, "pragma") != 0) { do {
NextChar ();
} while (CurC == ' ');
if (!IsSym (token) || strcmp (token, "pragma") != 0) {
/* OOPS - should not happen */ /* OOPS - should not happen */
Error (ERR_CPP_DIRECTIVE_EXPECTED); Error (ERR_CPP_DIRECTIVE_EXPECTED);
} }
@@ -719,7 +748,7 @@ void NextToken (void)
break; break;
default: default:
unknown (c); unknown (CurC);
} }

View File

@@ -172,10 +172,10 @@ extern Token NextTok; /* The next token */
void symname (char* s); void SymName (char* s);
/* Get symbol from input stream */ /* Get symbol from input stream */
int issym (char* s); int IsSym (char* s);
/* Get symbol from input stream or return 0 if not a symbol. */ /* Get symbol from input stream or return 0 if not a symbol. */
void NextToken (void); void NextToken (void);