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 -------------------------------------------------------------------------*/
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(&asmbuff, yytext, strlen(yytext));
85 yylval.yyinline = dbuf_c_str(&asmbuff);
86 dbuf_detach(&asmbuff);
93 dbuf_append(&asmbuff, yytext, 1);
96 dbuf_append(&asmbuff, yytext, 1);
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_size(&dbuf, 0);
382 dbuf_append(&dbuf, "\"", 1);
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(&dbuf, "\n", 1);
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(&dbuf, "\"", 1); /* 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(&linebuf, "#", 1);
442 while ((ch = input()) && ch != '\n') {
444 dbuf_append(&linebuf, buf, 1);
452 line = dbuf_c_str(&linebuf);
454 /* process the line */
455 if (startsWith(line, "#pragma"))
456 process_pragma(line);
460 dbuf_destroy(&linebuf);
476 dbuf_append(&dbuf, buf, 1); /* Put next substring introducer into output string */
481 return (char *)dbuf_c_str(&dbuf);
500 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
501 /* cross-compiling for MINGW32 with gcc 3.2 */
515 /* SAVE/RESTORE stack */
516 #define SAVE_RESTORE_SIZE 128
518 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
519 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
520 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
523 * cloneXxx functions should be updated every time a new set is
524 * added to the options or optimize structure!
527 static struct options *cloneOptions(struct options *opt)
529 struct options *new_opt;
531 new_opt = Safe_malloc(sizeof (struct options));
533 /* clone scalar values */
537 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
538 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
539 /* not implemented yet: */
540 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
545 static struct optimize *cloneOptimize(struct optimize *opt)
547 struct optimize *new_opt;
549 new_opt = Safe_malloc(sizeof (struct optimize));
551 /* clone scalar values */
557 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
559 struct SDCCERRG *new_val;
561 new_val = Safe_malloc(sizeof (struct SDCCERRG));
563 /* clone scalar values */
569 static void copyAndFreeOptions(struct options *dest, struct options *src)
571 /* delete dest sets */
572 deleteSet(&dest->calleeSavesSet);
573 deleteSet(&dest->excludeRegsSet);
574 /* not implemented yet: */
575 /* deleteSet(&dest->olaysSet); */
577 /* copy src to dest */
583 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
585 /* copy src to dest */
591 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
593 /* copy src to dest */
600 * returns 1 if the pragma was processed, 0 if not
602 static int doPragma(int id, const char *name, const char *cp)
604 struct pragma_token_s token;
608 init_pragma_token(&token);
614 cp = get_pragma_token(cp, &token);
615 if (TOKEN_EOL != token.type)
621 STACK_PUSH(options_stack, cloneOptions(&options));
622 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
623 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
629 struct options *optionsp;
630 struct optimize *optimizep;
631 struct SDCCERRG *sdccerrgp;
633 cp = get_pragma_token(cp, &token);
634 if (TOKEN_EOL != token.type)
640 optionsp = STACK_POP(options_stack);
641 copyAndFreeOptions(&options, optionsp);
643 optimizep = STACK_POP(optimize_stack);
644 copyAndFreeOptimize(&optimize, optimizep);
646 sdccerrgp = STACK_POP(SDCCERRG_stack);
647 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
652 cp = get_pragma_token(cp, &token);
653 if (TOKEN_EOL != token.type)
659 optimize.loopInduction = 0;
663 cp = get_pragma_token(cp, &token);
664 if (TOKEN_EOL != token.type)
670 optimize.loopInvariant = 0;
674 cp = get_pragma_token(cp, &token);
675 if (TOKEN_EOL != token.type)
681 optimize.loopInduction = 1;
685 cp = get_pragma_token(cp, &token);
686 if (TOKEN_EOL != token.type)
692 options.stackAuto = 1;
696 cp = get_pragma_token(cp, &token);
697 if (TOKEN_EOL != token.type)
703 optimize.noJTabBoundary = 1;
707 cp = get_pragma_token(cp, &token);
708 if (TOKEN_EOL != token.type)
714 optimize.global_cse = 0;
718 cp = get_pragma_token(cp, &token);
719 if (TOKEN_EOL != token.type)
725 options.noOverlay = 1;
729 cp = get_pragma_token(cp, &token);
730 if (TOKEN_EOL != token.type)
736 options.lessPedantic = 1;
737 setErrorLogLevel(ERROR_LEVEL_WARNING);
741 /* append to the functions already listed
743 setParseWithComma(&options.calleeSavesSet, cp);
749 deleteSet(&options.excludeRegsSet);
750 setParseWithComma(&options.excludeRegsSet, cp);
756 cp = get_pragma_token(cp, &token);
757 if (TOKEN_EOL != token.type)
767 cp = get_pragma_token(cp, &token);
768 if (TOKEN_EOL != token.type)
774 optimize.noLoopReverse = 1;
778 cp = get_pragma_token(cp, &token);
779 if (TOKEN_EOL != token.type)
791 cp = get_pragma_token(cp, &token);
792 if (TOKEN_INT != token.type)
797 warn = token.val.int_val;
799 cp = get_pragma_token(cp, &token);
800 if (TOKEN_EOL != token.type)
806 if (warn < MAX_ERROR_WARNING)
807 setWarningDisabled(warn);
812 cp = get_pragma_token(cp, &token);
813 if (TOKEN_EOL != token.type)
819 optimize.codeSpeed = 1;
820 optimize.codeSize = 0;
824 cp = get_pragma_token(cp, &token);
825 if (TOKEN_EOL != token.type)
831 optimize.codeSpeed = 0;
832 optimize.codeSize = 1;
835 case P_OPTCODEBALANCED:
836 cp = get_pragma_token(cp, &token);
837 if (TOKEN_EOL != token.type)
843 optimize.codeSpeed = 0;
844 optimize.codeSize = 0;
848 cp = get_pragma_token(cp, &token);
849 if (TOKEN_EOL != token.type)
856 options.std_sdcc = 0;
860 cp = get_pragma_token(cp, &token);
861 if (TOKEN_EOL != token.type)
868 options.std_sdcc = 0;
872 cp = get_pragma_token(cp, &token);
873 if (TOKEN_EOL != token.type)
880 options.std_sdcc = 1;
884 cp = get_pragma_token(cp, &token);
885 if (TOKEN_EOL != token.type)
892 options.std_sdcc = 1;
899 cp = get_pragma_token(cp, &token);
900 if (token.type == TOKEN_EOL)
905 segname = get_pragma_string(&token);
907 cp = get_pragma_token(cp, &token);
908 if (token.type != TOKEN_EOL)
914 if (strlen(segname) > 8)
921 dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
922 options.code_seg = Safe_strdup(get_pragma_string(&token));
931 cp = get_pragma_token(cp, &token);
932 if (token.type == TOKEN_EOL)
937 segname = get_pragma_string(&token);
939 cp = get_pragma_token(cp, &token);
940 if (token.type != TOKEN_EOL)
946 if (strlen(segname) > 8)
953 dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
954 options.code_seg = Safe_strdup(get_pragma_string(&token));
964 get_pragma_token(cp, &token);
966 if (1 == err || (0 == err && token.type != TOKEN_EOL))
967 werror(W_BAD_PRAGMA_ARGUMENTS, name);
969 free_pragma_token(&token);
973 static struct pragma_s pragma_tbl[] = {
974 { "save", P_SAVE, 0, doPragma },
975 { "restore", P_RESTORE, 0, doPragma },
976 { "noinduction", P_NOINDUCTION, 0, doPragma },
977 { "noinvariant", P_NOINVARIANT, 0, doPragma },
978 { "noloopreverse", P_LOOPREV, 0, doPragma },
979 { "induction", P_INDUCTION, 0, doPragma },
980 { "stackauto", P_STACKAUTO, 0, doPragma },
981 { "nojtbound", P_NOJTBOUND, 0, doPragma },
982 { "nogcse", P_NOGCSE, 0, doPragma },
983 { "nooverlay", P_NOOVERLAY, 0, doPragma },
984 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
985 { "exclude", P_EXCLUDE, 0, doPragma },
986 { "noiv", P_NOIV, 0, doPragma },
987 { "overlay", P_OVERLAY_, 0, doPragma },
988 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
989 { "disable_warning",P_DISABLEWARN, 0, doPragma },
990 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
991 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
992 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
993 { "std_c89", P_STD_C89, 0, doPragma },
994 { "std_c99", P_STD_C99, 0, doPragma },
995 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
996 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
997 { "codeseg", P_CODESEG, 0, doPragma },
998 { "constseg", P_CONSTSEG, 0, doPragma },
999 { NULL, 0, 0, NULL },
1003 * returns 1 if the pragma was processed, 0 if not
1006 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1008 struct pragma_token_s token;
1012 init_pragma_token(&token);
1014 s = get_pragma_token(s, &token);
1016 /* skip separating whitespace */
1017 while ('\n' != *s && isspace((unsigned char)*s))
1020 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1022 /* now compare and do what needs to be done */
1023 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1025 if (pragma_tbl[i].deprecated != 0)
1026 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1028 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1033 free_pragma_token(&token);
1037 static int process_pragma(const char *s)
1039 struct pragma_token_s token;
1041 init_pragma_token(&token);
1043 s = get_pragma_token(s, &token);
1044 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1046 /* Oops, womething went totally wrong - internal error */
1047 wassertl(0, "pragma parser internal error");
1051 while ('\n' != *s && isspace((unsigned char)*s))
1054 /* First give the port a chance */
1055 if (port->process_pragma && port->process_pragma(s))
1058 if (process_pragma_tbl(pragma_tbl, s))
1064 werror(W_UNKNOWN_PRAGMA, s);
1069 /* will return 1 if the string is a part
1070 of a target specific keyword */
1071 static int isTargetKeyword(const char *s)
1075 if (port->keywords == NULL)
1078 if (s[0] == '_' && s[1] == '_')
1080 /* Keywords in the port's array have either 0 or 1 underscore, */
1081 /* so skip over the appropriate number of chars when comparing */
1082 for (i = 0 ; port->keywords[i] ; i++ )
1084 if (port->keywords[i][0] == '_' &&
1085 strcmp(port->keywords[i],s+1) == 0)
1087 else if (strcmp(port->keywords[i],s+2) == 0)
1093 for (i = 0 ; port->keywords[i] ; i++ )
1095 if (strcmp(port->keywords[i],s) == 0)
1105 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1106 werror(W_SAVE_RESTORE);
1111 int yyerror(char *s)
1115 if(options.vc_err_style)
1116 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1117 filename, mylineno, s, yytext, column);
1119 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1120 filename, mylineno, s ,yytext, column);