home *** CD-ROM | disk | FTP | other *** search
-
- /* scanner for configuration tokens */
-
- %{
- #define YY_NEVER_INTERACTIVE 1
- #define YY_INPUT(buf,result,maxsize) result = command_context_getstring(cf, buf, maxsize)
-
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include "StringUtils.h"
-
- #define __COMMAND_L__
-
- #include "log.h"
-
- #define _L LOG_COMMANDS | LOG_INFO
-
- #include "xmalloc.h"
- #include "moduledb.h"
- #include "command.h"
- #include "command_parser.h"
- #include "command_lexer.h"
-
- #undef DEBUG
- // #define DEBUG 1
-
-
- /* Utilities */
-
- static int
- command_context_new_text(command_context **context,
- const command_context *outer,
- const char *name, const char *data, int len);
-
- static int
- command_context_new_file(command_context **context,
- const command_context *outer,
- const char *filename);
-
- static void
- command_context_free(command_context **context);
-
- static int
- command_context_getstring(command_context *context,
- char *buf, int maxsize);
-
- command_symbol_table *command_scope = NULL;
-
- #define TEST_MEMERR(x) do { if ((x) != OS_NOERR) logger(_L | LOG_FATAL,"Out of memory\n"); } while (0)
-
- /* Current command context being used by the scanner. */
- static command_context *cf;
-
- /* String buffer */
- OSHandle lexer_string;
-
- #include "command.y.h"
-
- // F_V9t9 and F_TIFILES
- #include "fiad.h"
- %}
-
- %x grouper
- %x comment
- %x preproc
- %x string
-
- DIGIT [0-9]
- HEXDIG [0-9a-fA-F]
- OCTDIG [0-7]
- /*
- STRINGCHAR [^\r\n\t +-\*]
- STRINGFIRST [^\r\n\t 0123456789\"]
- */
- STRINGFIRST [A-Za-z_/]
- /* STRINGCHAR ({STRINGFIRST}|[:\\0-9\~]) */
- STRINGCHAR [^ \t\r\n=()\";+\-*^]
- STRING ({STRINGFIRST})({STRINGCHAR})*
- /*
- IDFIRST [A-Za-z_\$]
- ID ({IDFIRST})({IDFIRST}|[0-9])*
- */
- EOLCH [\r\n]
- EOL ("\r\n"|"\r"|"\n")
- WS [ \t]
- SIGN ("-")*
-
- %%
-
-
- {SIGN}"0x"{HEXDIG}+ {
- int sign = *yytext == '-';
- #ifdef DEBUG
- logger(_L | LOG_USER, "a hex number: %s\n", yytext);
- #endif
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = strtol(yytext+2+sign, NULL, 16);
- if (sign) yylval.expr.u.num = -yylval.expr.u.num;
- return NUM;
- }
-
- {SIGN}"$"{HEXDIG}+ {
- int sign = *yytext == '-';
- #ifdef DEBUG
- logger(_L | LOG_USER, "a hex number: %s\n", yytext);
- #endif
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = strtol(yytext+1, NULL, 16);
- if (sign) yylval.expr.u.num = -yylval.expr.u.num;
- return NUM;
- }
-
- {SIGN}"0"{OCTDIG}+ {
- #ifdef DEBUG
- logger(_L | LOG_USER, "an oct number: %s\n", yytext);
- #endif
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = strtol(yytext, NULL, 8);
- return NUM;
- }
-
- {SIGN}{DIGIT}+ {
- #ifdef DEBUG
- logger(_L | LOG_USER, "a decimal number: %s\n", yytext);
- #endif
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = strtol(yytext, NULL, 10);
- return NUM;
- }
-
- /* boolean values */
- [tT][rR][uU][eE]|[oO][nN]|[yY][eE][sS] {
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = 1;
- return NUM;
- }
- [fF][aA][lL][sS][eE]|[oO][fF][fF]|[nN][oO] {
- yylval.expr.type = ca_NUM;
- yylval.expr.u.num = 0;
- return NUM;
- }
-
- ">>" return RSHIFT;
- "<<" return LSHIFT;
- ">=" return COMPGE;
- "<=" return COMPLE;
- "==" return COMPEQ;
- "!="|"<>" return COMPNE;
- "&&"|"AND" return COMPAND;
- "||"|"OR" return COMPOR;
- "^^"|"XOR" return COMPXOR;
- "and" return '&';
- "or" return '|';
- "xor" return '^';
-
- "print" return PRINT;
-
- /* identifiers for modules.inf */
-
- "MINIMEM" yylval.expr.type = ca_NUM; yylval.expr.u.num = MOD_PART_MINIMEM; return NUM;
- "BANKED" yylval.expr.type = ca_NUM; yylval.expr.u.num = MOD_PART_BANKED; return NUM;
- "GROM" yylval.expr.type = ca_NUM; yylval.expr.u.num = MOD_PART_GROM; return NUM;
- "ROM" yylval.expr.type = ca_NUM; yylval.expr.u.num = MOD_PART_ROM; return NUM;
- "GRAMKRACKER" yylval.expr.type = ca_NUM; yylval.expr.u.num = MOD_PART_GRAMKRACKER; return NUM;
-
- /* identifiers for fileformat */
-
- "F_V9T9"|"F_V9t9" yylval.expr.type = ca_NUM; yylval.expr.u.num = F_V9t9; return NUM;
- "F_TIFILES" yylval.expr.type = ca_NUM; yylval.expr.u.num = F_TIFILES; return NUM;
-
-
- {EOL} {
- #ifdef DEBUG
- logger(_L | LOG_USER, "line ending\n");
- #endif
- cf->line++;
- return '\n';
- }
-
-
- "#" BEGIN(preproc);
-
- <preproc>"include"{WS}+"\""([^\r\n]+)"\""{WS}* {
- lexer_include(yytext);
- BEGIN(INITIAL);
- }
-
- <preproc>"include"{WS}.* {
- lexer_error("incorrectly formed #include statement");
- }
-
- <preproc>{EOL} { BEGIN(INITIAL); cf->line++; }
-
- <preproc>. /* ignore rest of comment */
-
- "//"[^\r\n]*{EOL} cf->line++;
-
- {WS} /* ignore whitespace */
-
- /* comment rules stolen from flex manual */
-
- "/*" BEGIN(comment);
-
- <comment>[^*\r\n]*
- <comment>[^*\r\n]*{EOL} cf->line++;
- <comment>"*"+[^*/\r\n]*
- <comment>"*"+[^*/\r\n]*{EOL} cf->line++;
- <comment>"*"+"/" BEGIN(INITIAL);
-
- /* grouper */
-
- "[" BEGIN(grouper);
-
- <grouper>[^]\r\n]*
- <grouper>[^]\r\n]*{EOL} cf->line++;
- <grouper>"]" BEGIN(INITIAL);
-
- <<EOF>> { if (!lexer_pop_context()) yyterminate(); }
-
- /* explicit string constant */
- "\"" {
- #ifdef DEBUG
- logger(_L | LOG_USER, "a string: ");
- #endif
- BEGIN(string);
- TEST_MEMERR(OS_NewHandle(0, &lexer_string));
- }
-
- <string>"\\\"" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\"", 1));
-
- <string>"\\t" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\t", 1));
- <string>"\\b" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\b", 1));
- <string>"\\r" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\r", 1));
- <string>"\\n" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\n", 1));
- <string>"\\\\" TEST_MEMERR(OS_AppendHandle(&lexer_string, "\\", 1));
-
- <string>"\"" {
- TEST_MEMERR(OS_AppendHandle(&lexer_string, "", 1));
- yylval.expr.u.str = strdup(OS_LockHandle(&lexer_string));
- OS_UnlockHandle(&lexer_string);
- OS_FreeHandle(&lexer_string);
- #ifdef DEBUG
- logger(_L | LOG_USER, "%s\n", yylval.expr.u.str);
- #endif
- BEGIN(INITIAL);
- return STRING;
- }
-
- <string>{EOL}
- <string><<EOF>> {
- TEST_MEMERR(OS_AppendHandle(&lexer_string, "", 1));
- yylval.expr.u.str = xstrdup(OS_LockHandle(&lexer_string));
- OS_UnlockHandle(&lexer_string);
- OS_FreeHandle(&lexer_string);
- lexer_error("Unterminated string (%s)\n", yylval.expr.u.str);
- BEGIN(INITIAL);
- return STRING;
- }
- <string>. TEST_MEMERR(OS_AppendHandle(&lexer_string, yytext, strlen(yytext)));
-
- /* implicit string constant */
-
- {STRING} {
- /*
- char *str;
- command_symbol *sym;
- #ifdef DEBUG
- logger(_L | LOG_USER, "an unquoted string: '%s'", yytext);
- #endif
-
- if (command_match_symbol(command_scope, yytext, &sym))
- {
- yylval.expr.type = ca_SYM;
- yylval.expr.u.str = xstrdup(yytext);
- #ifdef DEBUG
- logger(_L | L_0, "got an ID (%s)\n", yytext);
- #endif
- return IDSTRING;
- }
- else
- */
- {
- yylval.expr.type = ca_STRING;
- yylval.expr.u.str = xstrdup(yytext);
- return IDSTRING;
- }
- }
-
- . {
- //yylval.expr.type = ca_STRING;
- //yylval.expr.u.str = xstrdup(yytext);
- //return STRING;
- return *yytext;
- }
-
- %%
-
- static int
- command_context_new_text(command_context **context,
- const command_context *outer,
- const char *name, const char *data, int len)
- {
- my_assert(data != NULL);
-
- *context = (command_context *)xmalloc(sizeof(command_context));
-
- (*context)->outer = outer;
-
- if (name) (*context)->name = xstrdup(name);
- else (*context)->name = xstrdup("(unnamed)");
-
- if (!(*context) || !(*context)->name ||
- OS_NewHandle(len, &(*context)->hand) != OS_NOERR)
- return 0;
-
- (*context)->len = len;
- memcpy(OS_LockHandle(&(*context)->hand), data, len);
- OS_UnlockHandle(&(*context)->hand);
-
- (*context)->offs = 0;
- (*context)->line = 1;
-
-
- return 1;
- }
-
- static int
- command_context_new_file(command_context **context,
- const command_context *outer,
- const char *filename)
- {
- OSFileHandle fhand;
- OSError err;
- OSSpec spec;
-
- my_assert(filename != NULL);
-
- *context = (command_context *)xmalloc(sizeof(command_context));
- if (!*context) return 0;
-
- (*context)->outer = outer;
-
- (*context)->name = (char *)xstrdup(filename);
- if (!(*context)->name) return 0;
-
- if ((err = OS_MakeFileSpec(filename, &spec)) != OS_NOERR ||
- (err = OS_NewFileHandle(&spec, NULL, false, &fhand)) != OS_NOERR ||
- (err = OS_CopyHandle(&fhand.hand, &(*context)->hand)) != OS_NOERR ||
- (err = OS_FreeFileHandle(&fhand)) != OS_NOERR)
- {
- logger(LOG_COMMANDS|LOG_ERROR|LOG_USER, "Couldn't get/copy file text from '%s':\n%s\n", filename, OS_GetErrText(err));
- return 0;
- }
-
- OS_GetHandleSize(&(*context)->hand, &(*context)->len);
-
- (*context)->offs = 0;
- (*context)->line = 1;
-
- return 1;
- }
-
- static void
- command_context_free(command_context **context)
- {
- if (context == NULL || *context == NULL)
- return;
-
- if ((*context)->name) xfree((*context)->name);
- OS_FreeHandle(&(*context)->hand);
- xfree(*context);
-
- *context = NULL;
- }
-
-
- /* Routine to read text from our command buffer instead of stdin */
- static int command_context_getstring(command_context *context,
- char *buf, int maxsize)
- {
- void *ptr;
- OSSize cpy;
- // my_assert(context != NULL);
-
- if (context == NULL)
- return 0;
-
- ptr = OS_LockHandle(&context->hand);
-
- cpy = ((context->len - context->offs) < maxsize) ?
- (context->len - context->offs) :
- maxsize;
- memcpy(buf, ((char *)ptr) + context->offs, cpy);
- context->offs += cpy;
-
- OS_UnlockHandle(&context->hand);
-
- return cpy;
- }
-
- /******************************/
-
- command_context *lexer_push_text(const char *name, const char *data, int len)
- {
- command_context *cc;
- #ifdef DEBUG
- logger(_L | LOG_USER, "lexer: reading from text '%s'\n", name);
- #endif
- if (!command_context_new_text(&cc, cf, name, data, len))
- return NULL;
-
- if (cf)
- {
- cf->yybuf = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_create_buffer(NULL, cc->len));
- }
-
- cf = cc;
- return cf;
- }
-
- command_context *lexer_push_file(const char *filename)
- {
- command_context *cc;
- #ifdef DEBUG
- logger(_L | LOG_USER, "lexer: reading from file '%s'\n", filename);
- #endif
- if (!command_context_new_file(&cc, cf, filename))
- return NULL;
-
- if (cf)
- {
- cf->yybuf = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_create_buffer(NULL, cc->len));
- }
-
- cf = cc;
- return cf;
- }
-
- command_context *lexer_pop_context(void)
- {
- if (cf != NULL)
- {
- command_context *outer = (command_context *)cf->outer;
- command_context_free(&cf);
-
- if (outer)
- {
- yy_delete_buffer(YY_CURRENT_BUFFER);
- yy_switch_to_buffer(outer->yybuf);
- }
-
- cf = outer;
- #ifdef DEBUG
- logger(_L | LOG_USER, "lexer: popping context to '%s'\n", cf ? cf->name : "<null>");
- #endif
- return cf;
- }
-
- #ifdef DEBUG
- logger(LOG_FATAL,"popped null lexer context\n");
- #endif
- return NULL;
- }
-
- void lexer_error(const char *comm, ...)
- {
- va_list va;
- static char buf[256], *bptr;
- va_start(va, comm);
- bptr = mvprintf(buf, sizeof(buf), comm, va);
- logger(LOG_USER|LOG_ERROR, "%s:%d: %s\n", cf ? cf->name : "<unnamed>",
- cf ? cf->line : 0, bptr);
- if (bptr != buf) free(bptr);
- }
-
- void lexer_include(char *yy)
- {
- char extract[256];
-
- char *st = strchr(yy, '\"')+1;
- char *en = strchr(st, '\"');
- if (en-st > 256) en = st+256;
- memcpy(extract, st, en-st);
- extract[en-st] = 0;
-
- lexer_push_file(extract);
- }
-
- int yywrap(void)
- {
- return 1;
- }
-