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;
337 /* find the end of the file name */
338 while (*s && *s != '"')
341 tmpFname = Safe_malloc(s - sb + 1);
342 memcpy(tmpFname, sb, s - sb);
343 tmpFname[s - sb] = '\0';
345 lexFilename = Safe_malloc(s - sb + 1);
346 copyStr(lexFilename, tmpFname);
348 filename = lexFilename;
353 static void count_char(int ch)
359 lineno = ++lexLineno;
363 column += 8 - (column % 8);
372 static void count(void)
376 for (p = yytext; *p; ++p)
380 static int check_type(void)
382 symbol *sym = findSym(SymbolTab, NULL, yytext);
384 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
386 /* check if it is in the table as a typedef */
387 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
388 && SPEC_TYPEDEF (sym->etype))
395 * Change by JTV 2001-05-19 to not concantenate strings
396 * to support ANSI hex and octal escape sequences in string literals
399 static const char *stringLiteral(void)
401 #define STR_BUF_CHUNCK_LEN 1024
403 static struct dbuf_s dbuf; /* reusable string literal buffer */
406 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
408 dbuf_set_length(&dbuf, 0);
410 dbuf_append_char(&dbuf, '"');
412 /* put into the buffer till we hit the first \" */
424 /* if it is a \ then escape char's are allowed */
429 /* \<newline> is a continuator */
440 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
442 break; /* carry on */
445 /* if new line we have a new line break, which is illegal */
446 werror(W_NEWLINE_IN_STRING);
447 dbuf_append_char(&dbuf, '\n');
451 /* if this is a quote then we have work to do */
452 /* find the next non whitespace character */
453 /* if that is a double quote then carry on */
454 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
455 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
461 if ((ch = input()) != '\n')
463 werror(W_STRAY_BACKSLASH, column);
480 /* # at the beginning of the line: collect the entire line */
481 struct dbuf_s linebuf;
486 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
487 dbuf_append_char(&linebuf, '#');
489 while ((ch = input()) != EOF && ch != '\n')
490 dbuf_append_char(&linebuf, (char)ch);
495 line = dbuf_c_str(&linebuf);
497 /* process the line */
498 if (startsWith(line, "#pragma"))
499 process_pragma(line);
503 dbuf_destroy(&linebuf);
527 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
532 return dbuf_c_str(&dbuf);
551 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
552 /* cross-compiling for MINGW32 with gcc 3.2 */
566 /* SAVE/RESTORE stack */
567 #define SAVE_RESTORE_SIZE 128
569 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
570 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
571 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
574 * cloneXxx functions should be updated every time a new set is
575 * added to the options or optimize structure!
578 static struct options *cloneOptions(struct options *opt)
580 struct options *new_opt;
582 new_opt = Safe_malloc(sizeof (struct options));
584 /* clone scalar values */
588 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
589 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
590 /* not implemented yet: */
591 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
596 static struct optimize *cloneOptimize(struct optimize *opt)
598 struct optimize *new_opt;
600 new_opt = Safe_malloc(sizeof (struct optimize));
602 /* clone scalar values */
608 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
610 struct SDCCERRG *new_val;
612 new_val = Safe_malloc(sizeof (struct SDCCERRG));
614 /* clone scalar values */
620 static void copyAndFreeOptions(struct options *dest, struct options *src)
622 /* delete dest sets */
623 deleteSet(&dest->calleeSavesSet);
624 deleteSet(&dest->excludeRegsSet);
625 /* not implemented yet: */
626 /* deleteSet(&dest->olaysSet); */
628 /* copy src to dest */
634 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
636 /* copy src to dest */
642 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
644 /* copy src to dest */
651 * returns 1 if the pragma was processed, 0 if not
653 static int doPragma(int id, const char *name, const char *cp)
655 struct pragma_token_s token;
659 init_pragma_token(&token);
665 cp = get_pragma_token(cp, &token);
666 if (TOKEN_EOL != token.type)
672 STACK_PUSH(options_stack, cloneOptions(&options));
673 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
674 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
680 struct options *optionsp;
681 struct optimize *optimizep;
682 struct SDCCERRG *sdccerrgp;
684 cp = get_pragma_token(cp, &token);
685 if (TOKEN_EOL != token.type)
691 optionsp = STACK_POP(options_stack);
692 copyAndFreeOptions(&options, optionsp);
694 optimizep = STACK_POP(optimize_stack);
695 copyAndFreeOptimize(&optimize, optimizep);
697 sdccerrgp = STACK_POP(SDCCERRG_stack);
698 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
703 cp = get_pragma_token(cp, &token);
704 if (TOKEN_EOL != token.type)
710 optimize.loopInduction = 0;
714 cp = get_pragma_token(cp, &token);
715 if (TOKEN_EOL != token.type)
721 optimize.loopInvariant = 0;
725 cp = get_pragma_token(cp, &token);
726 if (TOKEN_EOL != token.type)
732 optimize.loopInduction = 1;
736 cp = get_pragma_token(cp, &token);
737 if (TOKEN_EOL != token.type)
743 options.stackAuto = 1;
747 cp = get_pragma_token(cp, &token);
748 if (TOKEN_EOL != token.type)
754 optimize.noJTabBoundary = 1;
758 cp = get_pragma_token(cp, &token);
759 if (TOKEN_EOL != token.type)
765 optimize.global_cse = 0;
769 cp = get_pragma_token(cp, &token);
770 if (TOKEN_EOL != token.type)
776 options.noOverlay = 1;
780 cp = get_pragma_token(cp, &token);
781 if (TOKEN_EOL != token.type)
787 options.lessPedantic = 1;
788 setErrorLogLevel(ERROR_LEVEL_WARNING);
792 /* append to the functions already listed
794 setParseWithComma(&options.calleeSavesSet, cp);
800 deleteSet(&options.excludeRegsSet);
801 setParseWithComma(&options.excludeRegsSet, cp);
807 cp = get_pragma_token(cp, &token);
808 if (TOKEN_EOL != token.type)
818 cp = get_pragma_token(cp, &token);
819 if (TOKEN_EOL != token.type)
825 optimize.noLoopReverse = 1;
829 cp = get_pragma_token(cp, &token);
830 if (TOKEN_EOL != token.type)
842 cp = get_pragma_token(cp, &token);
843 if (TOKEN_INT != token.type)
848 warn = token.val.int_val;
850 cp = get_pragma_token(cp, &token);
851 if (TOKEN_EOL != token.type)
857 if (warn < MAX_ERROR_WARNING)
858 setWarningDisabled(warn);
863 cp = get_pragma_token(cp, &token);
864 if (TOKEN_EOL != token.type)
870 optimize.codeSpeed = 1;
871 optimize.codeSize = 0;
875 cp = get_pragma_token(cp, &token);
876 if (TOKEN_EOL != token.type)
882 optimize.codeSpeed = 0;
883 optimize.codeSize = 1;
886 case P_OPTCODEBALANCED:
887 cp = get_pragma_token(cp, &token);
888 if (TOKEN_EOL != token.type)
894 optimize.codeSpeed = 0;
895 optimize.codeSize = 0;
899 cp = get_pragma_token(cp, &token);
900 if (TOKEN_EOL != token.type)
907 options.std_sdcc = 0;
911 cp = get_pragma_token(cp, &token);
912 if (TOKEN_EOL != token.type)
919 options.std_sdcc = 0;
923 cp = get_pragma_token(cp, &token);
924 if (TOKEN_EOL != token.type)
931 options.std_sdcc = 1;
935 cp = get_pragma_token(cp, &token);
936 if (TOKEN_EOL != token.type)
943 options.std_sdcc = 1;
949 struct dbuf_s segname;
951 cp = get_pragma_token(cp, &token);
952 if (token.type == TOKEN_EOL)
958 dbuf_init(&segname, 16);
959 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
961 cp = get_pragma_token(cp, &token);
962 if (token.type != TOKEN_EOL)
964 dbuf_destroy(&segname);
970 options.code_seg = dbuf_detach(&segname);
972 options.const_seg = dbuf_detach(&segname);
981 get_pragma_token(cp, &token);
983 if (1 == err || (0 == err && token.type != TOKEN_EOL))
984 werror(W_BAD_PRAGMA_ARGUMENTS, name);
986 free_pragma_token(&token);
990 static struct pragma_s pragma_tbl[] = {
991 { "save", P_SAVE, 0, doPragma },
992 { "restore", P_RESTORE, 0, doPragma },
993 { "noinduction", P_NOINDUCTION, 0, doPragma },
994 { "noinvariant", P_NOINVARIANT, 0, doPragma },
995 { "noloopreverse", P_LOOPREV, 0, doPragma },
996 { "induction", P_INDUCTION, 0, doPragma },
997 { "stackauto", P_STACKAUTO, 0, doPragma },
998 { "nojtbound", P_NOJTBOUND, 0, doPragma },
999 { "nogcse", P_NOGCSE, 0, doPragma },
1000 { "nooverlay", P_NOOVERLAY, 0, doPragma },
1001 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
1002 { "exclude", P_EXCLUDE, 0, doPragma },
1003 { "noiv", P_NOIV, 0, doPragma },
1004 { "overlay", P_OVERLAY_, 0, doPragma },
1005 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
1006 { "disable_warning",P_DISABLEWARN, 0, doPragma },
1007 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
1008 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
1009 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
1010 { "std_c89", P_STD_C89, 0, doPragma },
1011 { "std_c99", P_STD_C99, 0, doPragma },
1012 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
1013 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
1014 { "codeseg", P_CODESEG, 0, doPragma },
1015 { "constseg", P_CONSTSEG, 0, doPragma },
1016 { NULL, 0, 0, NULL },
1020 * returns 1 if the pragma was processed, 0 if not
1023 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1025 struct pragma_token_s token;
1029 init_pragma_token(&token);
1031 s = get_pragma_token(s, &token);
1033 /* skip separating whitespace */
1034 while ('\n' != *s && isspace((unsigned char)*s))
1037 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1039 /* now compare and do what needs to be done */
1040 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1042 if (pragma_tbl[i].deprecated != 0)
1043 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1045 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1050 free_pragma_token(&token);
1054 static int process_pragma(const char *s)
1056 struct pragma_token_s token;
1058 init_pragma_token(&token);
1060 s = get_pragma_token(s, &token);
1061 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1063 /* Oops, womething went totally wrong - internal error */
1064 wassertl(0, "pragma parser internal error");
1068 while ('\n' != *s && isspace((unsigned char)*s))
1071 /* First give the port a chance */
1072 if (port->process_pragma && port->process_pragma(s))
1075 if (process_pragma_tbl(pragma_tbl, s))
1081 werror(W_UNKNOWN_PRAGMA, s);
1086 /* will return 1 if the string is a part
1087 of a target specific keyword */
1088 static int isTargetKeyword(const char *s)
1092 if (port->keywords == NULL)
1095 if (s[0] == '_' && s[1] == '_')
1097 /* Keywords in the port's array have either 0 or 1 underscore, */
1098 /* so skip over the appropriate number of chars when comparing */
1099 for (i = 0 ; port->keywords[i] ; i++ )
1101 if (port->keywords[i][0] == '_' &&
1102 strcmp(port->keywords[i],s+1) == 0)
1104 else if (strcmp(port->keywords[i],s+2) == 0)
1110 for (i = 0 ; port->keywords[i] ; i++ )
1112 if (strcmp(port->keywords[i],s) == 0)
1122 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1123 werror(W_SAVE_RESTORE);
1128 int yyerror(char *s)
1132 if(options.vc_err_style)
1133 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1134 lexFilename, lexLineno, s, yytext, column);
1136 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1137 lexFilename, lexLineno, s ,yytext, column);