/*****************************************************************************/
/* */
-/* scanner.c */
+/* scanner.c */
/* */
-/* Configuration file scanner for the da65 disassembler */
+/* Configuration file scanner for the da65 disassembler */
/* */
/* */
/* */
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/* Current token and attributes */
unsigned InfoTok;
-char InfoSVal [CFG_MAX_IDENT_LEN+1];
+char InfoSVal [CFG_MAX_IDENT_LEN+1];
long InfoIVal;
/* Error location */
-unsigned InfoErrorLine;
-unsigned InfoErrorCol;
+unsigned InfoErrorLine;
+unsigned InfoErrorCol;
/* Input sources for the configuration */
-static const char* InfoFile = 0;
+static const char* InfoFile = 0;
/* Other input stuff */
-static int C = ' ';
-static unsigned InputLine = 1;
-static unsigned InputCol = 0;
-static FILE* InputFile = 0;
+static int C = ' ';
+static unsigned InputLine = 1;
+static unsigned InputCol = 0;
+static FILE* InputFile = 0;
/*****************************************************************************/
-/* Error handling */
+/* Error handling */
/*****************************************************************************/
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
/* Count columns */
if (C != EOF) {
- ++InputCol;
+ ++InputCol;
}
/* Count lines */
if (C == '\n') {
- ++InputLine;
- InputCol = 0;
+ ++InputLine;
+ InputCol = 0;
}
}
/* Return the value for a numeric digit */
{
if (IsDigit (C)) {
- return C - '0';
+ return C - '0';
} else {
- return toupper (C) - 'A' + 10;
+ return toupper (C) - 'A' + 10;
}
}
/* Read the next token from the input stream */
{
unsigned I;
-
+ int Esc;
Again:
/* Skip whitespace */
while (IsSpace (C)) {
- NextChar ();
+ NextChar ();
}
/* Remember the current position */
/* Identifier? */
if (C == '_' || IsAlpha (C)) {
- /* Read the identifier */
- I = 0;
- while (C == '_' || IsAlNum (C)) {
- if (I < CFG_MAX_IDENT_LEN) {
- InfoSVal [I++] = C;
- }
- NextChar ();
- }
- InfoSVal [I] = '\0';
- InfoTok = INFOTOK_IDENT;
- return;
+ /* Read the identifier */
+ I = 0;
+ while (C == '_' || IsAlNum (C)) {
+ if (I < CFG_MAX_IDENT_LEN) {
+ InfoSVal [I++] = C;
+ }
+ NextChar ();
+ }
+ InfoSVal [I] = '\0';
+ InfoTok = INFOTOK_IDENT;
+ return;
}
/* Hex number? */
if (C == '$') {
- NextChar ();
- if (!IsXDigit (C)) {
- InfoError ("Hex digit expected");
- }
- InfoIVal = 0;
- while (IsXDigit (C)) {
- InfoIVal = InfoIVal * 16 + DigitVal (C);
- NextChar ();
- }
- InfoTok = INFOTOK_INTCON;
- return;
+ NextChar ();
+ if (!IsXDigit (C)) {
+ InfoError ("Hex digit expected");
+ }
+ InfoIVal = 0;
+ while (IsXDigit (C)) {
+ InfoIVal = InfoIVal * 16 + DigitVal (C);
+ NextChar ();
+ }
+ InfoTok = INFOTOK_INTCON;
+ return;
}
/* Decimal number? */
if (IsDigit (C)) {
- InfoIVal = 0;
- while (IsDigit (C)) {
- InfoIVal = InfoIVal * 10 + DigitVal (C);
- NextChar ();
- }
- InfoTok = INFOTOK_INTCON;
- return;
+ InfoIVal = 0;
+ while (IsDigit (C)) {
+ InfoIVal = InfoIVal * 10 + DigitVal (C);
+ NextChar ();
+ }
+ InfoTok = INFOTOK_INTCON;
+ return;
}
/* Other characters */
switch (C) {
- case '{':
- NextChar ();
- InfoTok = INFOTOK_LCURLY;
- break;
+ case '{':
+ NextChar ();
+ InfoTok = INFOTOK_LCURLY;
+ break;
- case '}':
- NextChar ();
- InfoTok = INFOTOK_RCURLY;
- break;
+ case '}':
+ NextChar ();
+ InfoTok = INFOTOK_RCURLY;
+ break;
- case ';':
- NextChar ();
- InfoTok = INFOTOK_SEMI;
- break;
+ case ';':
+ NextChar ();
+ InfoTok = INFOTOK_SEMI;
+ break;
- case '.':
- NextChar ();
- InfoTok = INFOTOK_DOT;
- break;
+ case '.':
+ NextChar ();
+ InfoTok = INFOTOK_DOT;
+ break;
- case ',':
- NextChar ();
- InfoTok = INFOTOK_COMMA;
- break;
+ case ',':
+ NextChar ();
+ InfoTok = INFOTOK_COMMA;
+ break;
- case '=':
- NextChar ();
- InfoTok = INFOTOK_EQ;
- break;
+ case '=':
+ NextChar ();
+ InfoTok = INFOTOK_EQ;
+ break;
case ':':
- NextChar ();
- InfoTok = INFOTOK_COLON;
- break;
+ NextChar ();
+ InfoTok = INFOTOK_COLON;
+ break;
case '\"':
- NextChar ();
- I = 0;
- while (C != '\"') {
- if (C == EOF || C == '\n') {
- InfoError ("Unterminated string");
- }
- if (I < CFG_MAX_IDENT_LEN) {
- InfoSVal [I++] = C;
- }
- NextChar ();
- }
- NextChar ();
- InfoSVal [I] = '\0';
- InfoTok = INFOTOK_STRCON;
- break;
+ NextChar ();
+ I = 0;
+ while (C != '\"') {
+ Esc = (C == '\\');
+ if (Esc) {
+ NextChar ();
+ }
+ if (C == EOF || C == '\n') {
+ InfoError ("Unterminated string");
+ }
+ if (Esc) {
+ switch (C) {
+ case '\"': C = '\"'; break;
+ case '\'': C = '\''; break;
+ default: InfoError ("Invalid escape char: %c", C);
+ }
+ }
+ if (I < CFG_MAX_IDENT_LEN) {
+ InfoSVal [I++] = C;
+ }
+ NextChar ();
+ }
+ NextChar ();
+ InfoSVal [I] = '\0';
+ InfoTok = INFOTOK_STRCON;
+ break;
case '\'':
NextChar ();
break;
case '#':
- /* Comment */
- while (C != '\n' && C != EOF) {
- NextChar ();
- }
- if (C != EOF) {
- goto Again;
- }
- InfoTok = INFOTOK_EOF;
- break;
+ /* Comment */
+ while (C != '\n' && C != EOF) {
+ NextChar ();
+ }
+ if (C != EOF) {
+ goto Again;
+ }
+ InfoTok = INFOTOK_EOF;
+ break;
case EOF:
- InfoTok = INFOTOK_EOF;
- break;
+ InfoTok = INFOTOK_EOF;
+ break;
- default:
- InfoError ("Invalid character `%c'", C);
+ default:
+ InfoError ("Invalid character `%c'", C);
}
}
/* Skip a token, print an error message if not found */
{
if (InfoTok != T) {
- InfoError (Msg);
+ InfoError (Msg);
}
InfoNextTok ();
}
/* Consume a comma if there is one */
{
if (InfoTok == INFOTOK_COMMA) {
- InfoNextTok ();
+ InfoNextTok ();
}
}
/* Consume an equal sign if there is one */
{
if (InfoTok == INFOTOK_EQ) {
- InfoNextTok ();
+ InfoNextTok ();
}
}
/* Make sure the next token is an integer */
{
if (InfoTok != INFOTOK_INTCON) {
- InfoError ("Integer constant expected");
+ InfoError ("Integer constant expected");
}
}
/* Make sure the next token is a string constant */
{
if (InfoTok != INFOTOK_STRCON) {
- InfoError ("String constant expected");
+ InfoError ("String constant expected");
}
}
/* Make sure the next token is a char constant */
{
if (InfoTok != INFOTOK_STRCON) {
- InfoError ("Character constant expected");
+ InfoError ("Character constant expected");
}
}
/* Make sure the next token is an identifier */
{
if (InfoTok != INFOTOK_IDENT) {
- InfoError ("Identifier expected");
+ InfoError ("Identifier expected");
}
}
/* Check the range of InfoIVal */
{
if (InfoIVal < Lo || InfoIVal > Hi) {
- InfoError ("Range error");
+ InfoError ("Range error");
}
}
/* We need an identifier */
if (InfoTok == INFOTOK_IDENT) {
- /* Make it upper case */
- I = 0;
- while (InfoSVal [I]) {
- InfoSVal [I] = toupper (InfoSVal [I]);
- ++I;
- }
-
- /* Linear search */
- for (I = 0; I < Size; ++I) {
- if (strcmp (InfoSVal, Table [I].Ident) == 0) {
- InfoTok = Table [I].Tok;
- return;
- }
- }
+ /* Make it upper case */
+ I = 0;
+ while (InfoSVal [I]) {
+ InfoSVal [I] = toupper (InfoSVal [I]);
+ ++I;
+ }
+
+ /* Linear search */
+ for (I = 0; I < Size; ++I) {
+ if (strcmp (InfoSVal, Table [I].Ident) == 0) {
+ InfoTok = Table [I].Tok;
+ return;
+ }
+ }
}
/* Map an identifier or integer to a boolean token */
{
static const IdentTok Booleans [] = {
- { "YES", INFOTOK_TRUE },
- { "NO", INFOTOK_FALSE },
+ { "YES", INFOTOK_TRUE },
+ { "NO", INFOTOK_FALSE },
{ "TRUE", INFOTOK_TRUE },
{ "FALSE", INFOTOK_FALSE },
- { "ON", INFOTOK_TRUE },
- { "OFF", INFOTOK_FALSE },
+ { "ON", INFOTOK_TRUE },
+ { "OFF", INFOTOK_FALSE },
};
/* If we have an identifier, map it to a boolean token */
if (InfoTok == INFOTOK_IDENT) {
- InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
+ InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
} else {
- /* We expected an integer here */
- if (InfoTok != INFOTOK_INTCON) {
- InfoError ("Boolean value expected");
- }
- InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
+ /* We expected an integer here */
+ if (InfoTok != INFOTOK_INTCON) {
+ InfoError ("Boolean value expected");
+ }
+ InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
}
}
/* Close the input file if we had one */
if (InputFile) {
(void) fclose (InputFile);
- InputFile = 0;
+ InputFile = 0;
}
}
-
-
-
-