/*-----------------------------------------------------------------------
- SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
- 8/16 bit microcontrollers)
+ SDCC.lex - lexical analyser for use with sdcc (free open source
+ compiler for 8/16 bit microcontrollers)
Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
-%option noyywrap
+D [0-9]
+L [a-zA-Z_$]
+H [a-fA-F0-9]
+E [Ee][+-]?{D}+
+FS (f|F|l|L)
+IS (u|U|l|L)*
-D [0-9]
-L [a-zA-Z_]
-H [a-fA-F0-9]
-E [Ee][+-]?{D}+
-FS (f|F|l|L)
-IS (u|U|l|L)*
%{
-
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "common.h"
#include "newalloc.h"
-#include "dbuf.h"
+#include "dbuf_string.h"
-char *stringLiteral();
-char *currFname;
+#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
+ check_type())
-extern int lineno, column;
-extern char *filename ;
-int mylineno = 1 ;
-void count() ;
-int process_pragma(char *);
-#undef yywrap
+#define TKEYWORDSDCC(token) return (options.std_sdcc && isTargetKeyword(yytext)\
+ ? token : check_type())
-#ifndef YYPROTO
+#define TKEYWORD99(token) return (options.std_c99 ? token : check_type())
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
+extern char *filename;
+extern int lineno;
+int column = 0; /* current column */
-#endif
+/* global definitions */
+char *lexFilename;
+int lexLineno = 1;
-int yywrap YY_PROTO((void))
-{
- return(1);
-}
+/* local definitions */
+static struct dbuf_s asmbuff; /* reusable _asm buffer */
-static void yyunput (int, char *);
-
-static void my_unput(char c)
-{
- yyunput(c, (yytext_ptr));
-}
-
-#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
- check_type(yytext))
-char *asmbuff=NULL;
-int asmbuffSize=0;
-char *asmp ;
-extern int check_type ();
- extern int isTargetKeyword ();
-extern int checkCurrFile (char *);
-extern int processPragma (char *);
-extern int printListing (int );
-struct optimize save_optimize ;
-struct options save_options ;
+/* forward declarations */
+int yyerror(char *s);
+static const char *stringLiteral(void);
+static void count(void);
+static void count_char(int);
+static int process_pragma(const char *);
+static int check_type(void);
+static int isTargetKeyword(const char *s);
+static int checkCurrFile(const char *s);
%}
%x asm
%%
-"_asm" {
- count();
- asmp = asmbuff = realloc (asmbuff, INITIAL_INLINEASM);
- asmbuffSize=INITIAL_INLINEASM;
- BEGIN(asm) ;
+_?"_asm" {
+ count();
+ if (!options.std_sdcc && yytext[1] != '_')
+ return check_type();
+ if (asmbuff.buf == NULL)
+ dbuf_init(&asmbuff, INITIAL_INLINEASM);
+ else
+ dbuf_set_length(&asmbuff, 0);
+
+ BEGIN(asm);
}
-<asm>"_endasm" {
+<asm>_?"_endasm" {
count();
- *asmp = '\0';
- yylval.yyinline = strdup (asmbuff);
- BEGIN(INITIAL);
- return (INLINEASM);
+ if (!options.std_sdcc && yytext[1] != '_')
+ {
+ dbuf_append_str(&asmbuff, yytext);
+ }
+ else
+ {
+ yylval.yyinline = dbuf_c_str(&asmbuff);
+ BEGIN(INITIAL);
+ return (INLINEASM);
+ }
}
-<asm>. {
- if (asmp-asmbuff >= asmbuffSize-2) {
- // increase the buffersize with 50%
- int size=asmp-asmbuff;
- asmbuffSize=asmbuffSize*3/2;
- asmbuff = realloc (asmbuff, asmbuffSize);
- asmp=asmbuff+size;
- }
- *asmp++ = yytext[0];
+<asm>\n {
+ count();
+ dbuf_append_char(&asmbuff, *yytext);
}
-<asm>\n {
- count();
- if (asmp-asmbuff >= asmbuffSize-3) {
- // increase the buffersize with 50%
- int size=asmp-asmbuff;
- asmbuffSize=asmbuffSize*3/2;
- asmbuff = realloc (asmbuff, asmbuffSize);
- asmp=asmbuff+size;
- }
- *asmp++ = '\n' ;
+<asm>. {
+ dbuf_append_char(&asmbuff, *yytext);
}
-"at" { count(); TKEYWORD(AT) ; }
-"auto" { count(); return(AUTO); }
-"bit" { count(); TKEYWORD(BIT) ; }
+"at" { count(); TKEYWORDSDCC(AT); }
+"__at" { count(); TKEYWORD(AT); }
+"auto" { count(); return(AUTO); }
+"bit" { count(); TKEYWORDSDCC(BIT); }
+"__bit" { count(); TKEYWORD(BIT); }
"break" { count(); return(BREAK); }
"case" { count(); return(CASE); }
"char" { count(); return(CHAR); }
-"code" { count(); TKEYWORD(CODE); }
+"code" { count(); TKEYWORDSDCC(CODE); }
+"__code" { count(); TKEYWORD(CODE); }
"const" { count(); return(CONST); }
"continue" { count(); return(CONTINUE); }
-"critical" { count(); TKEYWORD(CRITICAL); }
-"data" { count(); TKEYWORD(DATA); }
+"critical" { count(); TKEYWORDSDCC(CRITICAL); }
+"__critical" { count(); TKEYWORD(CRITICAL); }
+"data" { count(); TKEYWORDSDCC(DATA); }
+"__data" { count(); TKEYWORD(DATA); }
"default" { count(); return(DEFAULT); }
"do" { count(); return(DO); }
"double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
"else" { count(); return(ELSE); }
"enum" { count(); return(ENUM); }
"extern" { count(); return(EXTERN); }
-"far" { count(); TKEYWORD(XDATA); }
-"eeprom" { count(); TKEYWORD(EEPROM); }
+"far" { count(); TKEYWORDSDCC(XDATA); }
+"__far" { count(); TKEYWORD(XDATA); }
+"eeprom" { count(); TKEYWORDSDCC(EEPROM); }
+"__eeprom" { count(); TKEYWORD(EEPROM); }
"float" { count(); return(FLOAT); }
-"flash" { count(); TKEYWORD(CODE);}
+"fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
+"__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
+"flash" { count(); TKEYWORDSDCC(CODE); }
+"__flash" { count(); TKEYWORD(CODE); }
"for" { count(); return(FOR); }
-"goto" { count(); return(GOTO); }
-"idata" { count(); TKEYWORD(IDATA);}
+"goto" { count(); return(GOTO); }
+"idata" { count(); TKEYWORDSDCC(IDATA); }
+"__idata" { count(); TKEYWORD(IDATA); }
"if" { count(); return(IF); }
"int" { count(); return(INT); }
-"interrupt" { count(); return(INTERRUPT);}
-"nonbanked" { count(); TKEYWORD(NONBANKED);}
-"banked" { count(); TKEYWORD(BANKED);}
-"long" { count(); return(LONG); }
-"near" { count(); TKEYWORD(DATA);}
-"pdata" { count(); TKEYWORD(PDATA); }
-"reentrant" { count(); TKEYWORD(REENTRANT);}
+"interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
+"__interrupt" { count(); TKEYWORD(INTERRUPT); }
+"nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
+"__nonbanked" { count(); TKEYWORD(NONBANKED); }
+"banked" { count(); TKEYWORDSDCC(BANKED); }
+"__banked" { count(); TKEYWORD(BANKED); }
+"long" { count(); return(LONG); }
+"near" { count(); TKEYWORDSDCC(DATA); }
+"__near" { count(); TKEYWORD(DATA); }
+"pdata" { count(); TKEYWORDSDCC(PDATA); }
+"__pdata" { count(); TKEYWORD(PDATA); }
+"reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
+"__reentrant" { count(); TKEYWORD(REENTRANT); }
+"shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
+"__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
+"wparam" { count(); TKEYWORDSDCC(WPARAM); }
+"__wparam" { count(); TKEYWORD(WPARAM); }
"register" { count(); return(REGISTER); }
"return" { count(); return(RETURN); }
-"sfr" { count(); TKEYWORD(SFR) ; }
-"sbit" { count(); TKEYWORD(SBIT) ; }
+"sfr" { count(); TKEYWORDSDCC(SFR); }
+"__sfr" { count(); TKEYWORD(SFR); }
+"sfr16" { count(); TKEYWORDSDCC(SFR16); }
+"__sfr16" { count(); TKEYWORD(SFR16); }
+"sfr32" { count(); TKEYWORDSDCC(SFR32); }
+"__sfr32" { count(); TKEYWORD(SFR32); }
+"sbit" { count(); TKEYWORDSDCC(SBIT); }
+"__sbit" { count(); TKEYWORD(SBIT); }
"short" { count(); return(SHORT); }
"signed" { count(); return(SIGNED); }
"sizeof" { count(); return(SIZEOF); }
-"sram" { count(); TKEYWORD(XDATA);}
+"sram" { count(); TKEYWORDSDCC(XDATA); }
+"__sram" { count(); TKEYWORD(XDATA); }
"static" { count(); return(STATIC); }
"struct" { count(); return(STRUCT); }
"switch" { count(); return(SWITCH); }
"unsigned" { count(); return(UNSIGNED); }
"void" { count(); return(VOID); }
"volatile" { count(); return(VOLATILE); }
-"using" { count(); TKEYWORD(USING); }
-"_naked" { count(); TKEYWORD(NAKED); }
+"using" { count(); TKEYWORDSDCC(USING); }
+"__using" { count(); TKEYWORD(USING); }
+"_naked" { count(); TKEYWORDSDCC(NAKED); }
+"__naked" { count(); TKEYWORD(NAKED); }
"while" { count(); return(WHILE); }
-"xdata" { count(); TKEYWORD(XDATA); }
-"..." { count(); return(VAR_ARGS);}
-"__typeof" { count(); return TYPEOF;}
-"_JavaNative" { count(); TKEYWORD(JAVANATIVE);}
-"_overlay" { count(); TKEYWORD(OVERLAY);}
-{L}({L}|{D})* { count(); return(check_type()); }
+"xdata" { count(); TKEYWORDSDCC(XDATA); }
+"__xdata" { count(); TKEYWORD(XDATA); }
+"..." { count(); return(VAR_ARGS); }
+"__typeof" { count(); return TYPEOF; }
+"_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
+"_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
+"__overlay" { count(); TKEYWORD(OVERLAY); }
+"inline" { count(); TKEYWORD99(INLINE); }
+"restrict" { count(); TKEYWORD99(RESTRICT); }
+{L}({L}|{D})* {
+ if (!options.dollars_in_ident && strchr(yytext, '$'))
+ {
+ yyerror("stray '$' in program");
+ }
+ count();
+ return(check_type());
+}
0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
-0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
-{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
-'(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */}
+0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
+[1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
+'(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
{D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
{D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
-{D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
-\" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
-">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
-"<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
-"+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
-"-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
-"*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
-"/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
-"%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
-"&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
-"^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
-"|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
+{D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
+\" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
+">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
+"<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
+"+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
+"-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
+"*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
+"/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
+"%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
+"&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
+"^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
+"|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
">>" { count(); return(RIGHT_OP); }
"<<" { count(); return(LEFT_OP); }
"++" { count(); return(INC_OP); }
"==" { count(); return(EQ_OP); }
"!=" { count(); return(NE_OP); }
";" { count(); return(';'); }
-"{" { count(); NestLevel++ ; return('{'); }
-"}" { count(); NestLevel--; return('}'); }
+"{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
+"}" { count(); NestLevel--; return('}'); }
"," { count(); return(','); }
":" { count(); return(':'); }
"=" { count(); return('='); }
-"(" { count(); return('('); }
+"(" { count(); ignoreTypedefType = 0; return('('); }
")" { count(); return(')'); }
"[" { count(); return('['); }
"]" { count(); return(']'); }
"^" { count(); return('^'); }
"|" { count(); return('|'); }
"?" { count(); return('?'); }
-^#line.*"\n" { count(); checkCurrFile(yytext); }
-^#pragma.*"\n" { count(); process_pragma(yytext); }
+^#pragma.*$ { count(); process_pragma(yytext); }
+^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
-^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
-^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
-"\r\n" { count(); }
-"\n" { count(); }
+^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
+^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
+"\r\n" { count(); }
+"\n" { count(); }
[ \t\v\f] { count(); }
\\ {
- char ch=input();
- if (ch!='\n') {
- // that could have been removed by the preprocessor anyway
- werror (W_STRAY_BACKSLASH, column);
- my_unput(ch);
- }
+ int ch = input();
+
+ if (ch == '\n')
+ count_char(ch);
+ else
+ {
+ /* that could have been removed by the preprocessor anyway */
+ werror (W_STRAY_BACKSLASH, column);
+ unput(ch);
+ }
}
-. { count() ; }
+. { count(); }
%%
-int checkCurrFile ( char *s)
+/* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
+#ifndef yytext_ptr
+#define yytext_ptr yytext
+#endif
+
+
+static int checkCurrFile (const char *s)
{
- char lineNum[10] ;
- int lNum ;
- char *tptr ;
-
- /* first check if this is a #line */
- if ( strncmp(s,"#line",5) )
- return 0 ;
-
- /* get to the line number */
- while (!isdigit(*s))
- s++ ;
- tptr = lineNum ;
- while (isdigit(*s))
- *tptr++ = *s++ ;
- *tptr = '\0';
- sscanf(lineNum,"%d",&lNum);
-
- /* now see if we have a file name */
- while (*s != '\"' && *s)
- s++ ;
-
- /* if we don't have a filename then */
- /* set the current line number to */
- /* line number if printFlag is on */
- if (!*s) {
- lineno = mylineno = lNum ;
+ int lNum;
+ char *tptr;
+
+ /* skip '#' character */
+ if (*s++ != '#')
+ return 0;
+
+ /* check if this is a #line
+ this is not standard and can be removed in the future */
+#define LINE_STR "line"
+#define LINE_LEN ((sizeof LINE_STR) - 1)
+
+ if (strncmp(s, LINE_STR, LINE_LEN) == 0)
+ s += LINE_LEN;
+
+ /* get the line number */
+ lNum = strtol(s, &tptr, 10);
+ if (tptr == s || !isspace((unsigned char)*tptr))
+ return 0;
+ s = tptr;
+
+ /* adjust the line number */
+ lineno = lexLineno = lNum;
+
+ /* now see if we have a file name */
+ while (*s != '"' && *s)
+ ++s;
+
+ if (!*s)
+ {
+ /* no file name: return */
return 0;
}
-
- /* if we have a filename then check */
- /* if it is "standard in" if yes then */
- /* get the currentfile name info */
- s++ ;
-
- /* in c1mode fullSrcFileName is NULL */
- if ( fullSrcFileName &&
- strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
- lineno = mylineno = lNum;
- currFname = fullSrcFileName ;
- } else {
- char *sb = s;
- /* mark the end of the filename */
- while (*s != '"') s++;
- *s = '\0';
- currFname = strdup (sb);
- lineno = mylineno = lNum;
+
+ /* skip the double quote */
+ ++s;
+
+ /* get the file name and see if it is different from current one.
+ in c1mode fullSrcFileName is NULL */
+ if (fullSrcFileName &&
+ strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
+ {
+ lexFilename = fullSrcFileName;
}
- filename = currFname ;
- return 0;
+ else
+ {
+ const char *sb = s;
+ char *tmpFname;
+
+ /* find the end of the file name */
+ while (*s && *s != '"')
+ ++s;
+
+ tmpFname = Safe_malloc(s - sb + 1);
+ memcpy(tmpFname, sb, s - sb);
+ tmpFname[s - sb] = '\0';
+
+ lexFilename = Safe_malloc(s - sb + 1);
+ copyStr(lexFilename, tmpFname);
+ }
+ filename = lexFilename;
+
+ return 0;
}
-
-int column = 0;
-int plineIdx=0;
-void count()
+static void count_char(int ch)
{
- int i;
- for (i = 0; yytext[i] != '\0'; i++) {
- if (yytext[i] == '\n') {
+ switch (ch)
+ {
+ case '\n':
column = 0;
- lineno = ++mylineno ;
+ lineno = ++lexLineno;
+ break;
+
+ case '\t':
+ column += 8 - (column % 8);
+ break;
+
+ default:
+ ++column;
+ break;
}
- else
- if (yytext[i] == '\t')
- column += 8 - (column % 8);
- else
- column++;
- }
- /* ECHO; */
}
-int check_type()
+static void count(void)
{
- /* check if it is in the typedef table */
- if (findSym(TypedefTab,NULL,yytext)) {
- strncpyz(yylval.yychar,yytext, SDCC_NAME_MAX);
- return (TYPE_NAME) ;
- }
- else {
- strncpyz (yylval.yychar,yytext, SDCC_NAME_MAX);
- return(IDENTIFIER);
- }
+ const char *p;
+
+ for (p = yytext; *p; ++p)
+ count_char(*p);
+}
+
+static int check_type(void)
+{
+ symbol *sym = findSym(SymbolTab, NULL, yytext);
+
+ strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
+
+ /* check if it is in the table as a typedef */
+ if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
+ && SPEC_TYPEDEF (sym->etype))
+ return (TYPE_NAME);
+ else
+ return(IDENTIFIER);
}
/*
* Change by JTV 2001-05-19 to not concantenate strings
- * to support ANSI hex and octal escape sequences in string liteals
+ * to support ANSI hex and octal escape sequences in string literals
*/
-char *stringLiteral()
+static const char *stringLiteral(void)
{
#define STR_BUF_CHUNCK_LEN 1024
int ch;
- static struct dbuf_s dbuf;
- char buf[2];
+ static struct dbuf_s dbuf; /* reusable string literal buffer */
if (dbuf.alloc == 0)
dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
else
- dbuf_set_size(&dbuf, 0);
+ dbuf_set_length(&dbuf, 0);
+ dbuf_append_char(&dbuf, '"');
- dbuf_append(&dbuf, "\"", 1);
/* put into the buffer till we hit the first \" */
- while ((ch = input()) != 0) {
- switch (ch) {
- case '\\':
- /* if it is a \ then escape char's are allowed */
+ for (; ; )
+ {
ch = input();
- if (ch == '\n') {
- /* \<newline> is a continuator */
- lineno = ++mylineno;
- column = 0;
- }
- else {
- buf[0] = '\\';
- buf[1] = ch;
- dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
- }
- break; /* carry on */
-
- case '\n':
- /* if new line we have a new line break, which is illegal */
- werror(W_NEWLINE_IN_STRING);
- dbuf_append(&dbuf, "\n", 1);
- lineno = ++mylineno;
- column = 0;
- break;
+ count_char(ch);
+ if (ch == EOF)
+ break;
- case '"':
- /* if this is a quote then we have work to do */
- /* find the next non whitespace character */
- /* if that is a double quote then carry on */
- dbuf_append(&dbuf, "\"", 1); /* Pass end of this string or substring to evaluator */
- while ((ch = input()) && (isspace(ch) || ch=='\\')) {
- switch (ch) {
+ switch (ch)
+ {
case '\\':
- if ((ch = input()) != '\n') {
- werror(W_STRAY_BACKSLASH, column);
- my_unput(ch);
- }
- else {
- lineno = ++mylineno;
- column = 0;
- }
- break;
+ /* if it is a \ then escape char's are allowed */
+ ch = input();
+ count_char(ch);
+ if (ch == '\n')
+ {
+ /* \<newline> is a continuator */
+ }
+ else
+ {
+ char buf[2];
+
+ if (ch == EOF)
+ goto out;
+
+ buf[0] = '\\';
+ buf[1] = ch;
+ dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
+ }
+ break; /* carry on */
case '\n':
- mylineno++;
+ /* if new line we have a new line break, which is illegal */
+ werror(W_NEWLINE_IN_STRING);
+ dbuf_append_char(&dbuf, '\n');
break;
- }
- }
-
- if (!ch)
- goto out;
- if (ch != '\"') {
- my_unput(ch) ;
- goto out;
- }
- break;
+ case '"':
+ /* if this is a quote then we have work to do */
+ /* find the next non whitespace character */
+ /* if that is a double quote then carry on */
+ dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
+ while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
+ {
+ switch (ch)
+ {
+ case '\\':
+ count_char(ch);
+ if ((ch = input()) != '\n')
+ {
+ werror(W_STRAY_BACKSLASH, column);
+ if (ch != EOF)
+ unput(ch);
+ else
+ count_char(ch);
+ }
+ else
+ count_char(ch);
+ break;
+
+ case '\n':
+ count_char(ch);
+ break;
+
+ case '#':
+ if (column == 0)
+ {
+ /* # at the beginning of the line: collect the entire line */
+ struct dbuf_s linebuf;
+ const char *line;
+
+ count_char(ch);
+
+ dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
+ dbuf_append_char(&linebuf, '#');
+
+ while ((ch = input()) != EOF && ch != '\n')
+ dbuf_append_char(&linebuf, (char)ch);
+
+ if (ch == '\n')
+ count_char(ch);
+
+ line = dbuf_c_str(&linebuf);
+
+ /* process the line */
+ if (startsWith(line, "#pragma"))
+ process_pragma(line);
+ else
+ checkCurrFile(line);
+
+ dbuf_destroy(&linebuf);
+ }
+ else
+ {
+ unput(ch);
+ goto out;
+ }
+
+ default:
+ count_char(ch);
+ break;
+ }
+ }
+
+ if (ch == EOF)
+ goto out;
+
+ if (ch != '"')
+ {
+ unput(ch);
+ goto out;
+ }
+ count_char(ch);
+ break;
- default:
- buf[0] = ch;
- dbuf_append(&dbuf, buf, 1); /* Put next substring introducer into output string */
+ default:
+ dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
+ }
}
- }
out:
- return (char *)dbuf_c_str(&dbuf);
+ return dbuf_c_str(&dbuf);
}
-enum pragma_id {
- P_SAVE = 1,
- P_RESTORE ,
- P_NOINDUCTION,
- P_NOINVARIANT,
- P_INDUCTION ,
- P_STACKAUTO ,
- P_NOJTBOUND ,
- P_NOOVERLAY ,
- P_LESSPEDANTIC,
- P_NOGCSE ,
- P_CALLEE_SAVES,
- P_EXCLUDE ,
- P_NOIV ,
- P_LOOPREV ,
- P_OVERLAY_ /* I had a strange conflict with P_OVERLAY while */
- /* cross-compiling for MINGW32 with gcc 3.2 */
+enum {
+ P_SAVE = 1,
+ P_RESTORE,
+ P_NOINDUCTION,
+ P_NOINVARIANT,
+ P_INDUCTION,
+ P_STACKAUTO,
+ P_NOJTBOUND,
+ P_NOOVERLAY,
+ P_LESSPEDANTIC,
+ P_NOGCSE,
+ P_CALLEE_SAVES,
+ P_EXCLUDE,
+ P_NOIV,
+ P_LOOPREV,
+ P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
+ /* cross-compiling for MINGW32 with gcc 3.2 */
+ P_DISABLEWARN,
+ P_OPTCODESPEED,
+ P_OPTCODESIZE,
+ P_OPTCODEBALANCED,
+ P_STD_C89,
+ P_STD_C99,
+ P_STD_SDCC89,
+ P_STD_SDCC99,
+ P_CODESEG,
+ P_CONSTSEG
};
STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
+STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
+/*
+ * cloneXxx functions should be updated every time a new set is
+ * added to the options or optimize structure!
+ */
-void doPragma (int op, char *cp)
+static struct options *cloneOptions(struct options *opt)
{
- switch (op) {
- case P_SAVE:
- {
- struct options *optionsp;
- struct optimize *optimizep;
+ struct options *new_opt;
- optionsp = Safe_malloc(sizeof (struct options));
- *optionsp = options;
- STACK_PUSH(options_stack, optionsp);
+ new_opt = Safe_malloc(sizeof (struct options));
- optimizep = Safe_malloc(sizeof (struct optimize));
- *optimizep = optimize;
- STACK_PUSH(optimize_stack, optimizep);
- }
- break;
+ /* clone scalar values */
+ *new_opt = *opt;
- case P_RESTORE:
- {
- struct options *optionsp;
- struct optimize *optimizep;
+ /* clone sets */
+ new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
+ new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
+ /* not implemented yet: */
+ /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
- optionsp = STACK_POP(options_stack);
- options = *optionsp;
- Safe_free(optionsp);
+ return new_opt;
+}
- optimizep = STACK_POP(optimize_stack);
- optimize = *optimizep;
- Safe_free(optimizep);
- }
- break;
+static struct optimize *cloneOptimize(struct optimize *opt)
+{
+ struct optimize *new_opt;
+
+ new_opt = Safe_malloc(sizeof (struct optimize));
+
+ /* clone scalar values */
+ *new_opt = *opt;
+
+ return new_opt;
+}
- case P_NOINDUCTION:
- optimize.loopInduction = 0 ;
- break;
+static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
+{
+ struct SDCCERRG *new_val;
- case P_NOINVARIANT:
- optimize.loopInvariant = 0 ;
- break;
+ new_val = Safe_malloc(sizeof (struct SDCCERRG));
- case P_INDUCTION:
- optimize.loopInduction = 1 ;
- break;
+ /* clone scalar values */
+ *new_val = *val;
- case P_STACKAUTO:
- options.stackAuto = 1;
- break;
+ return new_val;
+}
- case P_NOJTBOUND:
- optimize.noJTabBoundary = 1;
- break;
+static void copyAndFreeOptions(struct options *dest, struct options *src)
+{
+ /* delete dest sets */
+ deleteSet(&dest->calleeSavesSet);
+ deleteSet(&dest->excludeRegsSet);
+ /* not implemented yet: */
+ /* deleteSet(&dest->olaysSet); */
- case P_NOGCSE:
- optimize.global_cse = 0;
- break;
+ /* copy src to dest */
+ *dest = *src;
- case P_NOOVERLAY:
- options.noOverlay = 1;
- break;
+ Safe_free(src);
+}
- case P_LESSPEDANTIC:
- options.lessPedantic = 1;
- break;
+static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
+{
+ /* copy src to dest */
+ *dest = *src;
+
+ Safe_free(src);
+}
- case P_CALLEE_SAVES:
+static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
+{
+ /* copy src to dest */
+ *dest = *src;
+
+ Safe_free(src);
+}
+
+/*
+ * returns 1 if the pragma was processed, 0 if not
+ */
+static int doPragma(int id, const char *name, const char *cp)
+{
+ struct pragma_token_s token;
+ int err = 0;
+ int processed = 1;
+
+ init_pragma_token(&token);
+
+ switch (id)
{
- int i=0;
+ case P_SAVE:
+ {
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ STACK_PUSH(options_stack, cloneOptions(&options));
+ STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
+ STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
+ }
+ break;
+
+ case P_RESTORE:
+ {
+ struct options *optionsp;
+ struct optimize *optimizep;
+ struct SDCCERRG *sdccerrgp;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optionsp = STACK_POP(options_stack);
+ copyAndFreeOptions(&options, optionsp);
+
+ optimizep = STACK_POP(optimize_stack);
+ copyAndFreeOptimize(&optimize, optimizep);
+
+ sdccerrgp = STACK_POP(SDCCERRG_stack);
+ copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
+ }
+ break;
+
+ case P_NOINDUCTION:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.loopInduction = 0;
+ break;
+
+ case P_NOINVARIANT:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.loopInvariant = 0;
+ break;
+
+ case P_INDUCTION:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.loopInduction = 1;
+ break;
+
+ case P_STACKAUTO:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.stackAuto = 1;
+ break;
+
+ case P_NOJTBOUND:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.noJTabBoundary = 1;
+ break;
+
+ case P_NOGCSE:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.global_cse = 0;
+ break;
+
+ case P_NOOVERLAY:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.noOverlay = 1;
+ break;
+
+ case P_LESSPEDANTIC:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.lessPedantic = 1;
+ setErrorLogLevel(ERROR_LEVEL_WARNING);
+ break;
+
+ case P_CALLEE_SAVES:
/* append to the functions already listed
in callee-saves */
- for (; options.calleeSaves[i] ;i++);
- parseWithComma(&options.calleeSaves[i], Safe_strdup(cp));
- }
- break;
+ setParseWithComma(&options.calleeSavesSet, cp);
+ err = -1;
+ break;
+
+ case P_EXCLUDE:
+ {
+ deleteSet(&options.excludeRegsSet);
+ setParseWithComma(&options.excludeRegsSet, cp);
+ err = -1;
+ }
+ break;
+
+ case P_NOIV:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.noiv = 1;
+ break;
+
+ case P_LOOPREV:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_EXCLUDE:
- parseWithComma(options.excludeRegs, Safe_strdup(cp));
- break;
+ optimize.noLoopReverse = 1;
+ break;
+
+ case P_OVERLAY_:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ break; /* notyet */
- case P_NOIV:
- options.noiv = 1;
- break;
+ case P_DISABLEWARN:
+ {
+ int warn;
- case P_LOOPREV:
- optimize.noLoopReverse = 1;
- break;
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ err = 1;
+ break;
+ }
+ warn = token.val.int_val;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ if (warn < MAX_ERROR_WARNING)
+ setWarningDisabled(warn);
+ }
+ break;
+
+ case P_OPTCODESPEED:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.codeSpeed = 1;
+ optimize.codeSize = 0;
+ break;
+
+ case P_OPTCODESIZE:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_OVERLAY_:
- break; /* notyet */
- }
+ optimize.codeSpeed = 0;
+ optimize.codeSize = 1;
+ break;
+
+ case P_OPTCODEBALANCED:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.codeSpeed = 0;
+ optimize.codeSize = 0;
+ break;
+
+ case P_STD_C89:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 0;
+ options.std_sdcc = 0;
+ break;
+
+ case P_STD_C99:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 1;
+ options.std_sdcc = 0;
+ break;
+
+ case P_STD_SDCC89:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 0;
+ options.std_sdcc = 1;
+ break;
+
+ case P_STD_SDCC99:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 1;
+ options.std_sdcc = 1;
+ break;
+
+ case P_CODESEG:
+ case P_CONSTSEG:
+ {
+ struct dbuf_s segname;
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type == TOKEN_EOL)
+ {
+ err = 1;
+ break;
+ }
+
+ dbuf_init(&segname, 16);
+ dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type != TOKEN_EOL)
+ {
+ dbuf_destroy(&segname);
+ err = 1;
+ break;
+ }
+
+ if (id == P_CODESEG)
+ options.code_seg = dbuf_detach(&segname);
+ else
+ options.const_seg = dbuf_detach(&segname);
+ }
+ break;
+
+ default:
+ processed = 0;
+ break;
+ }
+
+ get_pragma_token(cp, &token);
+
+ if (1 == err || (0 == err && token.type != TOKEN_EOL))
+ werror(W_BAD_PRAGMA_ARGUMENTS, name);
+
+ free_pragma_token(&token);
+ return processed;
}
-int process_pragma(char *s)
+static struct pragma_s pragma_tbl[] = {
+ { "save", P_SAVE, 0, doPragma },
+ { "restore", P_RESTORE, 0, doPragma },
+ { "noinduction", P_NOINDUCTION, 0, doPragma },
+ { "noinvariant", P_NOINVARIANT, 0, doPragma },
+ { "noloopreverse", P_LOOPREV, 0, doPragma },
+ { "induction", P_INDUCTION, 0, doPragma },
+ { "stackauto", P_STACKAUTO, 0, doPragma },
+ { "nojtbound", P_NOJTBOUND, 0, doPragma },
+ { "nogcse", P_NOGCSE, 0, doPragma },
+ { "nooverlay", P_NOOVERLAY, 0, doPragma },
+ { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
+ { "exclude", P_EXCLUDE, 0, doPragma },
+ { "noiv", P_NOIV, 0, doPragma },
+ { "overlay", P_OVERLAY_, 0, doPragma },
+ { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
+ { "disable_warning",P_DISABLEWARN, 0, doPragma },
+ { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
+ { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
+ { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
+ { "std_c89", P_STD_C89, 0, doPragma },
+ { "std_c99", P_STD_C99, 0, doPragma },
+ { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
+ { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
+ { "codeseg", P_CODESEG, 0, doPragma },
+ { "constseg", P_CONSTSEG, 0, doPragma },
+ { NULL, 0, 0, NULL },
+};
+
+/*
+ * returns 1 if the pragma was processed, 0 if not
+ */
+int
+process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
{
-#define NELEM(x) (sizeof (x) / sizeof (x)[0])
-#define PRAGMA "#pragma"
-
- static struct pragma_s {
- const char *name;
- enum pragma_id id;
- } pragma_tbl[] = {
- { "SAVE", P_SAVE },
- { "RESTORE", P_RESTORE },
- { "NOINDUCTION", P_NOINDUCTION },
- { "NOINVARIANT", P_NOINVARIANT },
- { "NOLOOPREVERSE", P_LOOPREV },
- { "INDUCTION", P_INDUCTION },
- { "STACKAUTO", P_STACKAUTO },
- { "NOJTBOUND", P_NOJTBOUND },
- { "NOGCSE", P_NOGCSE },
- { "NOOVERLAY", P_NOOVERLAY },
- { "CALLEE-SAVES", P_CALLEE_SAVES },
- { "EXCLUDE", P_EXCLUDE },
- { "NOIV", P_NOIV },
- { "OVERLAY", P_OVERLAY_ },
- { "LESS_PEDANTIC", P_LESSPEDANTIC },
- };
- char *cp ;
+ struct pragma_token_s token;
int i;
+ int ret = 0;
- /* find the pragma */
- while (strncmp(s, PRAGMA, (sizeof PRAGMA) - 1))
- s++;
- s += (sizeof PRAGMA) - 1;
-
- /* look for the directive */
- while(isspace(*s))
+ init_pragma_token(&token);
+
+ s = get_pragma_token(s, &token);
+
+ /* skip separating whitespace */
+ while ('\n' != *s && isspace((unsigned char)*s))
s++;
- cp = s;
- /* look for the end of the directive */
- while ((!isspace(*s)) && (*s != '\n'))
- s++ ;
+ for (i = 0; NULL != pragma_tbl[i].name; ++i)
+ {
+ /* now compare and do what needs to be done */
+ if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
+ {
+ if (pragma_tbl[i].deprecated != 0)
+ werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
- /* First give the port a chance */
- if (port->process_pragma && !port->process_pragma(cp))
- return 0;
+ ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
+ break;
+ }
+ }
- for (i = 0; i < NELEM(pragma_tbl); i++) {
- /* now compare and do what needs to be done */
- size_t len = strlen(pragma_tbl[i].name);
+ free_pragma_token(&token);
+ return ret;
+}
- if (strncmp(cp, pragma_tbl[i].name, len) == 0) {
- doPragma(pragma_tbl[i].id, cp + len);
- return 0;
+static int process_pragma(const char *s)
+{
+ struct pragma_token_s token;
+
+ init_pragma_token(&token);
+
+ s = get_pragma_token(s, &token);
+ if (0 != strcmp("#pragma", get_pragma_string(&token)))
+ {
+ /* Oops, womething went totally wrong - internal error */
+ wassertl(0, "pragma parser internal error");
}
- }
- werror(W_UNKNOWN_PRAGMA,cp);
- return 0;
+ /* skip spaces */
+ while ('\n' != *s && isspace((unsigned char)*s))
+ ++s;
+
+ /* First give the port a chance */
+ if (port->process_pragma && port->process_pragma(s))
+ return 1;
+
+ if (process_pragma_tbl(pragma_tbl, s))
+ {
+ return 1;
+ }
+ else
+ {
+ werror(W_UNKNOWN_PRAGMA, s);
+ return 0;
+ }
}
/* will return 1 if the string is a part
of a target specific keyword */
-int isTargetKeyword(char *s)
+static int isTargetKeyword(const char *s)
{
- int i;
-
- if (port->keywords == NULL)
- return 0;
- for ( i = 0 ; port->keywords[i] ; i++ ) {
- if (strcmp(port->keywords[i],s) == 0)
- return 1;
- }
-
+ int i;
+
+ if (port->keywords == NULL)
return 0;
+
+ if (s[0] == '_' && s[1] == '_')
+ {
+ /* Keywords in the port's array have either 0 or 1 underscore, */
+ /* so skip over the appropriate number of chars when comparing */
+ for (i = 0 ; port->keywords[i] ; i++ )
+ {
+ if (port->keywords[i][0] == '_' &&
+ strcmp(port->keywords[i],s+1) == 0)
+ return 1;
+ else if (strcmp(port->keywords[i],s+2) == 0)
+ return 1;
+ }
+ }
+ else
+ {
+ for (i = 0 ; port->keywords[i] ; i++ )
+ {
+ if (strcmp(port->keywords[i],s) == 0)
+ return 1;
+ }
+ }
+
+ return 0;
}
-extern int fatalError;
+int yywrap(void)
+{
+ if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
+ werror(W_SAVE_RESTORE);
+
+ return 1;
+}
int yyerror(char *s)
{
- fflush(stdout);
-
- if (mylineno && filename) {
- if(options.vc_err_style)
- fprintf(stdout,"\n%s(%d) : %s: token -> '%s' ; column %d\n",
- filename,mylineno,
- s,yytext,column);
- else
- fprintf(stdout,"\n%s:%d: %s: token -> '%s' ; column %d\n",
- filename,mylineno,
- s,yytext,column);
- fatalError++;
- } else {
- // this comes from an empy file, no problem
- }
- return 0;
+ fflush(stdout);
+
+ if(options.vc_err_style)
+ fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
+ lexFilename, lexLineno, s, yytext, column);
+ else
+ fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
+ lexFilename, lexLineno, s ,yytext, column);
+ fatalError++;
+
+ return 0;
}