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 -------------------------------------------------------------------------*/
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 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(const char *s);
64 static int checkCurrFile(const 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_str(&asmbuff, yytext);
85 yylval.yyinline = dbuf_c_str(&asmbuff);
86 dbuf_detach(&asmbuff);
93 dbuf_append_char(&asmbuff, *yytext);
96 dbuf_append_char(&asmbuff, *yytext);
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 (const 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;
317 /* find the end of the filename */
318 while (*s && *s != '"')
320 currFname = Safe_malloc(s - sb + 1);
321 memcpy(currFname, sb, s - sb);
322 currFname[s - sb] = '\0';
323 lineno = mylineno = lNum;
325 filename = currFname ;
332 static void count(void)
335 for (i = 0; yytext[i] != '\0'; i++) {
336 if (yytext[i] == '\n') {
341 if (yytext[i] == '\t')
342 column += 8 - (column % 8);
349 static int check_type(void)
351 symbol *sym = findSym(SymbolTab, NULL, yytext);
353 /* check if it is in the table as a typedef */
354 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
355 && SPEC_TYPEDEF (sym->etype)) {
356 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
360 strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX);
366 * Change by JTV 2001-05-19 to not concantenate strings
367 * to support ANSI hex and octal escape sequences in string literals
370 static char *stringLiteral(void)
372 #define STR_BUF_CHUNCK_LEN 1024
374 static struct dbuf_s dbuf;
377 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
379 dbuf_set_length(&dbuf, 0);
381 dbuf_append_char(&dbuf, '"');
382 /* put into the buffer till we hit the first \" */
384 while ((ch = input()) != 0) {
387 /* if it is a \ then escape char's are allowed */
390 /* \<newline> is a continuator */
399 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
401 break; /* carry on */
404 /* if new line we have a new line break, which is illegal */
405 werror(W_NEWLINE_IN_STRING);
406 dbuf_append_char(&dbuf, '\n');
412 /* if this is a quote then we have work to do */
413 /* find the next non whitespace character */
414 /* if that is a double quote then carry on */
415 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
416 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#')) {
419 if ((ch = input()) != '\n') {
420 werror(W_STRAY_BACKSLASH, column);
436 /* # at the beginning of the line: collect the entire line */
437 struct dbuf_s linebuf;
440 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
441 dbuf_append_char(&linebuf, '#');
443 while ((ch = input()) && ch != '\n') {
444 dbuf_append_char(&linebuf, (char)ch);
452 line = dbuf_c_str(&linebuf);
454 /* process the line */
455 if (startsWith(line, "#pragma"))
456 process_pragma(line);
460 dbuf_destroy(&linebuf);
475 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
480 return (char *)dbuf_c_str(&dbuf);
499 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
500 /* cross-compiling for MINGW32 with gcc 3.2 */
514 /* SAVE/RESTORE stack */
515 #define SAVE_RESTORE_SIZE 128
517 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
518 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
519 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
522 * cloneXxx functions should be updated every time a new set is
523 * added to the options or optimize structure!
526 static struct options *cloneOptions(struct options *opt)
528 struct options *new_opt;
530 new_opt = Safe_malloc(sizeof (struct options));
532 /* clone scalar values */
536 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
537 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
538 /* not implemented yet: */
539 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
544 static struct optimize *cloneOptimize(struct optimize *opt)
546 struct optimize *new_opt;
548 new_opt = Safe_malloc(sizeof (struct optimize));
550 /* clone scalar values */
556 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
558 struct SDCCERRG *new_val;
560 new_val = Safe_malloc(sizeof (struct SDCCERRG));
562 /* clone scalar values */
568 static void copyAndFreeOptions(struct options *dest, struct options *src)
570 /* delete dest sets */
571 deleteSet(&dest->calleeSavesSet);
572 deleteSet(&dest->excludeRegsSet);
573 /* not implemented yet: */
574 /* deleteSet(&dest->olaysSet); */
576 /* copy src to dest */
582 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
584 /* copy src to dest */
590 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
592 /* copy src to dest */
599 * returns 1 if the pragma was processed, 0 if not
601 static int doPragma(int id, const char *name, const char *cp)
603 struct pragma_token_s token;
607 init_pragma_token(&token);
613 cp = get_pragma_token(cp, &token);
614 if (TOKEN_EOL != token.type)
620 STACK_PUSH(options_stack, cloneOptions(&options));
621 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
622 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
628 struct options *optionsp;
629 struct optimize *optimizep;
630 struct SDCCERRG *sdccerrgp;
632 cp = get_pragma_token(cp, &token);
633 if (TOKEN_EOL != token.type)
639 optionsp = STACK_POP(options_stack);
640 copyAndFreeOptions(&options, optionsp);
642 optimizep = STACK_POP(optimize_stack);
643 copyAndFreeOptimize(&optimize, optimizep);
645 sdccerrgp = STACK_POP(SDCCERRG_stack);
646 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
651 cp = get_pragma_token(cp, &token);
652 if (TOKEN_EOL != token.type)
658 optimize.loopInduction = 0;
662 cp = get_pragma_token(cp, &token);
663 if (TOKEN_EOL != token.type)
669 optimize.loopInvariant = 0;
673 cp = get_pragma_token(cp, &token);
674 if (TOKEN_EOL != token.type)
680 optimize.loopInduction = 1;
684 cp = get_pragma_token(cp, &token);
685 if (TOKEN_EOL != token.type)
691 options.stackAuto = 1;
695 cp = get_pragma_token(cp, &token);
696 if (TOKEN_EOL != token.type)
702 optimize.noJTabBoundary = 1;
706 cp = get_pragma_token(cp, &token);
707 if (TOKEN_EOL != token.type)
713 optimize.global_cse = 0;
717 cp = get_pragma_token(cp, &token);
718 if (TOKEN_EOL != token.type)
724 options.noOverlay = 1;
728 cp = get_pragma_token(cp, &token);
729 if (TOKEN_EOL != token.type)
735 options.lessPedantic = 1;
736 setErrorLogLevel(ERROR_LEVEL_WARNING);
740 /* append to the functions already listed
742 setParseWithComma(&options.calleeSavesSet, cp);
748 deleteSet(&options.excludeRegsSet);
749 setParseWithComma(&options.excludeRegsSet, cp);
755 cp = get_pragma_token(cp, &token);
756 if (TOKEN_EOL != token.type)
766 cp = get_pragma_token(cp, &token);
767 if (TOKEN_EOL != token.type)
773 optimize.noLoopReverse = 1;
777 cp = get_pragma_token(cp, &token);
778 if (TOKEN_EOL != token.type)
790 cp = get_pragma_token(cp, &token);
791 if (TOKEN_INT != token.type)
796 warn = token.val.int_val;
798 cp = get_pragma_token(cp, &token);
799 if (TOKEN_EOL != token.type)
805 if (warn < MAX_ERROR_WARNING)
806 setWarningDisabled(warn);
811 cp = get_pragma_token(cp, &token);
812 if (TOKEN_EOL != token.type)
818 optimize.codeSpeed = 1;
819 optimize.codeSize = 0;
823 cp = get_pragma_token(cp, &token);
824 if (TOKEN_EOL != token.type)
830 optimize.codeSpeed = 0;
831 optimize.codeSize = 1;
834 case P_OPTCODEBALANCED:
835 cp = get_pragma_token(cp, &token);
836 if (TOKEN_EOL != token.type)
842 optimize.codeSpeed = 0;
843 optimize.codeSize = 0;
847 cp = get_pragma_token(cp, &token);
848 if (TOKEN_EOL != token.type)
855 options.std_sdcc = 0;
859 cp = get_pragma_token(cp, &token);
860 if (TOKEN_EOL != token.type)
867 options.std_sdcc = 0;
871 cp = get_pragma_token(cp, &token);
872 if (TOKEN_EOL != token.type)
879 options.std_sdcc = 1;
883 cp = get_pragma_token(cp, &token);
884 if (TOKEN_EOL != token.type)
891 options.std_sdcc = 1;
897 struct dbuf_s segname;
899 cp = get_pragma_token(cp, &token);
900 if (token.type == TOKEN_EOL)
906 dbuf_init(&segname, 16);
907 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
909 cp = get_pragma_token(cp, &token);
910 if (token.type != TOKEN_EOL)
912 dbuf_destroy(&segname);
918 options.code_seg = dbuf_detach(&segname);
920 options.const_seg = dbuf_detach(&segname);
929 get_pragma_token(cp, &token);
931 if (1 == err || (0 == err && token.type != TOKEN_EOL))
932 werror(W_BAD_PRAGMA_ARGUMENTS, name);
934 free_pragma_token(&token);
938 static struct pragma_s pragma_tbl[] = {
939 { "save", P_SAVE, 0, doPragma },
940 { "restore", P_RESTORE, 0, doPragma },
941 { "noinduction", P_NOINDUCTION, 0, doPragma },
942 { "noinvariant", P_NOINVARIANT, 0, doPragma },
943 { "noloopreverse", P_LOOPREV, 0, doPragma },
944 { "induction", P_INDUCTION, 0, doPragma },
945 { "stackauto", P_STACKAUTO, 0, doPragma },
946 { "nojtbound", P_NOJTBOUND, 0, doPragma },
947 { "nogcse", P_NOGCSE, 0, doPragma },
948 { "nooverlay", P_NOOVERLAY, 0, doPragma },
949 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
950 { "exclude", P_EXCLUDE, 0, doPragma },
951 { "noiv", P_NOIV, 0, doPragma },
952 { "overlay", P_OVERLAY_, 0, doPragma },
953 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
954 { "disable_warning",P_DISABLEWARN, 0, doPragma },
955 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
956 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
957 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
958 { "std_c89", P_STD_C89, 0, doPragma },
959 { "std_c99", P_STD_C99, 0, doPragma },
960 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
961 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
962 { "codeseg", P_CODESEG, 0, doPragma },
963 { "constseg", P_CONSTSEG, 0, doPragma },
964 { NULL, 0, 0, NULL },
968 * returns 1 if the pragma was processed, 0 if not
971 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
973 struct pragma_token_s token;
977 init_pragma_token(&token);
979 s = get_pragma_token(s, &token);
981 /* skip separating whitespace */
982 while ('\n' != *s && isspace((unsigned char)*s))
985 for (i = 0; NULL != pragma_tbl[i].name; ++i)
987 /* now compare and do what needs to be done */
988 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
990 if (pragma_tbl[i].deprecated != 0)
991 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
993 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
998 free_pragma_token(&token);
1002 static int process_pragma(const char *s)
1004 struct pragma_token_s token;
1006 init_pragma_token(&token);
1008 s = get_pragma_token(s, &token);
1009 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1011 /* Oops, womething went totally wrong - internal error */
1012 wassertl(0, "pragma parser internal error");
1016 while ('\n' != *s && isspace((unsigned char)*s))
1019 /* First give the port a chance */
1020 if (port->process_pragma && port->process_pragma(s))
1023 if (process_pragma_tbl(pragma_tbl, s))
1029 werror(W_UNKNOWN_PRAGMA, s);
1034 /* will return 1 if the string is a part
1035 of a target specific keyword */
1036 static int isTargetKeyword(const char *s)
1040 if (port->keywords == NULL)
1043 if (s[0] == '_' && s[1] == '_')
1045 /* Keywords in the port's array have either 0 or 1 underscore, */
1046 /* so skip over the appropriate number of chars when comparing */
1047 for (i = 0 ; port->keywords[i] ; i++ )
1049 if (port->keywords[i][0] == '_' &&
1050 strcmp(port->keywords[i],s+1) == 0)
1052 else if (strcmp(port->keywords[i],s+2) == 0)
1058 for (i = 0 ; port->keywords[i] ; i++ )
1060 if (strcmp(port->keywords[i],s) == 0)
1070 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1071 werror(W_SAVE_RESTORE);
1076 int yyerror(char *s)
1080 if(options.vc_err_style)
1081 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1082 filename, mylineno, s, yytext, column);
1084 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1085 filename, mylineno, s ,yytext, column);