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 -------------------------------------------------------------------------*/
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 /* local definitions */
54 static struct dbuf_s asmbuff; /* reusable _asm buffer */
56 /* forward declarations */
57 static const char *stringLiteral(void);
58 static void count(void);
59 static void count_char(int);
60 static int process_pragma(const char *);
61 static int check_type(void);
62 static int isTargetKeyword(const char *s);
63 static int checkCurrFile(const char *s);
70 if (!options.std_sdcc && yytext[1] != '_')
72 if (asmbuff.buf == NULL)
73 dbuf_init(&asmbuff, INITIAL_INLINEASM);
75 dbuf_set_length(&asmbuff, 0);
81 if (!options.std_sdcc && yytext[1] != '_')
83 dbuf_append_str(&asmbuff, yytext);
87 yylval.yyinline = dbuf_c_str(&asmbuff);
94 dbuf_append_char(&asmbuff, *yytext);
97 dbuf_append_char(&asmbuff, *yytext);
99 "at" { count(); TKEYWORDSDCC(AT); }
100 "__at" { count(); TKEYWORD(AT); }
101 "auto" { count(); return(AUTO); }
102 "bit" { count(); TKEYWORDSDCC(BIT); }
103 "__bit" { count(); TKEYWORD(BIT); }
104 "break" { count(); return(BREAK); }
105 "case" { count(); return(CASE); }
106 "char" { count(); return(CHAR); }
107 "code" { count(); TKEYWORDSDCC(CODE); }
108 "__code" { count(); TKEYWORD(CODE); }
109 "const" { count(); return(CONST); }
110 "continue" { count(); return(CONTINUE); }
111 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
112 "__critical" { count(); TKEYWORD(CRITICAL); }
113 "data" { count(); TKEYWORDSDCC(DATA); }
114 "__data" { count(); TKEYWORD(DATA); }
115 "default" { count(); return(DEFAULT); }
116 "do" { count(); return(DO); }
117 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
118 "else" { count(); return(ELSE); }
119 "enum" { count(); return(ENUM); }
120 "extern" { count(); return(EXTERN); }
121 "far" { count(); TKEYWORDSDCC(XDATA); }
122 "__far" { count(); TKEYWORD(XDATA); }
123 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
124 "__eeprom" { count(); TKEYWORD(EEPROM); }
125 "float" { count(); return(FLOAT); }
126 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
127 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
128 "flash" { count(); TKEYWORDSDCC(CODE); }
129 "__flash" { count(); TKEYWORD(CODE); }
130 "for" { count(); return(FOR); }
131 "goto" { count(); return(GOTO); }
132 "idata" { count(); TKEYWORDSDCC(IDATA); }
133 "__idata" { count(); TKEYWORD(IDATA); }
134 "if" { count(); return(IF); }
135 "int" { count(); return(INT); }
136 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
137 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
138 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
139 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
140 "banked" { count(); TKEYWORDSDCC(BANKED); }
141 "__banked" { count(); TKEYWORD(BANKED); }
142 "long" { count(); return(LONG); }
143 "near" { count(); TKEYWORDSDCC(DATA); }
144 "__near" { count(); TKEYWORD(DATA); }
145 "pdata" { count(); TKEYWORDSDCC(PDATA); }
146 "__pdata" { count(); TKEYWORD(PDATA); }
147 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
148 "__reentrant" { count(); TKEYWORD(REENTRANT); }
149 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
150 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
151 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
152 "__wparam" { count(); TKEYWORD(WPARAM); }
153 "register" { count(); return(REGISTER); }
154 "return" { count(); return(RETURN); }
155 "sfr" { count(); TKEYWORDSDCC(SFR); }
156 "__sfr" { count(); TKEYWORD(SFR); }
157 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
158 "__sfr16" { count(); TKEYWORD(SFR16); }
159 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
160 "__sfr32" { count(); TKEYWORD(SFR32); }
161 "sbit" { count(); TKEYWORDSDCC(SBIT); }
162 "__sbit" { count(); TKEYWORD(SBIT); }
163 "short" { count(); return(SHORT); }
164 "signed" { count(); return(SIGNED); }
165 "sizeof" { count(); return(SIZEOF); }
166 "sram" { count(); TKEYWORDSDCC(XDATA); }
167 "__sram" { count(); TKEYWORD(XDATA); }
168 "static" { count(); return(STATIC); }
169 "struct" { count(); return(STRUCT); }
170 "switch" { count(); return(SWITCH); }
171 "typedef" { count(); return(TYPEDEF); }
172 "union" { count(); return(UNION); }
173 "unsigned" { count(); return(UNSIGNED); }
174 "void" { count(); return(VOID); }
175 "volatile" { count(); return(VOLATILE); }
176 "using" { count(); TKEYWORDSDCC(USING); }
177 "__using" { count(); TKEYWORD(USING); }
178 "_naked" { count(); TKEYWORDSDCC(NAKED); }
179 "__naked" { count(); TKEYWORD(NAKED); }
180 "while" { count(); return(WHILE); }
181 "xdata" { count(); TKEYWORDSDCC(XDATA); }
182 "__xdata" { count(); TKEYWORD(XDATA); }
183 "..." { count(); return(VAR_ARGS); }
184 "__typeof" { count(); return TYPEOF; }
185 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
186 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
187 "__overlay" { count(); TKEYWORD(OVERLAY); }
188 "inline" { count(); TKEYWORD99(INLINE); }
189 "restrict" { count(); TKEYWORD99(RESTRICT); }
190 {L}({L}|{D})* { count(); return(check_type()); }
191 {L_DOLL}({L_DOLL}|{D})* {
192 if (options.dollars_in_ident)
195 return(check_type());
200 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
201 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
202 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
203 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
204 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
205 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
206 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
207 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
208 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
209 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
210 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
211 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
212 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
213 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
214 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
215 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
216 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
217 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
218 ">>" { count(); return(RIGHT_OP); }
219 "<<" { count(); return(LEFT_OP); }
220 "++" { count(); return(INC_OP); }
221 "--" { count(); return(DEC_OP); }
222 "->" { count(); return(PTR_OP); }
223 "&&" { count(); return(AND_OP); }
224 "||" { count(); return(OR_OP); }
225 "<=" { count(); return(LE_OP); }
226 ">=" { count(); return(GE_OP); }
227 "==" { count(); return(EQ_OP); }
228 "!=" { count(); return(NE_OP); }
229 ";" { count(); return(';'); }
230 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
231 "}" { count(); NestLevel--; return('}'); }
232 "," { count(); return(','); }
233 ":" { count(); return(':'); }
234 "=" { count(); return('='); }
235 "(" { count(); ignoreTypedefType = 0; return('('); }
236 ")" { count(); return(')'); }
237 "[" { count(); return('['); }
238 "]" { count(); return(']'); }
239 "." { count(); return('.'); }
240 "&" { count(); return('&'); }
241 "!" { count(); return('!'); }
242 "~" { count(); return('~'); }
243 "-" { count(); return('-'); }
244 "+" { count(); return('+'); }
245 "*" { count(); return('*'); }
246 "/" { count(); return('/'); }
247 "%" { count(); return('%'); }
248 "<" { count(); return('<'); }
249 ">" { count(); return('>'); }
250 "^" { count(); return('^'); }
251 "|" { count(); return('|'); }
252 "?" { count(); return('?'); }
253 ^#pragma.*$ { count(); process_pragma(yytext); }
254 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
256 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
257 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
260 [ \t\v\f] { count(); }
268 /* that could have been removed by the preprocessor anyway */
269 werror (W_STRAY_BACKSLASH, column);
276 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
278 #define yytext_ptr yytext
282 static int checkCurrFile (const char *s)
287 /* skip '#' character */
291 /* check if this is a #line
292 this is not standard and can be removed in the future */
293 #define LINE_STR "line"
294 #define LINE_LEN ((sizeof LINE_STR) - 1)
296 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
299 /* get the line number */
300 lNum = strtol(s, &tptr, 10);
301 if (tptr == s || !isspace((unsigned char)*tptr))
305 /* adjust the line number */
308 /* now see if we have a file name */
309 while (*s != '"' && *s)
314 /* no file name: return */
318 /* skip the double quote */
321 /* get the file name and see if it is different from current one.
322 in c1mode fullSrcFileName is NULL */
323 if (fullSrcFileName &&
324 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
326 filename = fullSrcFileName;
332 /* find the end of the filename */
333 while (*s && *s != '"')
336 filename = Safe_malloc(s - sb + 1);
337 memcpy(filename, sb, s - sb);
338 filename[s - sb] = '\0';
343 static void count_char(int ch)
353 column += 8 - (column % 8);
362 static void count(void)
366 for (p = yytext; *p; ++p)
370 static int check_type(void)
372 symbol *sym = findSym(SymbolTab, NULL, yytext);
374 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
376 /* check if it is in the table as a typedef */
377 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
378 && SPEC_TYPEDEF (sym->etype))
385 * Change by JTV 2001-05-19 to not concantenate strings
386 * to support ANSI hex and octal escape sequences in string literals
389 static const char *stringLiteral(void)
391 #define STR_BUF_CHUNCK_LEN 1024
393 static struct dbuf_s dbuf; /* reusable string literal buffer */
396 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
398 dbuf_set_length(&dbuf, 0);
400 dbuf_append_char(&dbuf, '"');
402 /* put into the buffer till we hit the first \" */
414 /* if it is a \ then escape char's are allowed */
419 /* \<newline> is a continuator */
430 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
432 break; /* carry on */
435 /* if new line we have a new line break, which is illegal */
436 werror(W_NEWLINE_IN_STRING);
437 dbuf_append_char(&dbuf, '\n');
441 /* if this is a quote then we have work to do */
442 /* find the next non whitespace character */
443 /* if that is a double quote then carry on */
444 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
445 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
451 if ((ch = input()) != '\n')
453 werror(W_STRAY_BACKSLASH, column);
470 /* # at the beginning of the line: collect the entire line */
471 struct dbuf_s linebuf;
476 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
477 dbuf_append_char(&linebuf, '#');
479 while ((ch = input()) != EOF && ch != '\n')
480 dbuf_append_char(&linebuf, (char)ch);
485 line = dbuf_c_str(&linebuf);
487 /* process the line */
488 if (startsWith(line, "#pragma"))
489 process_pragma(line);
493 dbuf_destroy(&linebuf);
517 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
522 return dbuf_c_str(&dbuf);
541 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
542 /* cross-compiling for MINGW32 with gcc 3.2 */
556 /* SAVE/RESTORE stack */
557 #define SAVE_RESTORE_SIZE 128
559 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
560 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
561 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
564 * cloneXxx functions should be updated every time a new set is
565 * added to the options or optimize structure!
568 static struct options *cloneOptions(struct options *opt)
570 struct options *new_opt;
572 new_opt = Safe_malloc(sizeof (struct options));
574 /* clone scalar values */
578 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
579 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
580 /* not implemented yet: */
581 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
586 static struct optimize *cloneOptimize(struct optimize *opt)
588 struct optimize *new_opt;
590 new_opt = Safe_malloc(sizeof (struct optimize));
592 /* clone scalar values */
598 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
600 struct SDCCERRG *new_val;
602 new_val = Safe_malloc(sizeof (struct SDCCERRG));
604 /* clone scalar values */
610 static void copyAndFreeOptions(struct options *dest, struct options *src)
612 /* delete dest sets */
613 deleteSet(&dest->calleeSavesSet);
614 deleteSet(&dest->excludeRegsSet);
615 /* not implemented yet: */
616 /* deleteSet(&dest->olaysSet); */
618 /* copy src to dest */
624 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
626 /* copy src to dest */
632 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
634 /* copy src to dest */
641 * returns 1 if the pragma was processed, 0 if not
643 static int doPragma(int id, const char *name, const char *cp)
645 struct pragma_token_s token;
649 init_pragma_token(&token);
655 cp = get_pragma_token(cp, &token);
656 if (TOKEN_EOL != token.type)
662 STACK_PUSH(options_stack, cloneOptions(&options));
663 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
664 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
670 struct options *optionsp;
671 struct optimize *optimizep;
672 struct SDCCERRG *sdccerrgp;
674 cp = get_pragma_token(cp, &token);
675 if (TOKEN_EOL != token.type)
681 optionsp = STACK_POP(options_stack);
682 copyAndFreeOptions(&options, optionsp);
684 optimizep = STACK_POP(optimize_stack);
685 copyAndFreeOptimize(&optimize, optimizep);
687 sdccerrgp = STACK_POP(SDCCERRG_stack);
688 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
693 cp = get_pragma_token(cp, &token);
694 if (TOKEN_EOL != token.type)
700 optimize.loopInduction = 0;
704 cp = get_pragma_token(cp, &token);
705 if (TOKEN_EOL != token.type)
711 optimize.loopInvariant = 0;
715 cp = get_pragma_token(cp, &token);
716 if (TOKEN_EOL != token.type)
722 optimize.loopInduction = 1;
726 cp = get_pragma_token(cp, &token);
727 if (TOKEN_EOL != token.type)
733 options.stackAuto = 1;
737 cp = get_pragma_token(cp, &token);
738 if (TOKEN_EOL != token.type)
744 optimize.noJTabBoundary = 1;
748 cp = get_pragma_token(cp, &token);
749 if (TOKEN_EOL != token.type)
755 optimize.global_cse = 0;
759 cp = get_pragma_token(cp, &token);
760 if (TOKEN_EOL != token.type)
766 options.noOverlay = 1;
770 cp = get_pragma_token(cp, &token);
771 if (TOKEN_EOL != token.type)
777 options.lessPedantic = 1;
778 setErrorLogLevel(ERROR_LEVEL_WARNING);
782 /* append to the functions already listed
784 setParseWithComma(&options.calleeSavesSet, cp);
790 deleteSet(&options.excludeRegsSet);
791 setParseWithComma(&options.excludeRegsSet, cp);
797 cp = get_pragma_token(cp, &token);
798 if (TOKEN_EOL != token.type)
808 cp = get_pragma_token(cp, &token);
809 if (TOKEN_EOL != token.type)
815 optimize.noLoopReverse = 1;
819 cp = get_pragma_token(cp, &token);
820 if (TOKEN_EOL != token.type)
832 cp = get_pragma_token(cp, &token);
833 if (TOKEN_INT != token.type)
838 warn = token.val.int_val;
840 cp = get_pragma_token(cp, &token);
841 if (TOKEN_EOL != token.type)
847 if (warn < MAX_ERROR_WARNING)
848 setWarningDisabled(warn);
853 cp = get_pragma_token(cp, &token);
854 if (TOKEN_EOL != token.type)
860 optimize.codeSpeed = 1;
861 optimize.codeSize = 0;
865 cp = get_pragma_token(cp, &token);
866 if (TOKEN_EOL != token.type)
872 optimize.codeSpeed = 0;
873 optimize.codeSize = 1;
876 case P_OPTCODEBALANCED:
877 cp = get_pragma_token(cp, &token);
878 if (TOKEN_EOL != token.type)
884 optimize.codeSpeed = 0;
885 optimize.codeSize = 0;
889 cp = get_pragma_token(cp, &token);
890 if (TOKEN_EOL != token.type)
897 options.std_sdcc = 0;
901 cp = get_pragma_token(cp, &token);
902 if (TOKEN_EOL != token.type)
909 options.std_sdcc = 0;
913 cp = get_pragma_token(cp, &token);
914 if (TOKEN_EOL != token.type)
921 options.std_sdcc = 1;
925 cp = get_pragma_token(cp, &token);
926 if (TOKEN_EOL != token.type)
933 options.std_sdcc = 1;
939 struct dbuf_s segname;
941 cp = get_pragma_token(cp, &token);
942 if (token.type == TOKEN_EOL)
948 dbuf_init(&segname, 16);
949 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
951 cp = get_pragma_token(cp, &token);
952 if (token.type != TOKEN_EOL)
954 dbuf_destroy(&segname);
960 options.code_seg = dbuf_detach(&segname);
962 options.const_seg = dbuf_detach(&segname);
971 get_pragma_token(cp, &token);
973 if (1 == err || (0 == err && token.type != TOKEN_EOL))
974 werror(W_BAD_PRAGMA_ARGUMENTS, name);
976 free_pragma_token(&token);
980 static struct pragma_s pragma_tbl[] = {
981 { "save", P_SAVE, 0, doPragma },
982 { "restore", P_RESTORE, 0, doPragma },
983 { "noinduction", P_NOINDUCTION, 0, doPragma },
984 { "noinvariant", P_NOINVARIANT, 0, doPragma },
985 { "noloopreverse", P_LOOPREV, 0, doPragma },
986 { "induction", P_INDUCTION, 0, doPragma },
987 { "stackauto", P_STACKAUTO, 0, doPragma },
988 { "nojtbound", P_NOJTBOUND, 0, doPragma },
989 { "nogcse", P_NOGCSE, 0, doPragma },
990 { "nooverlay", P_NOOVERLAY, 0, doPragma },
991 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
992 { "exclude", P_EXCLUDE, 0, doPragma },
993 { "noiv", P_NOIV, 0, doPragma },
994 { "overlay", P_OVERLAY_, 0, doPragma },
995 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
996 { "disable_warning",P_DISABLEWARN, 0, doPragma },
997 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
998 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
999 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1000 { "std_c89", P_STD_C89, 0, doPragma },
1001 { "std_c99", P_STD_C99, 0, doPragma },
1002 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1003 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1004 { "codeseg", P_CODESEG, 0, doPragma },
1005 { "constseg", P_CONSTSEG, 0, doPragma },
1006 { NULL, 0, 0, NULL },
1010 * returns 1 if the pragma was processed, 0 if not
1013 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1015 struct pragma_token_s token;
1019 init_pragma_token(&token);
1021 s = get_pragma_token(s, &token);
1023 /* skip separating whitespace */
1024 while ('\n' != *s && isspace((unsigned char)*s))
1027 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1029 /* now compare and do what needs to be done */
1030 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1032 if (pragma_tbl[i].deprecated != 0)
1033 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1035 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1040 free_pragma_token(&token);
1044 static int process_pragma(const char *s)
1046 struct pragma_token_s token;
1048 init_pragma_token(&token);
1050 s = get_pragma_token(s, &token);
1051 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1053 /* Oops, womething went totally wrong - internal error */
1054 wassertl(0, "pragma parser internal error");
1058 while ('\n' != *s && isspace((unsigned char)*s))
1061 /* First give the port a chance */
1062 if (port->process_pragma && port->process_pragma(s))
1065 if (process_pragma_tbl(pragma_tbl, s))
1071 werror(W_UNKNOWN_PRAGMA, s);
1076 /* will return 1 if the string is a part
1077 of a target specific keyword */
1078 static int isTargetKeyword(const char *s)
1082 if (port->keywords == NULL)
1085 if (s[0] == '_' && s[1] == '_')
1087 /* Keywords in the port's array have either 0 or 1 underscore, */
1088 /* so skip over the appropriate number of chars when comparing */
1089 for (i = 0 ; port->keywords[i] ; i++ )
1091 if (port->keywords[i][0] == '_' &&
1092 strcmp(port->keywords[i],s+1) == 0)
1094 else if (strcmp(port->keywords[i],s+2) == 0)
1100 for (i = 0 ; port->keywords[i] ; i++ )
1102 if (strcmp(port->keywords[i],s) == 0)
1112 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1113 werror(W_SAVE_RESTORE);
1118 int yyerror(char *s)
1122 if(options.vc_err_style)
1123 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1124 filename, lineno, s, yytext, column);
1126 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1127 filename, lineno, s ,yytext, column);