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(char *s);
64 static int checkCurrFile(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 (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;
315 /* mark the end of the filename */
316 while (*s != '"') s++;
318 currFname = strdup (sb);
319 lineno = mylineno = lNum;
321 filename = currFname ;
328 static void count(void)
331 for (i = 0; yytext[i] != '\0'; i++) {
332 if (yytext[i] == '\n') {
337 if (yytext[i] == '\t')
338 column += 8 - (column % 8);
345 static int check_type(void)
347 symbol *sym = findSym(SymbolTab, NULL, yytext);
349 /* check if it is in the table as a typedef */
350 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
351 && SPEC_TYPEDEF (sym->etype)) {
352 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
356 strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX);
362 * Change by JTV 2001-05-19 to not concantenate strings
363 * to support ANSI hex and octal escape sequences in string literals
366 static char *stringLiteral(void)
368 #define STR_BUF_CHUNCK_LEN 1024
370 static struct dbuf_s dbuf;
374 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
376 dbuf_set_size(&dbuf, 0);
378 dbuf_append(&dbuf, "\"", 1);
379 /* put into the buffer till we hit the first \" */
381 while ((ch = input()) != 0) {
384 /* if it is a \ then escape char's are allowed */
387 /* \<newline> is a continuator */
394 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
396 break; /* carry on */
399 /* if new line we have a new line break, which is illegal */
400 werror(W_NEWLINE_IN_STRING);
401 dbuf_append(&dbuf, "\n", 1);
407 /* if this is a quote then we have work to do */
408 /* find the next non whitespace character */
409 /* if that is a double quote then carry on */
410 dbuf_append(&dbuf, "\"", 1); /* Pass end of this string or substring to evaluator */
411 while ((ch = input()) && (isspace(ch) || ch == '\\')) {
414 if ((ch = input()) != '\n') {
415 werror(W_STRAY_BACKSLASH, column);
441 dbuf_append(&dbuf, buf, 1); /* Put next substring introducer into output string */
446 return (char *)dbuf_c_str(&dbuf);
465 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
466 /* cross-compiling for MINGW32 with gcc 3.2 */
480 /* SAVE/RESTORE stack */
481 #define SAVE_RESTORE_SIZE 128
483 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
484 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
485 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
488 * cloneXxx functions should be updated every time a new set is
489 * added to the options or optimize structure!
492 static struct options *cloneOptions(struct options *opt)
494 struct options *new_opt;
496 new_opt = Safe_malloc(sizeof (struct options));
498 /* clone scalar values */
502 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
503 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
504 /* not implemented yet: */
505 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
510 static struct optimize *cloneOptimize(struct optimize *opt)
512 struct optimize *new_opt;
514 new_opt = Safe_malloc(sizeof (struct optimize));
516 /* clone scalar values */
522 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
524 struct SDCCERRG *new_val;
526 new_val = Safe_malloc(sizeof (struct SDCCERRG));
528 /* clone scalar values */
534 static void copyAndFreeOptions(struct options *dest, struct options *src)
536 /* delete dest sets */
537 deleteSet(&dest->calleeSavesSet);
538 deleteSet(&dest->excludeRegsSet);
539 /* not implemented yet: */
540 /* deleteSet(&dest->olaysSet); */
542 /* copy src to dest */
548 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
550 /* copy src to dest */
556 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
558 /* copy src to dest */
565 * returns 1 if the pragma was processed, 0 if not
567 static int doPragma(int id, const char *name, const char *cp)
569 struct pragma_token_s token;
573 init_pragma_token(&token);
579 cp = get_pragma_token(cp, &token);
580 if (TOKEN_EOL != token.type)
586 STACK_PUSH(options_stack, cloneOptions(&options));
587 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
588 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
594 struct options *optionsp;
595 struct optimize *optimizep;
596 struct SDCCERRG *sdccerrgp;
598 cp = get_pragma_token(cp, &token);
599 if (TOKEN_EOL != token.type)
605 optionsp = STACK_POP(options_stack);
606 copyAndFreeOptions(&options, optionsp);
608 optimizep = STACK_POP(optimize_stack);
609 copyAndFreeOptimize(&optimize, optimizep);
611 sdccerrgp = STACK_POP(SDCCERRG_stack);
612 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
617 cp = get_pragma_token(cp, &token);
618 if (TOKEN_EOL != token.type)
624 optimize.loopInduction = 0;
628 cp = get_pragma_token(cp, &token);
629 if (TOKEN_EOL != token.type)
635 optimize.loopInvariant = 0;
639 cp = get_pragma_token(cp, &token);
640 if (TOKEN_EOL != token.type)
646 optimize.loopInduction = 1;
650 cp = get_pragma_token(cp, &token);
651 if (TOKEN_EOL != token.type)
657 options.stackAuto = 1;
661 cp = get_pragma_token(cp, &token);
662 if (TOKEN_EOL != token.type)
668 optimize.noJTabBoundary = 1;
672 cp = get_pragma_token(cp, &token);
673 if (TOKEN_EOL != token.type)
679 optimize.global_cse = 0;
683 cp = get_pragma_token(cp, &token);
684 if (TOKEN_EOL != token.type)
690 options.noOverlay = 1;
694 cp = get_pragma_token(cp, &token);
695 if (TOKEN_EOL != token.type)
701 options.lessPedantic = 1;
702 setErrorLogLevel(ERROR_LEVEL_WARNING);
706 /* append to the functions already listed
708 setParseWithComma(&options.calleeSavesSet, cp);
714 deleteSet(&options.excludeRegsSet);
715 setParseWithComma(&options.excludeRegsSet, cp);
721 cp = get_pragma_token(cp, &token);
722 if (TOKEN_EOL != token.type)
732 cp = get_pragma_token(cp, &token);
733 if (TOKEN_EOL != token.type)
739 optimize.noLoopReverse = 1;
743 cp = get_pragma_token(cp, &token);
744 if (TOKEN_EOL != token.type)
756 cp = get_pragma_token(cp, &token);
758 if (token.type != TOKEN_INT)
763 warn = token.val.int_val;
765 cp = get_pragma_token(cp, &token);
766 if (TOKEN_EOL != token.type)
772 if (warn < MAX_ERROR_WARNING)
773 setWarningDisabled(warn);
778 cp = get_pragma_token(cp, &token);
779 if (TOKEN_EOL != token.type)
785 optimize.codeSpeed = 1;
786 optimize.codeSize = 0;
790 cp = get_pragma_token(cp, &token);
791 if (TOKEN_EOL != token.type)
797 optimize.codeSpeed = 0;
798 optimize.codeSize = 1;
801 case P_OPTCODEBALANCED:
802 cp = get_pragma_token(cp, &token);
803 if (TOKEN_EOL != token.type)
809 optimize.codeSpeed = 0;
810 optimize.codeSize = 0;
814 cp = get_pragma_token(cp, &token);
815 if (TOKEN_EOL != token.type)
822 options.std_sdcc = 0;
826 cp = get_pragma_token(cp, &token);
827 if (TOKEN_EOL != token.type)
834 options.std_sdcc = 0;
838 cp = get_pragma_token(cp, &token);
839 if (TOKEN_EOL != token.type)
846 options.std_sdcc = 1;
850 cp = get_pragma_token(cp, &token);
851 if (TOKEN_EOL != token.type)
858 options.std_sdcc = 1;
865 cp = get_pragma_token(cp, &token);
866 if (token.type == TOKEN_EOL)
871 segname = get_pragma_string(&token);
873 cp = get_pragma_token(cp, &token);
874 if (token.type != TOKEN_EOL)
880 if (strlen(segname) > 8)
887 dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
888 options.code_seg = Safe_strdup(get_pragma_string(&token));
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));
930 get_pragma_token(cp, &token);
932 if (1 == err || (0 == err && token.type != TOKEN_EOL))
933 werror(W_BAD_PRAGMA_ARGUMENTS, name);
935 free_pragma_token(&token);
939 static struct pragma_s pragma_tbl[] = {
940 { "save", P_SAVE, 0, doPragma },
941 { "restore", P_RESTORE, 0, doPragma },
942 { "noinduction", P_NOINDUCTION, 0, doPragma },
943 { "noinvariant", P_NOINVARIANT, 0, doPragma },
944 { "noloopreverse", P_LOOPREV, 0, doPragma },
945 { "induction", P_INDUCTION, 0, doPragma },
946 { "stackauto", P_STACKAUTO, 0, doPragma },
947 { "nojtbound", P_NOJTBOUND, 0, doPragma },
948 { "nogcse", P_NOGCSE, 0, doPragma },
949 { "nooverlay", P_NOOVERLAY, 0, doPragma },
950 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
951 { "exclude", P_EXCLUDE, 0, doPragma },
952 { "noiv", P_NOIV, 0, doPragma },
953 { "overlay", P_OVERLAY_, 0, doPragma },
954 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
955 { "disable_warning",P_DISABLEWARN, 0, doPragma },
956 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
957 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
958 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
959 { "std_c89", P_STD_C89, 0, doPragma },
960 { "std_c99", P_STD_C99, 0, doPragma },
961 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
962 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
963 { "codeseg", P_CODESEG, 0, doPragma },
964 { "constseg", P_CONSTSEG, 0, doPragma },
965 { NULL, 0, 0, NULL },
969 * returns 1 if the pragma was processed, 0 if not
972 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
974 struct pragma_token_s token;
978 init_pragma_token(&token);
980 s = get_pragma_token(s, &token);
982 /* skip separating whitespace */
983 while ('\n' != *s && isspace((unsigned char)*s))
986 for (i = 0; NULL != pragma_tbl[i].name; ++i)
988 /* now compare and do what needs to be done */
989 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
991 if (pragma_tbl[i].deprecated != 0)
992 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
994 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
999 free_pragma_token(&token);
1003 static int process_pragma(const char *s)
1005 struct pragma_token_s token;
1007 init_pragma_token(&token);
1009 s = get_pragma_token(s, &token);
1010 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1012 /* Oops, womething went totally wrong - internal error */
1013 wassertl(0, "pragma parser internal error");
1017 while ('\n' != *s && isspace((unsigned char)*s))
1020 /* First give the port a chance */
1021 if (port->process_pragma && port->process_pragma(s))
1024 if (process_pragma_tbl(pragma_tbl, s))
1030 werror(W_UNKNOWN_PRAGMA, s);
1035 /* will return 1 if the string is a part
1036 of a target specific keyword */
1037 static int isTargetKeyword(char *s)
1041 if (port->keywords == NULL)
1044 if (s[0] == '_' && s[1] == '_')
1046 /* Keywords in the port's array have either 0 or 1 underscore, */
1047 /* so skip over the appropriate number of chars when comparing */
1048 for (i = 0 ; port->keywords[i] ; i++ )
1050 if (port->keywords[i][0] == '_' &&
1051 strcmp(port->keywords[i],s+1) == 0)
1053 else if (strcmp(port->keywords[i],s+2) == 0)
1059 for (i = 0 ; port->keywords[i] ; i++ )
1061 if (strcmp(port->keywords[i],s) == 0)
1071 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1072 werror(W_SAVE_RESTORE);
1077 int yyerror(char *s)
1081 if(options.vc_err_style)
1082 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1083 filename, mylineno, s, yytext, column);
1085 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1086 filename, mylineno, s ,yytext, column);