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 char *filename;
50 int column = 0; /* current column */
52 /* local definitions */
53 static struct dbuf_s asmbuff; /* reusable _asm buffer */
55 /* forward declarations */
56 static const char *stringLiteral(void);
57 static void count(void);
58 static int process_pragma(const char *);
59 static int check_type(void);
60 static int isTargetKeyword(const char *s);
61 static int checkCurrFile(const char *s);
68 if (!options.std_sdcc && yytext[1] != '_')
70 if (asmbuff.buf == NULL)
71 dbuf_init(&asmbuff, INITIAL_INLINEASM);
73 dbuf_set_length(&asmbuff, 0);
79 if (!options.std_sdcc && yytext[1] != '_')
81 dbuf_append_str(&asmbuff, yytext);
85 yylval.yyinline = dbuf_c_str(&asmbuff);
92 dbuf_append_char(&asmbuff, *yytext);
95 dbuf_append_char(&asmbuff, *yytext);
97 "at" { count(); TKEYWORDSDCC(AT); }
98 "__at" { count(); TKEYWORD(AT); }
99 "auto" { count(); return(AUTO); }
100 "bit" { count(); TKEYWORDSDCC(BIT); }
101 "__bit" { count(); TKEYWORD(BIT); }
102 "break" { count(); return(BREAK); }
103 "case" { count(); return(CASE); }
104 "char" { count(); return(CHAR); }
105 "code" { count(); TKEYWORDSDCC(CODE); }
106 "__code" { count(); TKEYWORD(CODE); }
107 "const" { count(); return(CONST); }
108 "continue" { count(); return(CONTINUE); }
109 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
110 "__critical" { count(); TKEYWORD(CRITICAL); }
111 "data" { count(); TKEYWORDSDCC(DATA); }
112 "__data" { count(); TKEYWORD(DATA); }
113 "default" { count(); return(DEFAULT); }
114 "do" { count(); return(DO); }
115 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
116 "else" { count(); return(ELSE); }
117 "enum" { count(); return(ENUM); }
118 "extern" { count(); return(EXTERN); }
119 "far" { count(); TKEYWORDSDCC(XDATA); }
120 "__far" { count(); TKEYWORD(XDATA); }
121 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
122 "__eeprom" { count(); TKEYWORD(EEPROM); }
123 "float" { count(); return(FLOAT); }
124 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
125 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
126 "flash" { count(); TKEYWORDSDCC(CODE); }
127 "__flash" { count(); TKEYWORD(CODE); }
128 "for" { count(); return(FOR); }
129 "goto" { count(); return(GOTO); }
130 "idata" { count(); TKEYWORDSDCC(IDATA); }
131 "__idata" { count(); TKEYWORD(IDATA); }
132 "if" { count(); return(IF); }
133 "int" { count(); return(INT); }
134 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
135 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
136 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
137 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
138 "banked" { count(); TKEYWORDSDCC(BANKED); }
139 "__banked" { count(); TKEYWORD(BANKED); }
140 "long" { count(); return(LONG); }
141 "near" { count(); TKEYWORDSDCC(DATA); }
142 "__near" { count(); TKEYWORD(DATA); }
143 "pdata" { count(); TKEYWORDSDCC(PDATA); }
144 "__pdata" { count(); TKEYWORD(PDATA); }
145 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
146 "__reentrant" { count(); TKEYWORD(REENTRANT); }
147 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
148 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
149 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
150 "__wparam" { count(); TKEYWORD(WPARAM); }
151 "register" { count(); return(REGISTER); }
152 "return" { count(); return(RETURN); }
153 "sfr" { count(); TKEYWORDSDCC(SFR); }
154 "__sfr" { count(); TKEYWORD(SFR); }
155 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
156 "__sfr16" { count(); TKEYWORD(SFR16); }
157 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
158 "__sfr32" { count(); TKEYWORD(SFR32); }
159 "sbit" { count(); TKEYWORDSDCC(SBIT); }
160 "__sbit" { count(); TKEYWORD(SBIT); }
161 "short" { count(); return(SHORT); }
162 "signed" { count(); return(SIGNED); }
163 "sizeof" { count(); return(SIZEOF); }
164 "sram" { count(); TKEYWORDSDCC(XDATA); }
165 "__sram" { count(); TKEYWORD(XDATA); }
166 "static" { count(); return(STATIC); }
167 "struct" { count(); return(STRUCT); }
168 "switch" { count(); return(SWITCH); }
169 "typedef" { count(); return(TYPEDEF); }
170 "union" { count(); return(UNION); }
171 "unsigned" { count(); return(UNSIGNED); }
172 "void" { count(); return(VOID); }
173 "volatile" { count(); return(VOLATILE); }
174 "using" { count(); TKEYWORDSDCC(USING); }
175 "__using" { count(); TKEYWORD(USING); }
176 "_naked" { count(); TKEYWORDSDCC(NAKED); }
177 "__naked" { count(); TKEYWORD(NAKED); }
178 "while" { count(); return(WHILE); }
179 "xdata" { count(); TKEYWORDSDCC(XDATA); }
180 "__xdata" { count(); TKEYWORD(XDATA); }
181 "..." { count(); return(VAR_ARGS); }
182 "__typeof" { count(); return TYPEOF; }
183 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
184 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
185 "__overlay" { count(); TKEYWORD(OVERLAY); }
186 "inline" { count(); TKEYWORD99(INLINE); }
187 "restrict" { count(); TKEYWORD99(RESTRICT); }
188 {L}({L}|{D})* { count(); return(check_type()); }
189 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
190 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
191 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
192 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
193 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
194 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
195 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
196 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
197 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
198 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
199 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
200 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
201 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
202 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
203 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
204 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
205 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
206 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
207 ">>" { count(); return(RIGHT_OP); }
208 "<<" { count(); return(LEFT_OP); }
209 "++" { count(); return(INC_OP); }
210 "--" { count(); return(DEC_OP); }
211 "->" { count(); return(PTR_OP); }
212 "&&" { count(); return(AND_OP); }
213 "||" { count(); return(OR_OP); }
214 "<=" { count(); return(LE_OP); }
215 ">=" { count(); return(GE_OP); }
216 "==" { count(); return(EQ_OP); }
217 "!=" { count(); return(NE_OP); }
218 ";" { count(); return(';'); }
219 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
220 "}" { count(); NestLevel--; return('}'); }
221 "," { count(); return(','); }
222 ":" { count(); return(':'); }
223 "=" { count(); return('='); }
224 "(" { count(); ignoreTypedefType = 0; return('('); }
225 ")" { count(); 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 ^#pragma.*$ { count(); process_pragma(yytext); }
243 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
245 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
246 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
249 [ \t\v\f] { count(); }
255 /* that could have been removed by the preprocessor anyway */
256 werror (W_STRAY_BACKSLASH, column);
264 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
266 #define yytext_ptr yytext
270 static int checkCurrFile (const char *s)
275 /* skip '#' character */
279 /* check if this is a #line
280 this is not standard and can be removed in the future */
281 #define LINE_STR "line"
282 #define LINE_LEN ((sizeof LINE_STR) - 1)
284 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
287 /* get the line number */
288 lNum = strtol(s, &tptr, 10);
289 if (tptr == s || !isspace((unsigned char)*tptr))
293 /* adjust the line number */
296 /* now see if we have a file name */
297 while (*s != '"' && *s)
302 /* no file name: return */
306 /* skip the double quote */
309 /* get the file name and see if it is different from current one.
310 in c1mode fullSrcFileName is NULL */
311 if (fullSrcFileName &&
312 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
314 filename = fullSrcFileName;
320 /* find the end of the filename */
321 while (*s && *s != '"')
324 filename = Safe_malloc(s - sb + 1);
325 memcpy(filename, sb, s - sb);
326 filename[s - sb] = '\0';
331 static void count(void)
334 for (i = 0; yytext[i] != '\0'; i++)
336 if (yytext[i] == '\n')
342 if (yytext[i] == '\t')
343 column += 8 - (column % 8);
350 static int check_type(void)
352 symbol *sym = findSym(SymbolTab, NULL, yytext);
354 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
356 /* check if it is in the table as a typedef */
357 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
358 && SPEC_TYPEDEF (sym->etype))
365 * Change by JTV 2001-05-19 to not concantenate strings
366 * to support ANSI hex and octal escape sequences in string literals
369 static const char *stringLiteral(void)
371 #define STR_BUF_CHUNCK_LEN 1024
373 static struct dbuf_s dbuf; /* reusable string literal buffer */
376 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
378 dbuf_set_length(&dbuf, 0);
380 dbuf_append_char(&dbuf, '"');
382 /* put into the buffer till we hit the first \" */
394 /* if it is a \ then escape char's are allowed */
395 if ((ch = input()) == '\n')
397 /* \<newline> is a continuator */
411 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
413 break; /* carry on */
416 /* if new line we have a new line break, which is illegal */
417 werror(W_NEWLINE_IN_STRING);
418 dbuf_append_char(&dbuf, '\n');
424 /* if this is a quote then we have work to do */
425 /* find the next non whitespace character */
426 /* if that is a double quote then carry on */
427 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
428 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
435 if ((ch = input()) != '\n')
438 werror(W_STRAY_BACKSLASH, column);
460 /* # at the beginning of the line: collect the entire line */
461 struct dbuf_s linebuf;
464 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
465 dbuf_append_char(&linebuf, '#');
467 while ((ch = input()) != EOF && ch != '\n')
468 dbuf_append_char(&linebuf, (char)ch);
476 line = dbuf_c_str(&linebuf);
478 /* process the line */
479 if (startsWith(line, "#pragma"))
480 process_pragma(line);
484 dbuf_destroy(&linebuf);
501 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
506 return dbuf_c_str(&dbuf);
525 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
526 /* cross-compiling for MINGW32 with gcc 3.2 */
540 /* SAVE/RESTORE stack */
541 #define SAVE_RESTORE_SIZE 128
543 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
544 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
545 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
548 * cloneXxx functions should be updated every time a new set is
549 * added to the options or optimize structure!
552 static struct options *cloneOptions(struct options *opt)
554 struct options *new_opt;
556 new_opt = Safe_malloc(sizeof (struct options));
558 /* clone scalar values */
562 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
563 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
564 /* not implemented yet: */
565 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
570 static struct optimize *cloneOptimize(struct optimize *opt)
572 struct optimize *new_opt;
574 new_opt = Safe_malloc(sizeof (struct optimize));
576 /* clone scalar values */
582 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
584 struct SDCCERRG *new_val;
586 new_val = Safe_malloc(sizeof (struct SDCCERRG));
588 /* clone scalar values */
594 static void copyAndFreeOptions(struct options *dest, struct options *src)
596 /* delete dest sets */
597 deleteSet(&dest->calleeSavesSet);
598 deleteSet(&dest->excludeRegsSet);
599 /* not implemented yet: */
600 /* deleteSet(&dest->olaysSet); */
602 /* copy src to dest */
608 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
610 /* copy src to dest */
616 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
618 /* copy src to dest */
625 * returns 1 if the pragma was processed, 0 if not
627 static int doPragma(int id, const char *name, const char *cp)
629 struct pragma_token_s token;
633 init_pragma_token(&token);
639 cp = get_pragma_token(cp, &token);
640 if (TOKEN_EOL != token.type)
646 STACK_PUSH(options_stack, cloneOptions(&options));
647 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
648 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
654 struct options *optionsp;
655 struct optimize *optimizep;
656 struct SDCCERRG *sdccerrgp;
658 cp = get_pragma_token(cp, &token);
659 if (TOKEN_EOL != token.type)
665 optionsp = STACK_POP(options_stack);
666 copyAndFreeOptions(&options, optionsp);
668 optimizep = STACK_POP(optimize_stack);
669 copyAndFreeOptimize(&optimize, optimizep);
671 sdccerrgp = STACK_POP(SDCCERRG_stack);
672 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
677 cp = get_pragma_token(cp, &token);
678 if (TOKEN_EOL != token.type)
684 optimize.loopInduction = 0;
688 cp = get_pragma_token(cp, &token);
689 if (TOKEN_EOL != token.type)
695 optimize.loopInvariant = 0;
699 cp = get_pragma_token(cp, &token);
700 if (TOKEN_EOL != token.type)
706 optimize.loopInduction = 1;
710 cp = get_pragma_token(cp, &token);
711 if (TOKEN_EOL != token.type)
717 options.stackAuto = 1;
721 cp = get_pragma_token(cp, &token);
722 if (TOKEN_EOL != token.type)
728 optimize.noJTabBoundary = 1;
732 cp = get_pragma_token(cp, &token);
733 if (TOKEN_EOL != token.type)
739 optimize.global_cse = 0;
743 cp = get_pragma_token(cp, &token);
744 if (TOKEN_EOL != token.type)
750 options.noOverlay = 1;
754 cp = get_pragma_token(cp, &token);
755 if (TOKEN_EOL != token.type)
761 options.lessPedantic = 1;
762 setErrorLogLevel(ERROR_LEVEL_WARNING);
766 /* append to the functions already listed
768 setParseWithComma(&options.calleeSavesSet, cp);
774 deleteSet(&options.excludeRegsSet);
775 setParseWithComma(&options.excludeRegsSet, cp);
781 cp = get_pragma_token(cp, &token);
782 if (TOKEN_EOL != token.type)
792 cp = get_pragma_token(cp, &token);
793 if (TOKEN_EOL != token.type)
799 optimize.noLoopReverse = 1;
803 cp = get_pragma_token(cp, &token);
804 if (TOKEN_EOL != token.type)
816 cp = get_pragma_token(cp, &token);
817 if (TOKEN_INT != token.type)
822 warn = token.val.int_val;
824 cp = get_pragma_token(cp, &token);
825 if (TOKEN_EOL != token.type)
831 if (warn < MAX_ERROR_WARNING)
832 setWarningDisabled(warn);
837 cp = get_pragma_token(cp, &token);
838 if (TOKEN_EOL != token.type)
844 optimize.codeSpeed = 1;
845 optimize.codeSize = 0;
849 cp = get_pragma_token(cp, &token);
850 if (TOKEN_EOL != token.type)
856 optimize.codeSpeed = 0;
857 optimize.codeSize = 1;
860 case P_OPTCODEBALANCED:
861 cp = get_pragma_token(cp, &token);
862 if (TOKEN_EOL != token.type)
868 optimize.codeSpeed = 0;
869 optimize.codeSize = 0;
873 cp = get_pragma_token(cp, &token);
874 if (TOKEN_EOL != token.type)
881 options.std_sdcc = 0;
885 cp = get_pragma_token(cp, &token);
886 if (TOKEN_EOL != token.type)
893 options.std_sdcc = 0;
897 cp = get_pragma_token(cp, &token);
898 if (TOKEN_EOL != token.type)
905 options.std_sdcc = 1;
909 cp = get_pragma_token(cp, &token);
910 if (TOKEN_EOL != token.type)
917 options.std_sdcc = 1;
923 struct dbuf_s segname;
925 cp = get_pragma_token(cp, &token);
926 if (token.type == TOKEN_EOL)
932 dbuf_init(&segname, 16);
933 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
935 cp = get_pragma_token(cp, &token);
936 if (token.type != TOKEN_EOL)
938 dbuf_destroy(&segname);
944 options.code_seg = dbuf_detach(&segname);
946 options.const_seg = dbuf_detach(&segname);
955 get_pragma_token(cp, &token);
957 if (1 == err || (0 == err && token.type != TOKEN_EOL))
958 werror(W_BAD_PRAGMA_ARGUMENTS, name);
960 free_pragma_token(&token);
964 static struct pragma_s pragma_tbl[] = {
965 { "save", P_SAVE, 0, doPragma },
966 { "restore", P_RESTORE, 0, doPragma },
967 { "noinduction", P_NOINDUCTION, 0, doPragma },
968 { "noinvariant", P_NOINVARIANT, 0, doPragma },
969 { "noloopreverse", P_LOOPREV, 0, doPragma },
970 { "induction", P_INDUCTION, 0, doPragma },
971 { "stackauto", P_STACKAUTO, 0, doPragma },
972 { "nojtbound", P_NOJTBOUND, 0, doPragma },
973 { "nogcse", P_NOGCSE, 0, doPragma },
974 { "nooverlay", P_NOOVERLAY, 0, doPragma },
975 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
976 { "exclude", P_EXCLUDE, 0, doPragma },
977 { "noiv", P_NOIV, 0, doPragma },
978 { "overlay", P_OVERLAY_, 0, doPragma },
979 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
980 { "disable_warning",P_DISABLEWARN, 0, doPragma },
981 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
982 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
983 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
984 { "std_c89", P_STD_C89, 0, doPragma },
985 { "std_c99", P_STD_C99, 0, doPragma },
986 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
987 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
988 { "codeseg", P_CODESEG, 0, doPragma },
989 { "constseg", P_CONSTSEG, 0, doPragma },
990 { NULL, 0, 0, NULL },
994 * returns 1 if the pragma was processed, 0 if not
997 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
999 struct pragma_token_s token;
1003 init_pragma_token(&token);
1005 s = get_pragma_token(s, &token);
1007 /* skip separating whitespace */
1008 while ('\n' != *s && isspace((unsigned char)*s))
1011 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1013 /* now compare and do what needs to be done */
1014 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1016 if (pragma_tbl[i].deprecated != 0)
1017 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1019 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1024 free_pragma_token(&token);
1028 static int process_pragma(const char *s)
1030 struct pragma_token_s token;
1032 init_pragma_token(&token);
1034 s = get_pragma_token(s, &token);
1035 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1037 /* Oops, womething went totally wrong - internal error */
1038 wassertl(0, "pragma parser internal error");
1042 while ('\n' != *s && isspace((unsigned char)*s))
1045 /* First give the port a chance */
1046 if (port->process_pragma && port->process_pragma(s))
1049 if (process_pragma_tbl(pragma_tbl, s))
1055 werror(W_UNKNOWN_PRAGMA, s);
1060 /* will return 1 if the string is a part
1061 of a target specific keyword */
1062 static int isTargetKeyword(const char *s)
1066 if (port->keywords == NULL)
1069 if (s[0] == '_' && s[1] == '_')
1071 /* Keywords in the port's array have either 0 or 1 underscore, */
1072 /* so skip over the appropriate number of chars when comparing */
1073 for (i = 0 ; port->keywords[i] ; i++ )
1075 if (port->keywords[i][0] == '_' &&
1076 strcmp(port->keywords[i],s+1) == 0)
1078 else if (strcmp(port->keywords[i],s+2) == 0)
1084 for (i = 0 ; port->keywords[i] ; i++ )
1086 if (strcmp(port->keywords[i],s) == 0)
1096 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1097 werror(W_SAVE_RESTORE);
1102 int yyerror(char *s)
1106 if(options.vc_err_style)
1107 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1108 filename, lineno, s, yytext, column);
1110 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1111 filename, lineno, s ,yytext, column);