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 -------------------------------------------------------------------------*/
39 #include "dbuf_string.h"
41 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
44 #define TKEYWORDSDCC(token) return (options.std_sdcc && isTargetKeyword(yytext)\
45 ? token : check_type())
47 #define TKEYWORD99(token) return (options.std_c99 ? token : check_type())
49 extern char *filename;
51 int column = 0; /* current column */
53 /* global definitions */
57 /* local definitions */
58 static struct dbuf_s asmbuff; /* reusable _asm buffer */
60 /* forward declarations */
62 static const char *stringLiteral(void);
63 static void count(void);
64 static void count_char(int);
65 static int process_pragma(const char *);
66 static int check_type(void);
67 static int isTargetKeyword(const char *s);
68 static int checkCurrFile(const char *s);
75 if (!options.std_sdcc && yytext[1] != '_')
77 if (asmbuff.buf == NULL)
78 dbuf_init(&asmbuff, INITIAL_INLINEASM);
80 dbuf_set_length(&asmbuff, 0);
86 if (!options.std_sdcc && yytext[1] != '_')
88 dbuf_append_str(&asmbuff, yytext);
92 yylval.yyinline = dbuf_c_str(&asmbuff);
99 dbuf_append_char(&asmbuff, *yytext);
102 dbuf_append_char(&asmbuff, *yytext);
104 "at" { count(); TKEYWORDSDCC(AT); }
105 "__at" { count(); TKEYWORD(AT); }
106 "auto" { count(); return(AUTO); }
107 "bit" { count(); TKEYWORDSDCC(BIT); }
108 "__bit" { count(); TKEYWORD(BIT); }
109 "break" { count(); return(BREAK); }
110 "case" { count(); return(CASE); }
111 "char" { count(); return(CHAR); }
112 "code" { count(); TKEYWORDSDCC(CODE); }
113 "__code" { count(); TKEYWORD(CODE); }
114 "const" { count(); return(CONST); }
115 "continue" { count(); return(CONTINUE); }
116 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
117 "__critical" { count(); TKEYWORD(CRITICAL); }
118 "data" { count(); TKEYWORDSDCC(DATA); }
119 "__data" { count(); TKEYWORD(DATA); }
120 "default" { count(); return(DEFAULT); }
121 "do" { count(); return(DO); }
122 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
123 "else" { count(); return(ELSE); }
124 "enum" { count(); return(ENUM); }
125 "extern" { count(); return(EXTERN); }
126 "far" { count(); TKEYWORDSDCC(XDATA); }
127 "__far" { count(); TKEYWORD(XDATA); }
128 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
129 "__eeprom" { count(); TKEYWORD(EEPROM); }
130 "float" { count(); return(FLOAT); }
131 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
132 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
133 "flash" { count(); TKEYWORDSDCC(CODE); }
134 "__flash" { count(); TKEYWORD(CODE); }
135 "for" { count(); return(FOR); }
136 "goto" { count(); return(GOTO); }
137 "idata" { count(); TKEYWORDSDCC(IDATA); }
138 "__idata" { count(); TKEYWORD(IDATA); }
139 "if" { count(); return(IF); }
140 "int" { count(); return(INT); }
141 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
142 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
143 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
144 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
145 "banked" { count(); TKEYWORDSDCC(BANKED); }
146 "__banked" { count(); TKEYWORD(BANKED); }
147 "long" { count(); return(LONG); }
148 "near" { count(); TKEYWORDSDCC(DATA); }
149 "__near" { count(); TKEYWORD(DATA); }
150 "pdata" { count(); TKEYWORDSDCC(PDATA); }
151 "__pdata" { count(); TKEYWORD(PDATA); }
152 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
153 "__reentrant" { count(); TKEYWORD(REENTRANT); }
154 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
155 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
156 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
157 "__wparam" { count(); TKEYWORD(WPARAM); }
158 "register" { count(); return(REGISTER); }
159 "return" { count(); return(RETURN); }
160 "sfr" { count(); TKEYWORDSDCC(SFR); }
161 "__sfr" { count(); TKEYWORD(SFR); }
162 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
163 "__sfr16" { count(); TKEYWORD(SFR16); }
164 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
165 "__sfr32" { count(); TKEYWORD(SFR32); }
166 "sbit" { count(); TKEYWORDSDCC(SBIT); }
167 "__sbit" { count(); TKEYWORD(SBIT); }
168 "short" { count(); return(SHORT); }
169 "signed" { count(); return(SIGNED); }
170 "sizeof" { count(); return(SIZEOF); }
171 "sram" { count(); TKEYWORDSDCC(XDATA); }
172 "__sram" { count(); TKEYWORD(XDATA); }
173 "static" { count(); return(STATIC); }
174 "struct" { count(); return(STRUCT); }
175 "switch" { count(); return(SWITCH); }
176 "typedef" { count(); return(TYPEDEF); }
177 "union" { count(); return(UNION); }
178 "unsigned" { count(); return(UNSIGNED); }
179 "void" { count(); return(VOID); }
180 "volatile" { count(); return(VOLATILE); }
181 "using" { count(); TKEYWORDSDCC(USING); }
182 "__using" { count(); TKEYWORD(USING); }
183 "_naked" { count(); TKEYWORDSDCC(NAKED); }
184 "__naked" { count(); TKEYWORD(NAKED); }
185 "while" { count(); return(WHILE); }
186 "xdata" { count(); TKEYWORDSDCC(XDATA); }
187 "__xdata" { count(); TKEYWORD(XDATA); }
188 "..." { count(); return(VAR_ARGS); }
189 "__typeof" { count(); return TYPEOF; }
190 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
191 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
192 "__overlay" { count(); TKEYWORD(OVERLAY); }
193 "inline" { count(); TKEYWORD99(INLINE); }
194 "restrict" { count(); TKEYWORD99(RESTRICT); }
196 if (!options.dollars_in_ident && strchr(yytext, '$'))
198 yyerror("stray '$' in program");
201 return(check_type());
204 if (!options.std_sdcc)
206 yyerror("binary (0b) constants are not allowed in ISO C");
209 yylval.val = constVal(yytext);
212 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
213 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
214 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
215 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
216 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
217 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
218 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
219 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
220 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
221 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
222 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
223 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
224 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
225 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
226 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
227 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
228 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
229 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
230 ">>" { count(); return(RIGHT_OP); }
231 "<<" { count(); return(LEFT_OP); }
232 "++" { count(); return(INC_OP); }
233 "--" { count(); return(DEC_OP); }
234 "->" { count(); return(PTR_OP); }
235 "&&" { count(); return(AND_OP); }
236 "||" { count(); return(OR_OP); }
237 "<=" { count(); return(LE_OP); }
238 ">=" { count(); return(GE_OP); }
239 "==" { count(); return(EQ_OP); }
240 "!=" { count(); return(NE_OP); }
241 ";" { count(); return(';'); }
242 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
243 "}" { count(); NestLevel--; return('}'); }
244 "," { count(); return(','); }
245 ":" { count(); return(':'); }
246 "=" { count(); return('='); }
247 "(" { count(); ignoreTypedefType = 0; return('('); }
248 ")" { count(); return(')'); }
249 "[" { count(); return('['); }
250 "]" { count(); return(']'); }
251 "." { count(); return('.'); }
252 "&" { count(); return('&'); }
253 "!" { count(); return('!'); }
254 "~" { count(); return('~'); }
255 "-" { count(); return('-'); }
256 "+" { count(); return('+'); }
257 "*" { count(); return('*'); }
258 "/" { count(); return('/'); }
259 "%" { count(); return('%'); }
260 "<" { count(); return('<'); }
261 ">" { count(); return('>'); }
262 "^" { count(); return('^'); }
263 "|" { count(); return('|'); }
264 "?" { count(); return('?'); }
265 ^#pragma.*$ { count(); process_pragma(yytext); }
266 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
268 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
269 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
272 [ \t\v\f] { count(); }
280 /* that could have been removed by the preprocessor anyway */
281 werror (W_STRAY_BACKSLASH, column);
288 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
290 #define yytext_ptr yytext
294 static int checkCurrFile (const char *s)
299 /* skip '#' character */
303 /* check if this is a #line
304 this is not standard and can be removed in the future */
305 #define LINE_STR "line"
306 #define LINE_LEN ((sizeof LINE_STR) - 1)
308 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
311 /* get the line number */
312 lNum = strtol(s, &tptr, 10);
313 if (tptr == s || !isspace((unsigned char)*tptr))
317 /* adjust the line number */
318 lineno = lexLineno = lNum;
320 /* now see if we have a file name */
321 while (*s != '"' && *s)
326 /* no file name: return */
330 /* skip the double quote */
333 /* get the file name and see if it is different from current one.
334 in c1mode fullSrcFileName is NULL */
335 if (fullSrcFileName &&
336 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
338 lexFilename = fullSrcFileName;
345 /* find the end of the file name */
346 while (*s && *s != '"')
349 tmpFname = Safe_malloc(s - sb + 1);
350 memcpy(tmpFname, sb, s - sb);
351 tmpFname[s - sb] = '\0';
353 lexFilename = Safe_malloc(s - sb + 1);
354 copyStr(lexFilename, tmpFname);
356 filename = lexFilename;
361 static void count_char(int ch)
367 lineno = ++lexLineno;
371 column += 8 - (column % 8);
380 static void count(void)
384 for (p = yytext; *p; ++p)
388 static int check_type(void)
390 symbol *sym = findSym(SymbolTab, NULL, yytext);
392 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
394 /* check if it is in the table as a typedef */
395 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
396 && SPEC_TYPEDEF (sym->etype) && findSym(TypedefTab, NULL, yytext))
403 * Change by JTV 2001-05-19 to not concantenate strings
404 * to support ANSI hex and octal escape sequences in string literals
407 static const char *stringLiteral(void)
409 #define STR_BUF_CHUNCK_LEN 1024
411 static struct dbuf_s dbuf; /* reusable string literal buffer */
414 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
416 dbuf_set_length(&dbuf, 0);
418 dbuf_append_char(&dbuf, '"');
420 /* put into the buffer till we hit the first \" */
432 /* if it is a \ then escape char's are allowed */
437 /* \<newline> is a continuator */
448 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
450 break; /* carry on */
453 /* if new line we have a new line break, which is illegal */
454 werror(W_NEWLINE_IN_STRING);
455 dbuf_append_char(&dbuf, '\n');
459 /* if this is a quote then we have work to do */
460 /* find the next non whitespace character */
461 /* if that is a double quote then carry on */
462 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
463 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
469 if ((ch = input()) != '\n')
471 werror(W_STRAY_BACKSLASH, column);
488 /* # at the beginning of the line: collect the entire line */
489 struct dbuf_s linebuf;
494 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
495 dbuf_append_char(&linebuf, '#');
497 while ((ch = input()) != EOF && ch != '\n')
498 dbuf_append_char(&linebuf, (char)ch);
503 line = dbuf_c_str(&linebuf);
505 /* process the line */
506 if (startsWith(line, "#pragma"))
507 process_pragma(line);
511 dbuf_destroy(&linebuf);
537 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
542 return dbuf_c_str(&dbuf);
561 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
562 /* cross-compiling for MINGW32 with gcc 3.2 */
576 /* SAVE/RESTORE stack */
577 #define SAVE_RESTORE_SIZE 128
579 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
580 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
581 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
584 * cloneXxx functions should be updated every time a new set is
585 * added to the options or optimize structure!
588 static struct options *cloneOptions(struct options *opt)
590 struct options *new_opt;
592 new_opt = Safe_malloc(sizeof (struct options));
594 /* clone scalar values */
598 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
599 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
600 /* not implemented yet: */
601 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
606 static struct optimize *cloneOptimize(struct optimize *opt)
608 struct optimize *new_opt;
610 new_opt = Safe_malloc(sizeof (struct optimize));
612 /* clone scalar values */
618 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
620 struct SDCCERRG *new_val;
622 new_val = Safe_malloc(sizeof (struct SDCCERRG));
624 /* clone scalar values */
630 static void copyAndFreeOptions(struct options *dest, struct options *src)
632 /* delete dest sets */
633 deleteSet(&dest->calleeSavesSet);
634 deleteSet(&dest->excludeRegsSet);
635 /* not implemented yet: */
636 /* deleteSet(&dest->olaysSet); */
638 /* copy src to dest */
644 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
646 /* copy src to dest */
652 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
654 /* copy src to dest */
661 * returns 1 if the pragma was processed, 0 if not
663 static int doPragma(int id, const char *name, const char *cp)
665 struct pragma_token_s token;
669 init_pragma_token(&token);
675 cp = get_pragma_token(cp, &token);
676 if (TOKEN_EOL != token.type)
682 STACK_PUSH(options_stack, cloneOptions(&options));
683 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
684 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
690 struct options *optionsp;
691 struct optimize *optimizep;
692 struct SDCCERRG *sdccerrgp;
694 cp = get_pragma_token(cp, &token);
695 if (TOKEN_EOL != token.type)
701 optionsp = STACK_POP(options_stack);
702 copyAndFreeOptions(&options, optionsp);
704 optimizep = STACK_POP(optimize_stack);
705 copyAndFreeOptimize(&optimize, optimizep);
707 sdccerrgp = STACK_POP(SDCCERRG_stack);
708 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
713 cp = get_pragma_token(cp, &token);
714 if (TOKEN_EOL != token.type)
720 optimize.loopInduction = 0;
724 cp = get_pragma_token(cp, &token);
725 if (TOKEN_EOL != token.type)
731 optimize.loopInvariant = 0;
735 cp = get_pragma_token(cp, &token);
736 if (TOKEN_EOL != token.type)
742 optimize.loopInduction = 1;
746 cp = get_pragma_token(cp, &token);
747 if (TOKEN_EOL != token.type)
753 options.stackAuto = 1;
757 cp = get_pragma_token(cp, &token);
758 if (TOKEN_EOL != token.type)
764 optimize.noJTabBoundary = 1;
768 cp = get_pragma_token(cp, &token);
769 if (TOKEN_EOL != token.type)
775 optimize.global_cse = 0;
779 cp = get_pragma_token(cp, &token);
780 if (TOKEN_EOL != token.type)
786 options.noOverlay = 1;
790 cp = get_pragma_token(cp, &token);
791 if (TOKEN_EOL != token.type)
797 options.lessPedantic = 1;
798 setErrorLogLevel(ERROR_LEVEL_WARNING);
802 /* append to the functions already listed
804 setParseWithComma(&options.calleeSavesSet, cp);
810 deleteSet(&options.excludeRegsSet);
811 setParseWithComma(&options.excludeRegsSet, cp);
817 cp = get_pragma_token(cp, &token);
818 if (TOKEN_EOL != token.type)
828 cp = get_pragma_token(cp, &token);
829 if (TOKEN_EOL != token.type)
835 optimize.noLoopReverse = 1;
839 cp = get_pragma_token(cp, &token);
840 if (TOKEN_EOL != token.type)
852 cp = get_pragma_token(cp, &token);
853 if (TOKEN_INT != token.type)
858 warn = token.val.int_val;
860 cp = get_pragma_token(cp, &token);
861 if (TOKEN_EOL != token.type)
867 if (warn < MAX_ERROR_WARNING)
868 setWarningDisabled(warn);
873 cp = get_pragma_token(cp, &token);
874 if (TOKEN_EOL != token.type)
880 optimize.codeSpeed = 1;
881 optimize.codeSize = 0;
885 cp = get_pragma_token(cp, &token);
886 if (TOKEN_EOL != token.type)
892 optimize.codeSpeed = 0;
893 optimize.codeSize = 1;
896 case P_OPTCODEBALANCED:
897 cp = get_pragma_token(cp, &token);
898 if (TOKEN_EOL != token.type)
904 optimize.codeSpeed = 0;
905 optimize.codeSize = 0;
909 cp = get_pragma_token(cp, &token);
910 if (TOKEN_EOL != token.type)
917 options.std_sdcc = 0;
921 cp = get_pragma_token(cp, &token);
922 if (TOKEN_EOL != token.type)
929 options.std_sdcc = 0;
933 cp = get_pragma_token(cp, &token);
934 if (TOKEN_EOL != token.type)
941 options.std_sdcc = 1;
945 cp = get_pragma_token(cp, &token);
946 if (TOKEN_EOL != token.type)
953 options.std_sdcc = 1;
959 struct dbuf_s segname;
961 cp = get_pragma_token(cp, &token);
962 if (token.type == TOKEN_EOL)
968 dbuf_init(&segname, 16);
969 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
971 cp = get_pragma_token(cp, &token);
972 if (token.type != TOKEN_EOL)
974 dbuf_destroy(&segname);
980 options.code_seg = dbuf_detach(&segname);
982 options.const_seg = dbuf_detach(&segname);
991 get_pragma_token(cp, &token);
993 if (1 == err || (0 == err && token.type != TOKEN_EOL))
994 werror(W_BAD_PRAGMA_ARGUMENTS, name);
996 free_pragma_token(&token);
1000 static struct pragma_s pragma_tbl[] = {
1001 { "save", P_SAVE, 0, doPragma },
1002 { "restore", P_RESTORE, 0, doPragma },
1003 { "noinduction", P_NOINDUCTION, 0, doPragma },
1004 { "noinvariant", P_NOINVARIANT, 0, doPragma },
1005 { "noloopreverse", P_LOOPREV, 0, doPragma },
1006 { "induction", P_INDUCTION, 0, doPragma },
1007 { "stackauto", P_STACKAUTO, 0, doPragma },
1008 { "nojtbound", P_NOJTBOUND, 0, doPragma },
1009 { "nogcse", P_NOGCSE, 0, doPragma },
1010 { "nooverlay", P_NOOVERLAY, 0, doPragma },
1011 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
1012 { "exclude", P_EXCLUDE, 0, doPragma },
1013 { "noiv", P_NOIV, 0, doPragma },
1014 { "overlay", P_OVERLAY_, 0, doPragma },
1015 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
1016 { "disable_warning",P_DISABLEWARN, 0, doPragma },
1017 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
1018 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
1019 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1020 { "std_c89", P_STD_C89, 0, doPragma },
1021 { "std_c99", P_STD_C99, 0, doPragma },
1022 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1023 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1024 { "codeseg", P_CODESEG, 0, doPragma },
1025 { "constseg", P_CONSTSEG, 0, doPragma },
1026 { NULL, 0, 0, NULL },
1030 * returns 1 if the pragma was processed, 0 if not
1033 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1035 struct pragma_token_s token;
1039 init_pragma_token(&token);
1041 s = get_pragma_token(s, &token);
1043 /* skip separating whitespace */
1044 while ('\n' != *s && isspace((unsigned char)*s))
1047 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1049 /* now compare and do what needs to be done */
1050 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1052 if (pragma_tbl[i].deprecated != 0)
1053 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1055 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1060 free_pragma_token(&token);
1064 static int process_pragma(const char *s)
1066 struct pragma_token_s token;
1068 init_pragma_token(&token);
1070 s = get_pragma_token(s, &token);
1071 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1073 /* Oops, womething went totally wrong - internal error */
1074 wassertl(0, "pragma parser internal error");
1078 while ('\n' != *s && isspace((unsigned char)*s))
1081 /* First give the port a chance */
1082 if (port->process_pragma && port->process_pragma(s))
1085 if (process_pragma_tbl(pragma_tbl, s))
1091 werror(W_UNKNOWN_PRAGMA, s);
1096 /* will return 1 if the string is a part
1097 of a target specific keyword */
1098 static int isTargetKeyword(const char *s)
1102 if (port->keywords == NULL)
1105 if (s[0] == '_' && s[1] == '_')
1107 /* Keywords in the port's array have either 0 or 1 underscore, */
1108 /* so skip over the appropriate number of chars when comparing */
1109 for (i = 0 ; port->keywords[i] ; i++ )
1111 if (port->keywords[i][0] == '_' &&
1112 strcmp(port->keywords[i],s+1) == 0)
1114 else if (strcmp(port->keywords[i],s+2) == 0)
1120 for (i = 0 ; port->keywords[i] ; i++ )
1122 if (strcmp(port->keywords[i],s) == 0)
1132 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1133 werror(W_SAVE_RESTORE);
1138 int yyerror(char *s)
1142 if(options.vc_err_style)
1143 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1144 lexFilename, lexLineno, s, yytext, column);
1146 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1147 lexFilename, lexLineno, s ,yytext, column);