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 /* global definitions */
57 /* local definitions */
58 static struct dbuf_s asmbuff; /* reusable _asm buffer */
60 /* forward declarations */
61 static const char *stringLiteral(void);
62 static void count(void);
63 static void count_char(int);
64 static int process_pragma(const char *);
65 static int check_type(void);
66 static int isTargetKeyword(const char *s);
67 static int checkCurrFile(const char *s);
74 if (!options.std_sdcc && yytext[1] != '_')
76 if (asmbuff.buf == NULL)
77 dbuf_init(&asmbuff, INITIAL_INLINEASM);
79 dbuf_set_length(&asmbuff, 0);
85 if (!options.std_sdcc && yytext[1] != '_')
87 dbuf_append_str(&asmbuff, yytext);
91 yylval.yyinline = dbuf_c_str(&asmbuff);
98 dbuf_append_char(&asmbuff, *yytext);
101 dbuf_append_char(&asmbuff, *yytext);
103 "at" { count(); TKEYWORDSDCC(AT); }
104 "__at" { count(); TKEYWORD(AT); }
105 "auto" { count(); return(AUTO); }
106 "bit" { count(); TKEYWORDSDCC(BIT); }
107 "__bit" { count(); TKEYWORD(BIT); }
108 "break" { count(); return(BREAK); }
109 "case" { count(); return(CASE); }
110 "char" { count(); return(CHAR); }
111 "code" { count(); TKEYWORDSDCC(CODE); }
112 "__code" { count(); TKEYWORD(CODE); }
113 "const" { count(); return(CONST); }
114 "continue" { count(); return(CONTINUE); }
115 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
116 "__critical" { count(); TKEYWORD(CRITICAL); }
117 "data" { count(); TKEYWORDSDCC(DATA); }
118 "__data" { count(); TKEYWORD(DATA); }
119 "default" { count(); return(DEFAULT); }
120 "do" { count(); return(DO); }
121 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
122 "else" { count(); return(ELSE); }
123 "enum" { count(); return(ENUM); }
124 "extern" { count(); return(EXTERN); }
125 "far" { count(); TKEYWORDSDCC(XDATA); }
126 "__far" { count(); TKEYWORD(XDATA); }
127 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
128 "__eeprom" { count(); TKEYWORD(EEPROM); }
129 "float" { count(); return(FLOAT); }
130 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
131 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
132 "flash" { count(); TKEYWORDSDCC(CODE); }
133 "__flash" { count(); TKEYWORD(CODE); }
134 "for" { count(); return(FOR); }
135 "goto" { count(); return(GOTO); }
136 "idata" { count(); TKEYWORDSDCC(IDATA); }
137 "__idata" { count(); TKEYWORD(IDATA); }
138 "if" { count(); return(IF); }
139 "int" { count(); return(INT); }
140 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
141 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
142 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
143 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
144 "banked" { count(); TKEYWORDSDCC(BANKED); }
145 "__banked" { count(); TKEYWORD(BANKED); }
146 "long" { count(); return(LONG); }
147 "near" { count(); TKEYWORDSDCC(DATA); }
148 "__near" { count(); TKEYWORD(DATA); }
149 "pdata" { count(); TKEYWORDSDCC(PDATA); }
150 "__pdata" { count(); TKEYWORD(PDATA); }
151 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
152 "__reentrant" { count(); TKEYWORD(REENTRANT); }
153 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
154 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
155 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
156 "__wparam" { count(); TKEYWORD(WPARAM); }
157 "register" { count(); return(REGISTER); }
158 "return" { count(); return(RETURN); }
159 "sfr" { count(); TKEYWORDSDCC(SFR); }
160 "__sfr" { count(); TKEYWORD(SFR); }
161 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
162 "__sfr16" { count(); TKEYWORD(SFR16); }
163 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
164 "__sfr32" { count(); TKEYWORD(SFR32); }
165 "sbit" { count(); TKEYWORDSDCC(SBIT); }
166 "__sbit" { count(); TKEYWORD(SBIT); }
167 "short" { count(); return(SHORT); }
168 "signed" { count(); return(SIGNED); }
169 "sizeof" { count(); return(SIZEOF); }
170 "sram" { count(); TKEYWORDSDCC(XDATA); }
171 "__sram" { count(); TKEYWORD(XDATA); }
172 "static" { count(); return(STATIC); }
173 "struct" { count(); return(STRUCT); }
174 "switch" { count(); return(SWITCH); }
175 "typedef" { count(); return(TYPEDEF); }
176 "union" { count(); return(UNION); }
177 "unsigned" { count(); return(UNSIGNED); }
178 "void" { count(); return(VOID); }
179 "volatile" { count(); return(VOLATILE); }
180 "using" { count(); TKEYWORDSDCC(USING); }
181 "__using" { count(); TKEYWORD(USING); }
182 "_naked" { count(); TKEYWORDSDCC(NAKED); }
183 "__naked" { count(); TKEYWORD(NAKED); }
184 "while" { count(); return(WHILE); }
185 "xdata" { count(); TKEYWORDSDCC(XDATA); }
186 "__xdata" { count(); TKEYWORD(XDATA); }
187 "..." { count(); return(VAR_ARGS); }
188 "__typeof" { count(); return TYPEOF; }
189 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
190 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
191 "__overlay" { count(); TKEYWORD(OVERLAY); }
192 "inline" { count(); TKEYWORD99(INLINE); }
193 "restrict" { count(); TKEYWORD99(RESTRICT); }
194 {L}({L}|{D})* { count(); return(check_type()); }
195 {L_DOLL}({L_DOLL}|{D})* {
196 if (options.dollars_in_ident)
199 return(check_type());
204 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
205 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
206 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
207 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
208 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
209 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
210 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
211 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
212 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
213 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
214 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
215 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
216 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
217 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
218 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
219 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
220 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
221 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
222 ">>" { count(); return(RIGHT_OP); }
223 "<<" { count(); return(LEFT_OP); }
224 "++" { count(); return(INC_OP); }
225 "--" { count(); return(DEC_OP); }
226 "->" { count(); return(PTR_OP); }
227 "&&" { count(); return(AND_OP); }
228 "||" { count(); return(OR_OP); }
229 "<=" { count(); return(LE_OP); }
230 ">=" { count(); return(GE_OP); }
231 "==" { count(); return(EQ_OP); }
232 "!=" { count(); return(NE_OP); }
233 ";" { count(); return(';'); }
234 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
235 "}" { count(); NestLevel--; return('}'); }
236 "," { count(); return(','); }
237 ":" { count(); return(':'); }
238 "=" { count(); return('='); }
239 "(" { count(); ignoreTypedefType = 0; 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 ">" { count(); return('>'); }
254 "^" { count(); return('^'); }
255 "|" { count(); return('|'); }
256 "?" { count(); return('?'); }
257 ^#pragma.*$ { count(); process_pragma(yytext); }
258 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
260 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
261 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
264 [ \t\v\f] { count(); }
272 /* that could have been removed by the preprocessor anyway */
273 werror (W_STRAY_BACKSLASH, column);
280 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
282 #define yytext_ptr yytext
286 static int checkCurrFile (const char *s)
291 /* skip '#' character */
295 /* check if this is a #line
296 this is not standard and can be removed in the future */
297 #define LINE_STR "line"
298 #define LINE_LEN ((sizeof LINE_STR) - 1)
300 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
303 /* get the line number */
304 lNum = strtol(s, &tptr, 10);
305 if (tptr == s || !isspace((unsigned char)*tptr))
309 /* adjust the line number */
310 lineno = lexLineno = lNum;
312 /* now see if we have a file name */
313 while (*s != '"' && *s)
318 /* no file name: return */
322 /* skip the double quote */
325 /* get the file name and see if it is different from current one.
326 in c1mode fullSrcFileName is NULL */
327 if (fullSrcFileName &&
328 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
330 lexFilename = fullSrcFileName;
336 /* find the end of the file name */
337 while (*s && *s != '"')
340 lexFilename = Safe_malloc(s - sb + 1);
341 memcpy(lexFilename, sb, s - sb);
342 lexFilename[s - sb] = '\0';
344 filename = lexFilename;
349 static void count_char(int ch)
355 lineno = ++lexLineno;
359 column += 8 - (column % 8);
368 static void count(void)
372 for (p = yytext; *p; ++p)
376 static int check_type(void)
378 symbol *sym = findSym(SymbolTab, NULL, yytext);
380 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
382 /* check if it is in the table as a typedef */
383 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
384 && SPEC_TYPEDEF (sym->etype))
391 * Change by JTV 2001-05-19 to not concantenate strings
392 * to support ANSI hex and octal escape sequences in string literals
395 static const char *stringLiteral(void)
397 #define STR_BUF_CHUNCK_LEN 1024
399 static struct dbuf_s dbuf; /* reusable string literal buffer */
402 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
404 dbuf_set_length(&dbuf, 0);
406 dbuf_append_char(&dbuf, '"');
408 /* put into the buffer till we hit the first \" */
420 /* if it is a \ then escape char's are allowed */
425 /* \<newline> is a continuator */
436 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
438 break; /* carry on */
441 /* if new line we have a new line break, which is illegal */
442 werror(W_NEWLINE_IN_STRING);
443 dbuf_append_char(&dbuf, '\n');
447 /* if this is a quote then we have work to do */
448 /* find the next non whitespace character */
449 /* if that is a double quote then carry on */
450 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
451 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
457 if ((ch = input()) != '\n')
459 werror(W_STRAY_BACKSLASH, column);
476 /* # at the beginning of the line: collect the entire line */
477 struct dbuf_s linebuf;
482 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
483 dbuf_append_char(&linebuf, '#');
485 while ((ch = input()) != EOF && ch != '\n')
486 dbuf_append_char(&linebuf, (char)ch);
491 line = dbuf_c_str(&linebuf);
493 /* process the line */
494 if (startsWith(line, "#pragma"))
495 process_pragma(line);
499 dbuf_destroy(&linebuf);
523 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
528 return dbuf_c_str(&dbuf);
547 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
548 /* cross-compiling for MINGW32 with gcc 3.2 */
562 /* SAVE/RESTORE stack */
563 #define SAVE_RESTORE_SIZE 128
565 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
566 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
567 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
570 * cloneXxx functions should be updated every time a new set is
571 * added to the options or optimize structure!
574 static struct options *cloneOptions(struct options *opt)
576 struct options *new_opt;
578 new_opt = Safe_malloc(sizeof (struct options));
580 /* clone scalar values */
584 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
585 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
586 /* not implemented yet: */
587 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
592 static struct optimize *cloneOptimize(struct optimize *opt)
594 struct optimize *new_opt;
596 new_opt = Safe_malloc(sizeof (struct optimize));
598 /* clone scalar values */
604 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
606 struct SDCCERRG *new_val;
608 new_val = Safe_malloc(sizeof (struct SDCCERRG));
610 /* clone scalar values */
616 static void copyAndFreeOptions(struct options *dest, struct options *src)
618 /* delete dest sets */
619 deleteSet(&dest->calleeSavesSet);
620 deleteSet(&dest->excludeRegsSet);
621 /* not implemented yet: */
622 /* deleteSet(&dest->olaysSet); */
624 /* copy src to dest */
630 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
632 /* copy src to dest */
638 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
640 /* copy src to dest */
647 * returns 1 if the pragma was processed, 0 if not
649 static int doPragma(int id, const char *name, const char *cp)
651 struct pragma_token_s token;
655 init_pragma_token(&token);
661 cp = get_pragma_token(cp, &token);
662 if (TOKEN_EOL != token.type)
668 STACK_PUSH(options_stack, cloneOptions(&options));
669 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
670 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
676 struct options *optionsp;
677 struct optimize *optimizep;
678 struct SDCCERRG *sdccerrgp;
680 cp = get_pragma_token(cp, &token);
681 if (TOKEN_EOL != token.type)
687 optionsp = STACK_POP(options_stack);
688 copyAndFreeOptions(&options, optionsp);
690 optimizep = STACK_POP(optimize_stack);
691 copyAndFreeOptimize(&optimize, optimizep);
693 sdccerrgp = STACK_POP(SDCCERRG_stack);
694 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
699 cp = get_pragma_token(cp, &token);
700 if (TOKEN_EOL != token.type)
706 optimize.loopInduction = 0;
710 cp = get_pragma_token(cp, &token);
711 if (TOKEN_EOL != token.type)
717 optimize.loopInvariant = 0;
721 cp = get_pragma_token(cp, &token);
722 if (TOKEN_EOL != token.type)
728 optimize.loopInduction = 1;
732 cp = get_pragma_token(cp, &token);
733 if (TOKEN_EOL != token.type)
739 options.stackAuto = 1;
743 cp = get_pragma_token(cp, &token);
744 if (TOKEN_EOL != token.type)
750 optimize.noJTabBoundary = 1;
754 cp = get_pragma_token(cp, &token);
755 if (TOKEN_EOL != token.type)
761 optimize.global_cse = 0;
765 cp = get_pragma_token(cp, &token);
766 if (TOKEN_EOL != token.type)
772 options.noOverlay = 1;
776 cp = get_pragma_token(cp, &token);
777 if (TOKEN_EOL != token.type)
783 options.lessPedantic = 1;
784 setErrorLogLevel(ERROR_LEVEL_WARNING);
788 /* append to the functions already listed
790 setParseWithComma(&options.calleeSavesSet, cp);
796 deleteSet(&options.excludeRegsSet);
797 setParseWithComma(&options.excludeRegsSet, cp);
803 cp = get_pragma_token(cp, &token);
804 if (TOKEN_EOL != token.type)
814 cp = get_pragma_token(cp, &token);
815 if (TOKEN_EOL != token.type)
821 optimize.noLoopReverse = 1;
825 cp = get_pragma_token(cp, &token);
826 if (TOKEN_EOL != token.type)
838 cp = get_pragma_token(cp, &token);
839 if (TOKEN_INT != token.type)
844 warn = token.val.int_val;
846 cp = get_pragma_token(cp, &token);
847 if (TOKEN_EOL != token.type)
853 if (warn < MAX_ERROR_WARNING)
854 setWarningDisabled(warn);
859 cp = get_pragma_token(cp, &token);
860 if (TOKEN_EOL != token.type)
866 optimize.codeSpeed = 1;
867 optimize.codeSize = 0;
871 cp = get_pragma_token(cp, &token);
872 if (TOKEN_EOL != token.type)
878 optimize.codeSpeed = 0;
879 optimize.codeSize = 1;
882 case P_OPTCODEBALANCED:
883 cp = get_pragma_token(cp, &token);
884 if (TOKEN_EOL != token.type)
890 optimize.codeSpeed = 0;
891 optimize.codeSize = 0;
895 cp = get_pragma_token(cp, &token);
896 if (TOKEN_EOL != token.type)
903 options.std_sdcc = 0;
907 cp = get_pragma_token(cp, &token);
908 if (TOKEN_EOL != token.type)
915 options.std_sdcc = 0;
919 cp = get_pragma_token(cp, &token);
920 if (TOKEN_EOL != token.type)
927 options.std_sdcc = 1;
931 cp = get_pragma_token(cp, &token);
932 if (TOKEN_EOL != token.type)
939 options.std_sdcc = 1;
945 struct dbuf_s segname;
947 cp = get_pragma_token(cp, &token);
948 if (token.type == TOKEN_EOL)
954 dbuf_init(&segname, 16);
955 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
957 cp = get_pragma_token(cp, &token);
958 if (token.type != TOKEN_EOL)
960 dbuf_destroy(&segname);
966 options.code_seg = dbuf_detach(&segname);
968 options.const_seg = dbuf_detach(&segname);
977 get_pragma_token(cp, &token);
979 if (1 == err || (0 == err && token.type != TOKEN_EOL))
980 werror(W_BAD_PRAGMA_ARGUMENTS, name);
982 free_pragma_token(&token);
986 static struct pragma_s pragma_tbl[] = {
987 { "save", P_SAVE, 0, doPragma },
988 { "restore", P_RESTORE, 0, doPragma },
989 { "noinduction", P_NOINDUCTION, 0, doPragma },
990 { "noinvariant", P_NOINVARIANT, 0, doPragma },
991 { "noloopreverse", P_LOOPREV, 0, doPragma },
992 { "induction", P_INDUCTION, 0, doPragma },
993 { "stackauto", P_STACKAUTO, 0, doPragma },
994 { "nojtbound", P_NOJTBOUND, 0, doPragma },
995 { "nogcse", P_NOGCSE, 0, doPragma },
996 { "nooverlay", P_NOOVERLAY, 0, doPragma },
997 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
998 { "exclude", P_EXCLUDE, 0, doPragma },
999 { "noiv", P_NOIV, 0, doPragma },
1000 { "overlay", P_OVERLAY_, 0, doPragma },
1001 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
1002 { "disable_warning",P_DISABLEWARN, 0, doPragma },
1003 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
1004 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
1005 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1006 { "std_c89", P_STD_C89, 0, doPragma },
1007 { "std_c99", P_STD_C99, 0, doPragma },
1008 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1009 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1010 { "codeseg", P_CODESEG, 0, doPragma },
1011 { "constseg", P_CONSTSEG, 0, doPragma },
1012 { NULL, 0, 0, NULL },
1016 * returns 1 if the pragma was processed, 0 if not
1019 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1021 struct pragma_token_s token;
1025 init_pragma_token(&token);
1027 s = get_pragma_token(s, &token);
1029 /* skip separating whitespace */
1030 while ('\n' != *s && isspace((unsigned char)*s))
1033 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1035 /* now compare and do what needs to be done */
1036 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1038 if (pragma_tbl[i].deprecated != 0)
1039 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1041 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1046 free_pragma_token(&token);
1050 static int process_pragma(const char *s)
1052 struct pragma_token_s token;
1054 init_pragma_token(&token);
1056 s = get_pragma_token(s, &token);
1057 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1059 /* Oops, womething went totally wrong - internal error */
1060 wassertl(0, "pragma parser internal error");
1064 while ('\n' != *s && isspace((unsigned char)*s))
1067 /* First give the port a chance */
1068 if (port->process_pragma && port->process_pragma(s))
1071 if (process_pragma_tbl(pragma_tbl, s))
1077 werror(W_UNKNOWN_PRAGMA, s);
1082 /* will return 1 if the string is a part
1083 of a target specific keyword */
1084 static int isTargetKeyword(const char *s)
1088 if (port->keywords == NULL)
1091 if (s[0] == '_' && s[1] == '_')
1093 /* Keywords in the port's array have either 0 or 1 underscore, */
1094 /* so skip over the appropriate number of chars when comparing */
1095 for (i = 0 ; port->keywords[i] ; i++ )
1097 if (port->keywords[i][0] == '_' &&
1098 strcmp(port->keywords[i],s+1) == 0)
1100 else if (strcmp(port->keywords[i],s+2) == 0)
1106 for (i = 0 ; port->keywords[i] ; i++ )
1108 if (strcmp(port->keywords[i],s) == 0)
1118 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1119 werror(W_SAVE_RESTORE);
1124 int yyerror(char *s)
1128 if(options.vc_err_style)
1129 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1130 lexFilename, lexLineno, s, yytext, column);
1132 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1133 lexFilename, lexLineno, s ,yytext, column);