1 /*-----------------------------------------------------------------------
2 SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
3 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 int lineno, column;
49 extern char *filename;
51 /* global definitions */
55 /* local definitions */
56 static struct dbuf_s asmbuff;
58 /* forward declarations */
59 static char *stringLiteral(void);
60 static void count(void);
61 static int process_pragma(const char *);
62 static int check_type(void);
63 static int isTargetKeyword(const char *s);
64 static int checkCurrFile(const char *s);
71 if (!options.std_sdcc && yytext[1] != '_')
73 assert(asmbuff.alloc == 0 && asmbuff.len == 0 && asmbuff.buf == NULL);
74 dbuf_init(&asmbuff, INITIAL_INLINEASM);
79 if (!options.std_sdcc && yytext[1] != '_')
81 dbuf_append_str(&asmbuff, yytext);
85 yylval.yyinline = dbuf_c_str(&asmbuff);
86 dbuf_detach(&asmbuff);
93 dbuf_append_char(&asmbuff, *yytext);
96 dbuf_append_char(&asmbuff, *yytext);
98 "at" { count(); TKEYWORDSDCC(AT); }
99 "__at" { count(); TKEYWORD(AT); }
100 "auto" { count(); return(AUTO); }
101 "bit" { count(); TKEYWORDSDCC(BIT); }
102 "__bit" { count(); TKEYWORD(BIT); }
103 "break" { count(); return(BREAK); }
104 "case" { count(); return(CASE); }
105 "char" { count(); return(CHAR); }
106 "code" { count(); TKEYWORDSDCC(CODE); }
107 "__code" { count(); TKEYWORD(CODE); }
108 "const" { count(); return(CONST); }
109 "continue" { count(); return(CONTINUE); }
110 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
111 "__critical" { count(); TKEYWORD(CRITICAL); }
112 "data" { count(); TKEYWORDSDCC(DATA); }
113 "__data" { count(); TKEYWORD(DATA); }
114 "default" { count(); return(DEFAULT); }
115 "do" { count(); return(DO); }
116 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
117 "else" { count(); return(ELSE); }
118 "enum" { count(); return(ENUM); }
119 "extern" { count(); return(EXTERN); }
120 "far" { count(); TKEYWORDSDCC(XDATA); }
121 "__far" { count(); TKEYWORD(XDATA); }
122 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
123 "__eeprom" { count(); TKEYWORD(EEPROM); }
124 "float" { count(); return(FLOAT); }
125 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
126 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
127 "flash" { count(); TKEYWORDSDCC(CODE); }
128 "__flash" { count(); TKEYWORD(CODE); }
129 "for" { count(); return(FOR); }
130 "goto" { count(); return(GOTO); }
131 "idata" { count(); TKEYWORDSDCC(IDATA); }
132 "__idata" { count(); TKEYWORD(IDATA); }
133 "if" { count(); return(IF); }
134 "int" { count(); return(INT); }
135 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
136 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
137 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
138 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
139 "banked" { count(); TKEYWORDSDCC(BANKED); }
140 "__banked" { count(); TKEYWORD(BANKED); }
141 "long" { count(); return(LONG); }
142 "near" { count(); TKEYWORDSDCC(DATA); }
143 "__near" { count(); TKEYWORD(DATA); }
144 "pdata" { count(); TKEYWORDSDCC(PDATA); }
145 "__pdata" { count(); TKEYWORD(PDATA); }
146 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
147 "__reentrant" { count(); TKEYWORD(REENTRANT); }
148 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
149 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
150 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
151 "__wparam" { count(); TKEYWORD(WPARAM); }
152 "register" { count(); return(REGISTER); }
153 "return" { count(); return(RETURN); }
154 "sfr" { count(); TKEYWORDSDCC(SFR); }
155 "__sfr" { count(); TKEYWORD(SFR); }
156 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
157 "__sfr16" { count(); TKEYWORD(SFR16); }
158 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
159 "__sfr32" { count(); TKEYWORD(SFR32); }
160 "sbit" { count(); TKEYWORDSDCC(SBIT); }
161 "__sbit" { count(); TKEYWORD(SBIT); }
162 "short" { count(); return(SHORT); }
163 "signed" { count(); return(SIGNED); }
164 "sizeof" { count(); return(SIZEOF); }
165 "sram" { count(); TKEYWORDSDCC(XDATA); }
166 "__sram" { count(); TKEYWORD(XDATA); }
167 "static" { count(); return(STATIC); }
168 "struct" { count(); return(STRUCT); }
169 "switch" { count(); return(SWITCH); }
170 "typedef" { count(); return(TYPEDEF); }
171 "union" { count(); return(UNION); }
172 "unsigned" { count(); return(UNSIGNED); }
173 "void" { count(); return(VOID); }
174 "volatile" { count(); return(VOLATILE); }
175 "using" { count(); TKEYWORDSDCC(USING); }
176 "__using" { count(); TKEYWORD(USING); }
177 "_naked" { count(); TKEYWORDSDCC(NAKED); }
178 "__naked" { count(); TKEYWORD(NAKED); }
179 "while" { count(); return(WHILE); }
180 "xdata" { count(); TKEYWORDSDCC(XDATA); }
181 "__xdata" { count(); TKEYWORD(XDATA); }
182 "..." { count(); return(VAR_ARGS); }
183 "__typeof" { count(); return TYPEOF; }
184 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
185 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
186 "__overlay" { count(); TKEYWORD(OVERLAY); }
187 "inline" { count(); TKEYWORD99(INLINE); }
188 "restrict" { count(); TKEYWORD99(RESTRICT); }
189 {L}({L}|{D})* { count(); return(check_type()); }
190 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
191 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
192 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
193 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
194 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
195 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
196 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
197 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
198 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
199 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
200 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
201 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
202 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
203 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
204 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
205 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
206 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
207 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
208 ">>" { count(); return(RIGHT_OP); }
209 "<<" { count(); return(LEFT_OP); }
210 "++" { count(); return(INC_OP); }
211 "--" { count(); return(DEC_OP); }
212 "->" { count(); return(PTR_OP); }
213 "&&" { count(); return(AND_OP); }
214 "||" { count(); return(OR_OP); }
215 "<=" { count(); return(LE_OP); }
216 ">=" { count(); return(GE_OP); }
217 "==" { count(); return(EQ_OP); }
218 "!=" { count(); return(NE_OP); }
219 ";" { count(); return(';'); }
220 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
221 "}" { count(); NestLevel--; return('}'); }
222 "," { count(); return(','); }
223 ":" { count(); return(':'); }
224 "=" { count(); return('='); }
225 "(" { count(); ignoreTypedefType = 0; return('('); }
226 ")" { count(); return(')'); }
227 "[" { count(); return('['); }
228 "]" { count(); return(']'); }
229 "." { count(); return('.'); }
230 "&" { count(); return('&'); }
231 "!" { count(); return('!'); }
232 "~" { count(); return('~'); }
233 "-" { count(); return('-'); }
234 "+" { count(); return('+'); }
235 "*" { count(); return('*'); }
236 "/" { count(); return('/'); }
237 "%" { count(); return('%'); }
238 "<" { count(); return('<'); }
239 ">" { count(); return('>'); }
240 "^" { count(); return('^'); }
241 "|" { count(); return('|'); }
242 "?" { count(); return('?'); }
243 ^#pragma.*$ { count(); process_pragma(yytext); }
244 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
246 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
247 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
250 [ \t\v\f] { count(); }
254 /* that could have been removed by the preprocessor anyway */
255 werror (W_STRAY_BACKSLASH, column);
262 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
264 #define yytext_ptr yytext
268 static int checkCurrFile (const char *s)
273 /* skip '#' character */
277 /* check if this is a #line
278 this is not standard and can be removed in the future */
279 #define LINE_STR "line"
280 #define LINE_LEN ((sizeof LINE_STR) - 1)
282 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
285 /* get the line number */
286 lNum = strtol(s, &tptr, 10);
287 if (tptr == s || !isspace((unsigned char)*tptr))
291 /* now see if we have a file name */
292 while (*s != '"' && *s)
295 /* if we don't have a filename then */
296 /* set the current line number to */
297 /* line number if printFlag is on */
299 lineno = mylineno = lNum;
303 /* if we have a filename then check */
304 /* if it is "standard in" if yes then */
305 /* get the currentfile name info */
308 /* in c1mode fullSrcFileName is NULL */
309 if (fullSrcFileName &&
310 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0) {
311 lineno = mylineno = lNum;
312 currFname = fullSrcFileName;
317 /* find the end of the filename */
318 while (*s && *s != '"')
320 currFname = Safe_malloc(s - sb + 1);
321 memcpy(currFname, sb, s - sb);
322 currFname[s - sb] = '\0';
323 lineno = mylineno = lNum;
325 filename = currFname ;
332 static void count(void)
335 for (i = 0; yytext[i] != '\0'; i++) {
336 if (yytext[i] == '\n') {
341 if (yytext[i] == '\t')
342 column += 8 - (column % 8);
349 static int check_type(void)
351 symbol *sym = findSym(SymbolTab, NULL, yytext);
353 /* check if it is in the table as a typedef */
354 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
355 && SPEC_TYPEDEF (sym->etype)) {
356 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
360 strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX);
366 * Change by JTV 2001-05-19 to not concantenate strings
367 * to support ANSI hex and octal escape sequences in string literals
370 static char *stringLiteral(void)
372 #define STR_BUF_CHUNCK_LEN 1024
374 static struct dbuf_s dbuf;
378 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
380 dbuf_set_length(&dbuf, 0);
382 dbuf_append_char(&dbuf, '"');
383 /* put into the buffer till we hit the first \" */
385 while ((ch = input()) != 0) {
388 /* if it is a \ then escape char's are allowed */
391 /* \<newline> is a continuator */
398 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
400 break; /* carry on */
403 /* if new line we have a new line break, which is illegal */
404 werror(W_NEWLINE_IN_STRING);
405 dbuf_append_char(&dbuf, '\n');
411 /* if this is a quote then we have work to do */
412 /* find the next non whitespace character */
413 /* if that is a double quote then carry on */
414 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
415 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#')) {
418 if ((ch = input()) != '\n') {
419 werror(W_STRAY_BACKSLASH, column);
435 /* # at the beginning of the line: collect the entire line */
436 struct dbuf_s linebuf;
439 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
440 dbuf_append_char(&linebuf, '#');
442 while ((ch = input()) && ch != '\n') {
443 dbuf_append_char(&linebuf, (char)ch);
451 line = dbuf_c_str(&linebuf);
453 /* process the line */
454 if (startsWith(line, "#pragma"))
455 process_pragma(line);
459 dbuf_destroy(&linebuf);
474 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
479 return (char *)dbuf_c_str(&dbuf);
498 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
499 /* cross-compiling for MINGW32 with gcc 3.2 */
513 /* SAVE/RESTORE stack */
514 #define SAVE_RESTORE_SIZE 128
516 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
517 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
518 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
521 * cloneXxx functions should be updated every time a new set is
522 * added to the options or optimize structure!
525 static struct options *cloneOptions(struct options *opt)
527 struct options *new_opt;
529 new_opt = Safe_malloc(sizeof (struct options));
531 /* clone scalar values */
535 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
536 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
537 /* not implemented yet: */
538 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
543 static struct optimize *cloneOptimize(struct optimize *opt)
545 struct optimize *new_opt;
547 new_opt = Safe_malloc(sizeof (struct optimize));
549 /* clone scalar values */
555 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
557 struct SDCCERRG *new_val;
559 new_val = Safe_malloc(sizeof (struct SDCCERRG));
561 /* clone scalar values */
567 static void copyAndFreeOptions(struct options *dest, struct options *src)
569 /* delete dest sets */
570 deleteSet(&dest->calleeSavesSet);
571 deleteSet(&dest->excludeRegsSet);
572 /* not implemented yet: */
573 /* deleteSet(&dest->olaysSet); */
575 /* copy src to dest */
581 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
583 /* copy src to dest */
589 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
591 /* copy src to dest */
598 * returns 1 if the pragma was processed, 0 if not
600 static int doPragma(int id, const char *name, const char *cp)
602 struct pragma_token_s token;
606 init_pragma_token(&token);
612 cp = get_pragma_token(cp, &token);
613 if (TOKEN_EOL != token.type)
619 STACK_PUSH(options_stack, cloneOptions(&options));
620 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
621 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
627 struct options *optionsp;
628 struct optimize *optimizep;
629 struct SDCCERRG *sdccerrgp;
631 cp = get_pragma_token(cp, &token);
632 if (TOKEN_EOL != token.type)
638 optionsp = STACK_POP(options_stack);
639 copyAndFreeOptions(&options, optionsp);
641 optimizep = STACK_POP(optimize_stack);
642 copyAndFreeOptimize(&optimize, optimizep);
644 sdccerrgp = STACK_POP(SDCCERRG_stack);
645 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
650 cp = get_pragma_token(cp, &token);
651 if (TOKEN_EOL != token.type)
657 optimize.loopInduction = 0;
661 cp = get_pragma_token(cp, &token);
662 if (TOKEN_EOL != token.type)
668 optimize.loopInvariant = 0;
672 cp = get_pragma_token(cp, &token);
673 if (TOKEN_EOL != token.type)
679 optimize.loopInduction = 1;
683 cp = get_pragma_token(cp, &token);
684 if (TOKEN_EOL != token.type)
690 options.stackAuto = 1;
694 cp = get_pragma_token(cp, &token);
695 if (TOKEN_EOL != token.type)
701 optimize.noJTabBoundary = 1;
705 cp = get_pragma_token(cp, &token);
706 if (TOKEN_EOL != token.type)
712 optimize.global_cse = 0;
716 cp = get_pragma_token(cp, &token);
717 if (TOKEN_EOL != token.type)
723 options.noOverlay = 1;
727 cp = get_pragma_token(cp, &token);
728 if (TOKEN_EOL != token.type)
734 options.lessPedantic = 1;
735 setErrorLogLevel(ERROR_LEVEL_WARNING);
739 /* append to the functions already listed
741 setParseWithComma(&options.calleeSavesSet, cp);
747 deleteSet(&options.excludeRegsSet);
748 setParseWithComma(&options.excludeRegsSet, cp);
754 cp = get_pragma_token(cp, &token);
755 if (TOKEN_EOL != token.type)
765 cp = get_pragma_token(cp, &token);
766 if (TOKEN_EOL != token.type)
772 optimize.noLoopReverse = 1;
776 cp = get_pragma_token(cp, &token);
777 if (TOKEN_EOL != token.type)
789 cp = get_pragma_token(cp, &token);
790 if (TOKEN_INT != token.type)
795 warn = token.val.int_val;
797 cp = get_pragma_token(cp, &token);
798 if (TOKEN_EOL != token.type)
804 if (warn < MAX_ERROR_WARNING)
805 setWarningDisabled(warn);
810 cp = get_pragma_token(cp, &token);
811 if (TOKEN_EOL != token.type)
817 optimize.codeSpeed = 1;
818 optimize.codeSize = 0;
822 cp = get_pragma_token(cp, &token);
823 if (TOKEN_EOL != token.type)
829 optimize.codeSpeed = 0;
830 optimize.codeSize = 1;
833 case P_OPTCODEBALANCED:
834 cp = get_pragma_token(cp, &token);
835 if (TOKEN_EOL != token.type)
841 optimize.codeSpeed = 0;
842 optimize.codeSize = 0;
846 cp = get_pragma_token(cp, &token);
847 if (TOKEN_EOL != token.type)
854 options.std_sdcc = 0;
858 cp = get_pragma_token(cp, &token);
859 if (TOKEN_EOL != token.type)
866 options.std_sdcc = 0;
870 cp = get_pragma_token(cp, &token);
871 if (TOKEN_EOL != token.type)
878 options.std_sdcc = 1;
882 cp = get_pragma_token(cp, &token);
883 if (TOKEN_EOL != token.type)
890 options.std_sdcc = 1;
897 cp = get_pragma_token(cp, &token);
898 if (token.type == TOKEN_EOL)
903 segname = get_pragma_string(&token);
905 cp = get_pragma_token(cp, &token);
906 if (token.type != TOKEN_EOL)
912 if (strlen(segname) > 8)
919 dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
920 options.code_seg = Safe_strdup(get_pragma_string(&token));
929 cp = get_pragma_token(cp, &token);
930 if (token.type == TOKEN_EOL)
935 segname = get_pragma_string(&token);
937 cp = get_pragma_token(cp, &token);
938 if (token.type != TOKEN_EOL)
944 if (strlen(segname) > 8)
951 dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
952 options.code_seg = Safe_strdup(get_pragma_string(&token));
962 get_pragma_token(cp, &token);
964 if (1 == err || (0 == err && token.type != TOKEN_EOL))
965 werror(W_BAD_PRAGMA_ARGUMENTS, name);
967 free_pragma_token(&token);
971 static struct pragma_s pragma_tbl[] = {
972 { "save", P_SAVE, 0, doPragma },
973 { "restore", P_RESTORE, 0, doPragma },
974 { "noinduction", P_NOINDUCTION, 0, doPragma },
975 { "noinvariant", P_NOINVARIANT, 0, doPragma },
976 { "noloopreverse", P_LOOPREV, 0, doPragma },
977 { "induction", P_INDUCTION, 0, doPragma },
978 { "stackauto", P_STACKAUTO, 0, doPragma },
979 { "nojtbound", P_NOJTBOUND, 0, doPragma },
980 { "nogcse", P_NOGCSE, 0, doPragma },
981 { "nooverlay", P_NOOVERLAY, 0, doPragma },
982 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
983 { "exclude", P_EXCLUDE, 0, doPragma },
984 { "noiv", P_NOIV, 0, doPragma },
985 { "overlay", P_OVERLAY_, 0, doPragma },
986 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
987 { "disable_warning",P_DISABLEWARN, 0, doPragma },
988 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
989 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
990 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
991 { "std_c89", P_STD_C89, 0, doPragma },
992 { "std_c99", P_STD_C99, 0, doPragma },
993 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
994 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
995 { "codeseg", P_CODESEG, 0, doPragma },
996 { "constseg", P_CONSTSEG, 0, doPragma },
997 { NULL, 0, 0, NULL },
1001 * returns 1 if the pragma was processed, 0 if not
1004 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1006 struct pragma_token_s token;
1010 init_pragma_token(&token);
1012 s = get_pragma_token(s, &token);
1014 /* skip separating whitespace */
1015 while ('\n' != *s && isspace((unsigned char)*s))
1018 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1020 /* now compare and do what needs to be done */
1021 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1023 if (pragma_tbl[i].deprecated != 0)
1024 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1026 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1031 free_pragma_token(&token);
1035 static int process_pragma(const char *s)
1037 struct pragma_token_s token;
1039 init_pragma_token(&token);
1041 s = get_pragma_token(s, &token);
1042 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1044 /* Oops, womething went totally wrong - internal error */
1045 wassertl(0, "pragma parser internal error");
1049 while ('\n' != *s && isspace((unsigned char)*s))
1052 /* First give the port a chance */
1053 if (port->process_pragma && port->process_pragma(s))
1056 if (process_pragma_tbl(pragma_tbl, s))
1062 werror(W_UNKNOWN_PRAGMA, s);
1067 /* will return 1 if the string is a part
1068 of a target specific keyword */
1069 static int isTargetKeyword(const char *s)
1073 if (port->keywords == NULL)
1076 if (s[0] == '_' && s[1] == '_')
1078 /* Keywords in the port's array have either 0 or 1 underscore, */
1079 /* so skip over the appropriate number of chars when comparing */
1080 for (i = 0 ; port->keywords[i] ; i++ )
1082 if (port->keywords[i][0] == '_' &&
1083 strcmp(port->keywords[i],s+1) == 0)
1085 else if (strcmp(port->keywords[i],s+2) == 0)
1091 for (i = 0 ; port->keywords[i] ; i++ )
1093 if (strcmp(port->keywords[i],s) == 0)
1103 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1104 werror(W_SAVE_RESTORE);
1109 int yyerror(char *s)
1113 if(options.vc_err_style)
1114 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1115 filename, mylineno, s, yytext, column);
1117 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1118 filename, mylineno, s ,yytext, column);