1 /*-----------------------------------------------------------------------
2 SDCC.lex - lexical analyser for use with sdcc (free open source
3 compiler for 8/16 bit microcontrollers)
4 Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 #include "dbuf_string.h"
40 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
43 #define TKEYWORDSDCC(token) return (options.std_sdcc && isTargetKeyword(yytext)\
44 ? token : check_type())
46 #define TKEYWORD99(token) return (options.std_c99 ? token : check_type())
48 extern char *filename;
50 int column = 0; /* current column */
52 /* global definitions */
56 /* local definitions */
57 static struct dbuf_s asmbuff; /* reusable _asm buffer */
59 /* forward declarations */
61 static const char *stringLiteral(void);
62 static void count(void);
63 static void count_char(int);
64 static int process_pragma(const char *);
65 static int check_type(void);
66 static int isTargetKeyword(const char *s);
67 static int checkCurrFile(const char *s);
74 if (!options.std_sdcc && yytext[1] != '_')
76 if (asmbuff.buf == NULL)
77 dbuf_init(&asmbuff, INITIAL_INLINEASM);
79 dbuf_set_length(&asmbuff, 0);
85 if (!options.std_sdcc && yytext[1] != '_')
87 dbuf_append_str(&asmbuff, yytext);
91 yylval.yyinline = dbuf_c_str(&asmbuff);
98 dbuf_append_char(&asmbuff, *yytext);
101 dbuf_append_char(&asmbuff, *yytext);
103 "at" { count(); TKEYWORDSDCC(AT); }
104 "__at" { count(); TKEYWORD(AT); }
105 "auto" { count(); return(AUTO); }
106 "bit" { count(); TKEYWORDSDCC(BIT); }
107 "__bit" { count(); TKEYWORD(BIT); }
108 "break" { count(); return(BREAK); }
109 "case" { count(); return(CASE); }
110 "char" { count(); return(CHAR); }
111 "code" { count(); TKEYWORDSDCC(CODE); }
112 "__code" { count(); TKEYWORD(CODE); }
113 "const" { count(); return(CONST); }
114 "continue" { count(); return(CONTINUE); }
115 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
116 "__critical" { count(); TKEYWORD(CRITICAL); }
117 "data" { count(); TKEYWORDSDCC(DATA); }
118 "__data" { count(); TKEYWORD(DATA); }
119 "default" { count(); return(DEFAULT); }
120 "do" { count(); return(DO); }
121 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
122 "else" { count(); return(ELSE); }
123 "enum" { count(); return(ENUM); }
124 "extern" { count(); return(EXTERN); }
125 "far" { count(); TKEYWORDSDCC(XDATA); }
126 "__far" { count(); TKEYWORD(XDATA); }
127 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
128 "__eeprom" { count(); TKEYWORD(EEPROM); }
129 "float" { count(); return(FLOAT); }
130 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
131 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
132 "flash" { count(); TKEYWORDSDCC(CODE); }
133 "__flash" { count(); TKEYWORD(CODE); }
134 "for" { count(); return(FOR); }
135 "goto" { count(); return(GOTO); }
136 "idata" { count(); TKEYWORDSDCC(IDATA); }
137 "__idata" { count(); TKEYWORD(IDATA); }
138 "if" { count(); return(IF); }
139 "int" { count(); return(INT); }
140 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
141 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
142 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
143 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
144 "banked" { count(); TKEYWORDSDCC(BANKED); }
145 "__banked" { count(); TKEYWORD(BANKED); }
146 "long" { count(); return(LONG); }
147 "near" { count(); TKEYWORDSDCC(DATA); }
148 "__near" { count(); TKEYWORD(DATA); }
149 "pdata" { count(); TKEYWORDSDCC(PDATA); }
150 "__pdata" { count(); TKEYWORD(PDATA); }
151 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
152 "__reentrant" { count(); TKEYWORD(REENTRANT); }
153 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
154 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
155 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
156 "__wparam" { count(); TKEYWORD(WPARAM); }
157 "register" { count(); return(REGISTER); }
158 "return" { count(); return(RETURN); }
159 "sfr" { count(); TKEYWORDSDCC(SFR); }
160 "__sfr" { count(); TKEYWORD(SFR); }
161 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
162 "__sfr16" { count(); TKEYWORD(SFR16); }
163 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
164 "__sfr32" { count(); TKEYWORD(SFR32); }
165 "sbit" { count(); TKEYWORDSDCC(SBIT); }
166 "__sbit" { count(); TKEYWORD(SBIT); }
167 "short" { count(); return(SHORT); }
168 "signed" { count(); return(SIGNED); }
169 "sizeof" { count(); return(SIZEOF); }
170 "sram" { count(); TKEYWORDSDCC(XDATA); }
171 "__sram" { count(); TKEYWORD(XDATA); }
172 "static" { count(); return(STATIC); }
173 "struct" { count(); return(STRUCT); }
174 "switch" { count(); return(SWITCH); }
175 "typedef" { count(); return(TYPEDEF); }
176 "union" { count(); return(UNION); }
177 "unsigned" { count(); return(UNSIGNED); }
178 "void" { count(); return(VOID); }
179 "volatile" { count(); return(VOLATILE); }
180 "using" { count(); TKEYWORDSDCC(USING); }
181 "__using" { count(); TKEYWORD(USING); }
182 "_naked" { count(); TKEYWORDSDCC(NAKED); }
183 "__naked" { count(); TKEYWORD(NAKED); }
184 "while" { count(); return(WHILE); }
185 "xdata" { count(); TKEYWORDSDCC(XDATA); }
186 "__xdata" { count(); TKEYWORD(XDATA); }
187 "..." { count(); return(VAR_ARGS); }
188 "__typeof" { count(); return TYPEOF; }
189 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
190 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
191 "__overlay" { count(); TKEYWORD(OVERLAY); }
192 "inline" { count(); TKEYWORD99(INLINE); }
193 "restrict" { count(); TKEYWORD99(RESTRICT); }
195 if (!options.dollars_in_ident && strchr(yytext, '$'))
197 yyerror("stray '$' in program");
200 return(check_type());
202 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
203 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
204 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
205 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
206 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
207 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
208 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
209 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
210 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
211 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
212 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
213 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
214 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
215 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
216 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
217 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
218 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
219 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
220 ">>" { count(); return(RIGHT_OP); }
221 "<<" { count(); return(LEFT_OP); }
222 "++" { count(); return(INC_OP); }
223 "--" { count(); return(DEC_OP); }
224 "->" { count(); return(PTR_OP); }
225 "&&" { count(); return(AND_OP); }
226 "||" { count(); return(OR_OP); }
227 "<=" { count(); return(LE_OP); }
228 ">=" { count(); return(GE_OP); }
229 "==" { count(); return(EQ_OP); }
230 "!=" { count(); return(NE_OP); }
231 ";" { count(); return(';'); }
232 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
233 "}" { count(); NestLevel--; return('}'); }
234 "," { count(); return(','); }
235 ":" { count(); return(':'); }
236 "=" { count(); return('='); }
237 "(" { count(); ignoreTypedefType = 0; return('('); }
238 ")" { count(); return(')'); }
239 "[" { count(); return('['); }
240 "]" { count(); return(']'); }
241 "." { count(); return('.'); }
242 "&" { count(); return('&'); }
243 "!" { count(); return('!'); }
244 "~" { count(); return('~'); }
245 "-" { count(); return('-'); }
246 "+" { count(); return('+'); }
247 "*" { count(); return('*'); }
248 "/" { count(); return('/'); }
249 "%" { count(); return('%'); }
250 "<" { count(); return('<'); }
251 ">" { count(); return('>'); }
252 "^" { count(); return('^'); }
253 "|" { count(); return('|'); }
254 "?" { count(); return('?'); }
255 ^#pragma.*$ { count(); process_pragma(yytext); }
256 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
258 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
259 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
262 [ \t\v\f] { count(); }
270 /* that could have been removed by the preprocessor anyway */
271 werror (W_STRAY_BACKSLASH, column);
278 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
280 #define yytext_ptr yytext
284 static int checkCurrFile (const char *s)
289 /* skip '#' character */
293 /* check if this is a #line
294 this is not standard and can be removed in the future */
295 #define LINE_STR "line"
296 #define LINE_LEN ((sizeof LINE_STR) - 1)
298 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
301 /* get the line number */
302 lNum = strtol(s, &tptr, 10);
303 if (tptr == s || !isspace((unsigned char)*tptr))
307 /* adjust the line number */
308 lineno = lexLineno = lNum;
310 /* now see if we have a file name */
311 while (*s != '"' && *s)
316 /* no file name: return */
320 /* skip the double quote */
323 /* get the file name and see if it is different from current one.
324 in c1mode fullSrcFileName is NULL */
325 if (fullSrcFileName &&
326 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
328 lexFilename = fullSrcFileName;
335 /* find the end of the file name */
336 while (*s && *s != '"')
339 tmpFname = Safe_malloc(s - sb + 1);
340 memcpy(tmpFname, sb, s - sb);
341 tmpFname[s - sb] = '\0';
343 lexFilename = Safe_malloc(s - sb + 1);
344 copyStr(lexFilename, tmpFname);
346 filename = lexFilename;
351 static void count_char(int ch)
357 lineno = ++lexLineno;
361 column += 8 - (column % 8);
370 static void count(void)
374 for (p = yytext; *p; ++p)
378 static int check_type(void)
380 symbol *sym = findSym(SymbolTab, NULL, yytext);
382 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
384 /* check if it is in the table as a typedef */
385 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
386 && SPEC_TYPEDEF (sym->etype))
393 * Change by JTV 2001-05-19 to not concantenate strings
394 * to support ANSI hex and octal escape sequences in string literals
397 static const char *stringLiteral(void)
399 #define STR_BUF_CHUNCK_LEN 1024
401 static struct dbuf_s dbuf; /* reusable string literal buffer */
404 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
406 dbuf_set_length(&dbuf, 0);
408 dbuf_append_char(&dbuf, '"');
410 /* put into the buffer till we hit the first \" */
422 /* if it is a \ then escape char's are allowed */
427 /* \<newline> is a continuator */
438 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
440 break; /* carry on */
443 /* if new line we have a new line break, which is illegal */
444 werror(W_NEWLINE_IN_STRING);
445 dbuf_append_char(&dbuf, '\n');
449 /* if this is a quote then we have work to do */
450 /* find the next non whitespace character */
451 /* if that is a double quote then carry on */
452 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
453 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
459 if ((ch = input()) != '\n')
461 werror(W_STRAY_BACKSLASH, column);
478 /* # at the beginning of the line: collect the entire line */
479 struct dbuf_s linebuf;
484 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
485 dbuf_append_char(&linebuf, '#');
487 while ((ch = input()) != EOF && ch != '\n')
488 dbuf_append_char(&linebuf, (char)ch);
493 line = dbuf_c_str(&linebuf);
495 /* process the line */
496 if (startsWith(line, "#pragma"))
497 process_pragma(line);
501 dbuf_destroy(&linebuf);
527 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
532 return dbuf_c_str(&dbuf);
551 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
552 /* cross-compiling for MINGW32 with gcc 3.2 */
566 /* SAVE/RESTORE stack */
567 #define SAVE_RESTORE_SIZE 128
569 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
570 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
571 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
574 * cloneXxx functions should be updated every time a new set is
575 * added to the options or optimize structure!
578 static struct options *cloneOptions(struct options *opt)
580 struct options *new_opt;
582 new_opt = Safe_malloc(sizeof (struct options));
584 /* clone scalar values */
588 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
589 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
590 /* not implemented yet: */
591 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
596 static struct optimize *cloneOptimize(struct optimize *opt)
598 struct optimize *new_opt;
600 new_opt = Safe_malloc(sizeof (struct optimize));
602 /* clone scalar values */
608 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
610 struct SDCCERRG *new_val;
612 new_val = Safe_malloc(sizeof (struct SDCCERRG));
614 /* clone scalar values */
620 static void copyAndFreeOptions(struct options *dest, struct options *src)
622 /* delete dest sets */
623 deleteSet(&dest->calleeSavesSet);
624 deleteSet(&dest->excludeRegsSet);
625 /* not implemented yet: */
626 /* deleteSet(&dest->olaysSet); */
628 /* copy src to dest */
634 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
636 /* copy src to dest */
642 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
644 /* copy src to dest */
651 * returns 1 if the pragma was processed, 0 if not
653 static int doPragma(int id, const char *name, const char *cp)
655 struct pragma_token_s token;
659 init_pragma_token(&token);
665 cp = get_pragma_token(cp, &token);
666 if (TOKEN_EOL != token.type)
672 STACK_PUSH(options_stack, cloneOptions(&options));
673 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
674 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
680 struct options *optionsp;
681 struct optimize *optimizep;
682 struct SDCCERRG *sdccerrgp;
684 cp = get_pragma_token(cp, &token);
685 if (TOKEN_EOL != token.type)
691 optionsp = STACK_POP(options_stack);
692 copyAndFreeOptions(&options, optionsp);
694 optimizep = STACK_POP(optimize_stack);
695 copyAndFreeOptimize(&optimize, optimizep);
697 sdccerrgp = STACK_POP(SDCCERRG_stack);
698 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
703 cp = get_pragma_token(cp, &token);
704 if (TOKEN_EOL != token.type)
710 optimize.loopInduction = 0;
714 cp = get_pragma_token(cp, &token);
715 if (TOKEN_EOL != token.type)
721 optimize.loopInvariant = 0;
725 cp = get_pragma_token(cp, &token);
726 if (TOKEN_EOL != token.type)
732 optimize.loopInduction = 1;
736 cp = get_pragma_token(cp, &token);
737 if (TOKEN_EOL != token.type)
743 options.stackAuto = 1;
747 cp = get_pragma_token(cp, &token);
748 if (TOKEN_EOL != token.type)
754 optimize.noJTabBoundary = 1;
758 cp = get_pragma_token(cp, &token);
759 if (TOKEN_EOL != token.type)
765 optimize.global_cse = 0;
769 cp = get_pragma_token(cp, &token);
770 if (TOKEN_EOL != token.type)
776 options.noOverlay = 1;
780 cp = get_pragma_token(cp, &token);
781 if (TOKEN_EOL != token.type)
787 options.lessPedantic = 1;
788 setErrorLogLevel(ERROR_LEVEL_WARNING);
792 /* append to the functions already listed
794 setParseWithComma(&options.calleeSavesSet, cp);
800 deleteSet(&options.excludeRegsSet);
801 setParseWithComma(&options.excludeRegsSet, cp);
807 cp = get_pragma_token(cp, &token);
808 if (TOKEN_EOL != token.type)
818 cp = get_pragma_token(cp, &token);
819 if (TOKEN_EOL != token.type)
825 optimize.noLoopReverse = 1;
829 cp = get_pragma_token(cp, &token);
830 if (TOKEN_EOL != token.type)
842 cp = get_pragma_token(cp, &token);
843 if (TOKEN_INT != token.type)
848 warn = token.val.int_val;
850 cp = get_pragma_token(cp, &token);
851 if (TOKEN_EOL != token.type)
857 if (warn < MAX_ERROR_WARNING)
858 setWarningDisabled(warn);
863 cp = get_pragma_token(cp, &token);
864 if (TOKEN_EOL != token.type)
870 optimize.codeSpeed = 1;
871 optimize.codeSize = 0;
875 cp = get_pragma_token(cp, &token);
876 if (TOKEN_EOL != token.type)
882 optimize.codeSpeed = 0;
883 optimize.codeSize = 1;
886 case P_OPTCODEBALANCED:
887 cp = get_pragma_token(cp, &token);
888 if (TOKEN_EOL != token.type)
894 optimize.codeSpeed = 0;
895 optimize.codeSize = 0;
899 cp = get_pragma_token(cp, &token);
900 if (TOKEN_EOL != token.type)
907 options.std_sdcc = 0;
911 cp = get_pragma_token(cp, &token);
912 if (TOKEN_EOL != token.type)
919 options.std_sdcc = 0;
923 cp = get_pragma_token(cp, &token);
924 if (TOKEN_EOL != token.type)
931 options.std_sdcc = 1;
935 cp = get_pragma_token(cp, &token);
936 if (TOKEN_EOL != token.type)
943 options.std_sdcc = 1;
949 struct dbuf_s segname;
951 cp = get_pragma_token(cp, &token);
952 if (token.type == TOKEN_EOL)
958 dbuf_init(&segname, 16);
959 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
961 cp = get_pragma_token(cp, &token);
962 if (token.type != TOKEN_EOL)
964 dbuf_destroy(&segname);
970 options.code_seg = dbuf_detach(&segname);
972 options.const_seg = dbuf_detach(&segname);
981 get_pragma_token(cp, &token);
983 if (1 == err || (0 == err && token.type != TOKEN_EOL))
984 werror(W_BAD_PRAGMA_ARGUMENTS, name);
986 free_pragma_token(&token);
990 static struct pragma_s pragma_tbl[] = {
991 { "save", P_SAVE, 0, doPragma },
992 { "restore", P_RESTORE, 0, doPragma },
993 { "noinduction", P_NOINDUCTION, 0, doPragma },
994 { "noinvariant", P_NOINVARIANT, 0, doPragma },
995 { "noloopreverse", P_LOOPREV, 0, doPragma },
996 { "induction", P_INDUCTION, 0, doPragma },
997 { "stackauto", P_STACKAUTO, 0, doPragma },
998 { "nojtbound", P_NOJTBOUND, 0, doPragma },
999 { "nogcse", P_NOGCSE, 0, doPragma },
1000 { "nooverlay", P_NOOVERLAY, 0, doPragma },
1001 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
1002 { "exclude", P_EXCLUDE, 0, doPragma },
1003 { "noiv", P_NOIV, 0, doPragma },
1004 { "overlay", P_OVERLAY_, 0, doPragma },
1005 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
1006 { "disable_warning",P_DISABLEWARN, 0, doPragma },
1007 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
1008 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
1009 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1010 { "std_c89", P_STD_C89, 0, doPragma },
1011 { "std_c99", P_STD_C99, 0, doPragma },
1012 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1013 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1014 { "codeseg", P_CODESEG, 0, doPragma },
1015 { "constseg", P_CONSTSEG, 0, doPragma },
1016 { NULL, 0, 0, NULL },
1020 * returns 1 if the pragma was processed, 0 if not
1023 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1025 struct pragma_token_s token;
1029 init_pragma_token(&token);
1031 s = get_pragma_token(s, &token);
1033 /* skip separating whitespace */
1034 while ('\n' != *s && isspace((unsigned char)*s))
1037 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1039 /* now compare and do what needs to be done */
1040 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1042 if (pragma_tbl[i].deprecated != 0)
1043 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1045 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1050 free_pragma_token(&token);
1054 static int process_pragma(const char *s)
1056 struct pragma_token_s token;
1058 init_pragma_token(&token);
1060 s = get_pragma_token(s, &token);
1061 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1063 /* Oops, womething went totally wrong - internal error */
1064 wassertl(0, "pragma parser internal error");
1068 while ('\n' != *s && isspace((unsigned char)*s))
1071 /* First give the port a chance */
1072 if (port->process_pragma && port->process_pragma(s))
1075 if (process_pragma_tbl(pragma_tbl, s))
1081 werror(W_UNKNOWN_PRAGMA, s);
1086 /* will return 1 if the string is a part
1087 of a target specific keyword */
1088 static int isTargetKeyword(const char *s)
1092 if (port->keywords == NULL)
1095 if (s[0] == '_' && s[1] == '_')
1097 /* Keywords in the port's array have either 0 or 1 underscore, */
1098 /* so skip over the appropriate number of chars when comparing */
1099 for (i = 0 ; port->keywords[i] ; i++ )
1101 if (port->keywords[i][0] == '_' &&
1102 strcmp(port->keywords[i],s+1) == 0)
1104 else if (strcmp(port->keywords[i],s+2) == 0)
1110 for (i = 0 ; port->keywords[i] ; i++ )
1112 if (strcmp(port->keywords[i],s) == 0)
1122 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1123 werror(W_SAVE_RESTORE);
1128 int yyerror(char *s)
1132 if(options.vc_err_style)
1133 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1134 lexFilename, lexLineno, s, yytext, column);
1136 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1137 lexFilename, lexLineno, s ,yytext, column);