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 -------------------------------------------------------------------------*/
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 /* global definitions */
56 /* local definitions */
57 static struct dbuf_s asmbuff; /* reusable _asm buffer */
59 /* 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); }
195 if (!options.dollars_in_ident && strchr(yytext, '$'))
197 yyerror("stray '$' in program");
200 return(check_type());
202 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
203 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
204 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
205 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
206 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
207 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
208 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
209 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
210 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
211 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
212 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
213 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
214 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
215 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
216 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
217 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
218 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
219 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
220 ">>" { count(); return(RIGHT_OP); }
221 "<<" { count(); return(LEFT_OP); }
222 "++" { count(); return(INC_OP); }
223 "--" { count(); return(DEC_OP); }
224 "->" { count(); return(PTR_OP); }
225 "&&" { count(); return(AND_OP); }
226 "||" { count(); return(OR_OP); }
227 "<=" { count(); return(LE_OP); }
228 ">=" { count(); return(GE_OP); }
229 "==" { count(); return(EQ_OP); }
230 "!=" { count(); return(NE_OP); }
231 ";" { count(); return(';'); }
232 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
233 "}" { count(); NestLevel--; return('}'); }
234 "," { count(); return(','); }
235 ":" { count(); return(':'); }
236 "=" { count(); return('='); }
237 "(" { count(); ignoreTypedefType = 0; 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 "|" { count(); return('|'); }
254 "?" { count(); return('?'); }
255 ^#pragma.*$ { count(); process_pragma(yytext); }
256 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
258 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
259 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
262 [ \t\v\f] { count(); }
270 /* that could have been removed by the preprocessor anyway */
271 werror (W_STRAY_BACKSLASH, column);
278 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
280 #define yytext_ptr yytext
284 static int checkCurrFile (const char *s)
289 /* skip '#' character */
293 /* check if this is a #line
294 this is not standard and can be removed in the future */
295 #define LINE_STR "line"
296 #define LINE_LEN ((sizeof LINE_STR) - 1)
298 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
301 /* get the line number */
302 lNum = strtol(s, &tptr, 10);
303 if (tptr == s || !isspace((unsigned char)*tptr))
307 /* adjust the line number */
308 lineno = lexLineno = lNum;
310 /* now see if we have a file name */
311 while (*s != '"' && *s)
316 /* no file name: return */
320 /* skip the double quote */
323 /* get the file name and see if it is different from current one.
324 in c1mode fullSrcFileName is NULL */
325 if (fullSrcFileName &&
326 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"')
328 lexFilename = fullSrcFileName;
335 /* find the end of the file name */
336 while (*s && *s != '"')
339 tmpFname = Safe_malloc(s - sb + 1);
340 memcpy(tmpFname, sb, s - sb);
341 tmpFname[s - sb] = '\0';
343 lexFilename = Safe_malloc(s - sb + 1);
344 copyStr(lexFilename, tmpFname);
346 filename = lexFilename;
351 static void count_char(int ch)
357 lineno = ++lexLineno;
361 column += 8 - (column % 8);
370 static void count(void)
374 for (p = yytext; *p; ++p)
378 static int check_type(void)
380 symbol *sym = findSym(SymbolTab, NULL, yytext);
382 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
384 /* check if it is in the table as a typedef */
385 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
386 && SPEC_TYPEDEF (sym->etype))
393 * Change by JTV 2001-05-19 to not concantenate strings
394 * to support ANSI hex and octal escape sequences in string literals
397 static const char *stringLiteral(void)
399 #define STR_BUF_CHUNCK_LEN 1024
401 static struct dbuf_s dbuf; /* reusable string literal buffer */
404 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
406 dbuf_set_length(&dbuf, 0);
408 dbuf_append_char(&dbuf, '"');
410 /* put into the buffer till we hit the first \" */
422 /* if it is a \ then escape char's are allowed */
427 /* \<newline> is a continuator */
438 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
440 break; /* carry on */
443 /* if new line we have a new line break, which is illegal */
444 werror(W_NEWLINE_IN_STRING);
445 dbuf_append_char(&dbuf, '\n');
449 /* if this is a quote then we have work to do */
450 /* find the next non whitespace character */
451 /* if that is a double quote then carry on */
452 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
453 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
459 if ((ch = input()) != '\n')
461 werror(W_STRAY_BACKSLASH, column);
478 /* # at the beginning of the line: collect the entire line */
479 struct dbuf_s linebuf;
484 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
485 dbuf_append_char(&linebuf, '#');
487 while ((ch = input()) != EOF && ch != '\n')
488 dbuf_append_char(&linebuf, (char)ch);
493 line = dbuf_c_str(&linebuf);
495 /* process the line */
496 if (startsWith(line, "#pragma"))
497 process_pragma(line);
501 dbuf_destroy(&linebuf);
525 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
530 return dbuf_c_str(&dbuf);
549 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
550 /* cross-compiling for MINGW32 with gcc 3.2 */
564 /* SAVE/RESTORE stack */
565 #define SAVE_RESTORE_SIZE 128
567 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
568 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
569 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
572 * cloneXxx functions should be updated every time a new set is
573 * added to the options or optimize structure!
576 static struct options *cloneOptions(struct options *opt)
578 struct options *new_opt;
580 new_opt = Safe_malloc(sizeof (struct options));
582 /* clone scalar values */
586 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
587 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
588 /* not implemented yet: */
589 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
594 static struct optimize *cloneOptimize(struct optimize *opt)
596 struct optimize *new_opt;
598 new_opt = Safe_malloc(sizeof (struct optimize));
600 /* clone scalar values */
606 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
608 struct SDCCERRG *new_val;
610 new_val = Safe_malloc(sizeof (struct SDCCERRG));
612 /* clone scalar values */
618 static void copyAndFreeOptions(struct options *dest, struct options *src)
620 /* delete dest sets */
621 deleteSet(&dest->calleeSavesSet);
622 deleteSet(&dest->excludeRegsSet);
623 /* not implemented yet: */
624 /* deleteSet(&dest->olaysSet); */
626 /* copy src to dest */
632 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
634 /* copy src to dest */
640 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
642 /* copy src to dest */
649 * returns 1 if the pragma was processed, 0 if not
651 static int doPragma(int id, const char *name, const char *cp)
653 struct pragma_token_s token;
657 init_pragma_token(&token);
663 cp = get_pragma_token(cp, &token);
664 if (TOKEN_EOL != token.type)
670 STACK_PUSH(options_stack, cloneOptions(&options));
671 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
672 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
678 struct options *optionsp;
679 struct optimize *optimizep;
680 struct SDCCERRG *sdccerrgp;
682 cp = get_pragma_token(cp, &token);
683 if (TOKEN_EOL != token.type)
689 optionsp = STACK_POP(options_stack);
690 copyAndFreeOptions(&options, optionsp);
692 optimizep = STACK_POP(optimize_stack);
693 copyAndFreeOptimize(&optimize, optimizep);
695 sdccerrgp = STACK_POP(SDCCERRG_stack);
696 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
701 cp = get_pragma_token(cp, &token);
702 if (TOKEN_EOL != token.type)
708 optimize.loopInduction = 0;
712 cp = get_pragma_token(cp, &token);
713 if (TOKEN_EOL != token.type)
719 optimize.loopInvariant = 0;
723 cp = get_pragma_token(cp, &token);
724 if (TOKEN_EOL != token.type)
730 optimize.loopInduction = 1;
734 cp = get_pragma_token(cp, &token);
735 if (TOKEN_EOL != token.type)
741 options.stackAuto = 1;
745 cp = get_pragma_token(cp, &token);
746 if (TOKEN_EOL != token.type)
752 optimize.noJTabBoundary = 1;
756 cp = get_pragma_token(cp, &token);
757 if (TOKEN_EOL != token.type)
763 optimize.global_cse = 0;
767 cp = get_pragma_token(cp, &token);
768 if (TOKEN_EOL != token.type)
774 options.noOverlay = 1;
778 cp = get_pragma_token(cp, &token);
779 if (TOKEN_EOL != token.type)
785 options.lessPedantic = 1;
786 setErrorLogLevel(ERROR_LEVEL_WARNING);
790 /* append to the functions already listed
792 setParseWithComma(&options.calleeSavesSet, cp);
798 deleteSet(&options.excludeRegsSet);
799 setParseWithComma(&options.excludeRegsSet, cp);
805 cp = get_pragma_token(cp, &token);
806 if (TOKEN_EOL != token.type)
816 cp = get_pragma_token(cp, &token);
817 if (TOKEN_EOL != token.type)
823 optimize.noLoopReverse = 1;
827 cp = get_pragma_token(cp, &token);
828 if (TOKEN_EOL != token.type)
840 cp = get_pragma_token(cp, &token);
841 if (TOKEN_INT != token.type)
846 warn = token.val.int_val;
848 cp = get_pragma_token(cp, &token);
849 if (TOKEN_EOL != token.type)
855 if (warn < MAX_ERROR_WARNING)
856 setWarningDisabled(warn);
861 cp = get_pragma_token(cp, &token);
862 if (TOKEN_EOL != token.type)
868 optimize.codeSpeed = 1;
869 optimize.codeSize = 0;
873 cp = get_pragma_token(cp, &token);
874 if (TOKEN_EOL != token.type)
880 optimize.codeSpeed = 0;
881 optimize.codeSize = 1;
884 case P_OPTCODEBALANCED:
885 cp = get_pragma_token(cp, &token);
886 if (TOKEN_EOL != token.type)
892 optimize.codeSpeed = 0;
893 optimize.codeSize = 0;
897 cp = get_pragma_token(cp, &token);
898 if (TOKEN_EOL != token.type)
905 options.std_sdcc = 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 = 1;
933 cp = get_pragma_token(cp, &token);
934 if (TOKEN_EOL != token.type)
941 options.std_sdcc = 1;
947 struct dbuf_s segname;
949 cp = get_pragma_token(cp, &token);
950 if (token.type == TOKEN_EOL)
956 dbuf_init(&segname, 16);
957 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
959 cp = get_pragma_token(cp, &token);
960 if (token.type != TOKEN_EOL)
962 dbuf_destroy(&segname);
968 options.code_seg = dbuf_detach(&segname);
970 options.const_seg = dbuf_detach(&segname);
979 get_pragma_token(cp, &token);
981 if (1 == err || (0 == err && token.type != TOKEN_EOL))
982 werror(W_BAD_PRAGMA_ARGUMENTS, name);
984 free_pragma_token(&token);
988 static struct pragma_s pragma_tbl[] = {
989 { "save", P_SAVE, 0, doPragma },
990 { "restore", P_RESTORE, 0, doPragma },
991 { "noinduction", P_NOINDUCTION, 0, doPragma },
992 { "noinvariant", P_NOINVARIANT, 0, doPragma },
993 { "noloopreverse", P_LOOPREV, 0, doPragma },
994 { "induction", P_INDUCTION, 0, doPragma },
995 { "stackauto", P_STACKAUTO, 0, doPragma },
996 { "nojtbound", P_NOJTBOUND, 0, doPragma },
997 { "nogcse", P_NOGCSE, 0, doPragma },
998 { "nooverlay", P_NOOVERLAY, 0, doPragma },
999 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
1000 { "exclude", P_EXCLUDE, 0, doPragma },
1001 { "noiv", P_NOIV, 0, doPragma },
1002 { "overlay", P_OVERLAY_, 0, doPragma },
1003 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
1004 { "disable_warning",P_DISABLEWARN, 0, doPragma },
1005 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
1006 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
1007 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1008 { "std_c89", P_STD_C89, 0, doPragma },
1009 { "std_c99", P_STD_C99, 0, doPragma },
1010 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1011 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1012 { "codeseg", P_CODESEG, 0, doPragma },
1013 { "constseg", P_CONSTSEG, 0, doPragma },
1014 { NULL, 0, 0, NULL },
1018 * returns 1 if the pragma was processed, 0 if not
1021 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1023 struct pragma_token_s token;
1027 init_pragma_token(&token);
1029 s = get_pragma_token(s, &token);
1031 /* skip separating whitespace */
1032 while ('\n' != *s && isspace((unsigned char)*s))
1035 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1037 /* now compare and do what needs to be done */
1038 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1040 if (pragma_tbl[i].deprecated != 0)
1041 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1043 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1048 free_pragma_token(&token);
1052 static int process_pragma(const char *s)
1054 struct pragma_token_s token;
1056 init_pragma_token(&token);
1058 s = get_pragma_token(s, &token);
1059 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1061 /* Oops, womething went totally wrong - internal error */
1062 wassertl(0, "pragma parser internal error");
1066 while ('\n' != *s && isspace((unsigned char)*s))
1069 /* First give the port a chance */
1070 if (port->process_pragma && port->process_pragma(s))
1073 if (process_pragma_tbl(pragma_tbl, s))
1079 werror(W_UNKNOWN_PRAGMA, s);
1084 /* will return 1 if the string is a part
1085 of a target specific keyword */
1086 static int isTargetKeyword(const char *s)
1090 if (port->keywords == NULL)
1093 if (s[0] == '_' && s[1] == '_')
1095 /* Keywords in the port's array have either 0 or 1 underscore, */
1096 /* so skip over the appropriate number of chars when comparing */
1097 for (i = 0 ; port->keywords[i] ; i++ )
1099 if (port->keywords[i][0] == '_' &&
1100 strcmp(port->keywords[i],s+1) == 0)
1102 else if (strcmp(port->keywords[i],s+2) == 0)
1108 for (i = 0 ; port->keywords[i] ; i++ )
1110 if (strcmp(port->keywords[i],s) == 0)
1120 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1121 werror(W_SAVE_RESTORE);
1126 int yyerror(char *s)
1130 if(options.vc_err_style)
1131 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1132 lexFilename, lexLineno, s, yytext, column);
1134 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1135 lexFilename, lexLineno, s ,yytext, column);