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; /* reusable _asm buffer */
58 /* forward declarations */
59 static const 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 if (asmbuff.buf == NULL)
74 dbuf_init(&asmbuff, INITIAL_INLINEASM);
76 dbuf_set_length(&asmbuff, 0);
82 if (!options.std_sdcc && yytext[1] != '_')
84 dbuf_append_str(&asmbuff, yytext);
88 yylval.yyinline = dbuf_c_str(&asmbuff);
95 dbuf_append_char(&asmbuff, *yytext);
98 dbuf_append_char(&asmbuff, *yytext);
100 "at" { count(); TKEYWORDSDCC(AT); }
101 "__at" { count(); TKEYWORD(AT); }
102 "auto" { count(); return(AUTO); }
103 "bit" { count(); TKEYWORDSDCC(BIT); }
104 "__bit" { count(); TKEYWORD(BIT); }
105 "break" { count(); return(BREAK); }
106 "case" { count(); return(CASE); }
107 "char" { count(); return(CHAR); }
108 "code" { count(); TKEYWORDSDCC(CODE); }
109 "__code" { count(); TKEYWORD(CODE); }
110 "const" { count(); return(CONST); }
111 "continue" { count(); return(CONTINUE); }
112 "critical" { count(); TKEYWORDSDCC(CRITICAL); }
113 "__critical" { count(); TKEYWORD(CRITICAL); }
114 "data" { count(); TKEYWORDSDCC(DATA); }
115 "__data" { count(); TKEYWORD(DATA); }
116 "default" { count(); return(DEFAULT); }
117 "do" { count(); return(DO); }
118 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
119 "else" { count(); return(ELSE); }
120 "enum" { count(); return(ENUM); }
121 "extern" { count(); return(EXTERN); }
122 "far" { count(); TKEYWORDSDCC(XDATA); }
123 "__far" { count(); TKEYWORD(XDATA); }
124 "eeprom" { count(); TKEYWORDSDCC(EEPROM); }
125 "__eeprom" { count(); TKEYWORD(EEPROM); }
126 "float" { count(); return(FLOAT); }
127 "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); }
128 "__fixed16x16" { count(); TKEYWORD(FIXED16X16); }
129 "flash" { count(); TKEYWORDSDCC(CODE); }
130 "__flash" { count(); TKEYWORD(CODE); }
131 "for" { count(); return(FOR); }
132 "goto" { count(); return(GOTO); }
133 "idata" { count(); TKEYWORDSDCC(IDATA); }
134 "__idata" { count(); TKEYWORD(IDATA); }
135 "if" { count(); return(IF); }
136 "int" { count(); return(INT); }
137 "interrupt" { count(); TKEYWORDSDCC(INTERRUPT); }
138 "__interrupt" { count(); TKEYWORD(INTERRUPT); }
139 "nonbanked" { count(); TKEYWORDSDCC(NONBANKED); }
140 "__nonbanked" { count(); TKEYWORD(NONBANKED); }
141 "banked" { count(); TKEYWORDSDCC(BANKED); }
142 "__banked" { count(); TKEYWORD(BANKED); }
143 "long" { count(); return(LONG); }
144 "near" { count(); TKEYWORDSDCC(DATA); }
145 "__near" { count(); TKEYWORD(DATA); }
146 "pdata" { count(); TKEYWORDSDCC(PDATA); }
147 "__pdata" { count(); TKEYWORD(PDATA); }
148 "reentrant" { count(); TKEYWORDSDCC(REENTRANT); }
149 "__reentrant" { count(); TKEYWORD(REENTRANT); }
150 "shadowregs" { count(); TKEYWORDSDCC(SHADOWREGS); }
151 "__shadowregs" { count(); TKEYWORD(SHADOWREGS); }
152 "wparam" { count(); TKEYWORDSDCC(WPARAM); }
153 "__wparam" { count(); TKEYWORD(WPARAM); }
154 "register" { count(); return(REGISTER); }
155 "return" { count(); return(RETURN); }
156 "sfr" { count(); TKEYWORDSDCC(SFR); }
157 "__sfr" { count(); TKEYWORD(SFR); }
158 "sfr16" { count(); TKEYWORDSDCC(SFR16); }
159 "__sfr16" { count(); TKEYWORD(SFR16); }
160 "sfr32" { count(); TKEYWORDSDCC(SFR32); }
161 "__sfr32" { count(); TKEYWORD(SFR32); }
162 "sbit" { count(); TKEYWORDSDCC(SBIT); }
163 "__sbit" { count(); TKEYWORD(SBIT); }
164 "short" { count(); return(SHORT); }
165 "signed" { count(); return(SIGNED); }
166 "sizeof" { count(); return(SIZEOF); }
167 "sram" { count(); TKEYWORDSDCC(XDATA); }
168 "__sram" { count(); TKEYWORD(XDATA); }
169 "static" { count(); return(STATIC); }
170 "struct" { count(); return(STRUCT); }
171 "switch" { count(); return(SWITCH); }
172 "typedef" { count(); return(TYPEDEF); }
173 "union" { count(); return(UNION); }
174 "unsigned" { count(); return(UNSIGNED); }
175 "void" { count(); return(VOID); }
176 "volatile" { count(); return(VOLATILE); }
177 "using" { count(); TKEYWORDSDCC(USING); }
178 "__using" { count(); TKEYWORD(USING); }
179 "_naked" { count(); TKEYWORDSDCC(NAKED); }
180 "__naked" { count(); TKEYWORD(NAKED); }
181 "while" { count(); return(WHILE); }
182 "xdata" { count(); TKEYWORDSDCC(XDATA); }
183 "__xdata" { count(); TKEYWORD(XDATA); }
184 "..." { count(); return(VAR_ARGS); }
185 "__typeof" { count(); return TYPEOF; }
186 "_JavaNative" { count(); TKEYWORD(JAVANATIVE); }
187 "_overlay" { count(); TKEYWORDSDCC(OVERLAY); }
188 "__overlay" { count(); TKEYWORD(OVERLAY); }
189 "inline" { count(); TKEYWORD99(INLINE); }
190 "restrict" { count(); TKEYWORD99(RESTRICT); }
191 {L}({L}|{D})* { count(); return(check_type()); }
192 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
193 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
194 [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
195 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
196 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
197 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
198 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
199 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
200 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
201 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); }
202 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); }
203 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); }
204 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); }
205 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); }
206 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); }
207 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); }
208 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); }
209 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); }
210 ">>" { count(); return(RIGHT_OP); }
211 "<<" { count(); return(LEFT_OP); }
212 "++" { count(); return(INC_OP); }
213 "--" { count(); return(DEC_OP); }
214 "->" { count(); return(PTR_OP); }
215 "&&" { count(); return(AND_OP); }
216 "||" { count(); return(OR_OP); }
217 "<=" { count(); return(LE_OP); }
218 ">=" { count(); return(GE_OP); }
219 "==" { count(); return(EQ_OP); }
220 "!=" { count(); return(NE_OP); }
221 ";" { count(); return(';'); }
222 "{" { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
223 "}" { count(); NestLevel--; return('}'); }
224 "," { count(); return(','); }
225 ":" { count(); return(':'); }
226 "=" { count(); return('='); }
227 "(" { count(); ignoreTypedefType = 0; 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 "|" { count(); return('|'); }
244 "?" { count(); return('?'); }
245 ^#pragma.*$ { count(); process_pragma(yytext); }
246 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
248 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
249 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
252 [ \t\v\f] { count(); }
258 /* that could have been removed by the preprocessor anyway */
259 werror (W_STRAY_BACKSLASH, column);
267 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
269 #define yytext_ptr yytext
273 static int checkCurrFile (const char *s)
278 /* skip '#' character */
282 /* check if this is a #line
283 this is not standard and can be removed in the future */
284 #define LINE_STR "line"
285 #define LINE_LEN ((sizeof LINE_STR) - 1)
287 if (strncmp(s, LINE_STR, LINE_LEN) == 0)
290 /* get the line number */
291 lNum = strtol(s, &tptr, 10);
292 if (tptr == s || !isspace((unsigned char)*tptr))
296 /* now see if we have a file name */
297 while (*s != '"' && *s)
300 /* if we don't have a filename then */
301 /* set the current line number to */
302 /* line number if printFlag is on */
304 lineno = mylineno = lNum;
308 /* if we have a filename then check */
309 /* if it is "standard in" if yes then */
310 /* get the currentfile name info */
313 /* in c1mode fullSrcFileName is NULL */
314 if (fullSrcFileName &&
315 strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0)
317 lineno = mylineno = lNum;
318 currFname = fullSrcFileName;
324 /* find the end of the filename */
325 while (*s && *s != '"')
327 currFname = Safe_malloc(s - sb + 1);
328 memcpy(currFname, sb, s - sb);
329 currFname[s - sb] = '\0';
330 lineno = mylineno = lNum;
332 filename = currFname;
339 static void count(void)
342 for (i = 0; yytext[i] != '\0'; i++)
344 if (yytext[i] == '\n')
350 if (yytext[i] == '\t')
351 column += 8 - (column % 8);
358 static int check_type(void)
360 symbol *sym = findSym(SymbolTab, NULL, yytext);
362 strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
364 /* check if it is in the table as a typedef */
365 if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
366 && SPEC_TYPEDEF (sym->etype))
373 * Change by JTV 2001-05-19 to not concantenate strings
374 * to support ANSI hex and octal escape sequences in string literals
377 static const char *stringLiteral(void)
379 #define STR_BUF_CHUNCK_LEN 1024
381 static struct dbuf_s dbuf; /* reusable string literal buffer */
384 dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
386 dbuf_set_length(&dbuf, 0);
388 dbuf_append_char(&dbuf, '"');
390 /* put into the buffer till we hit the first \" */
402 /* if it is a \ then escape char's are allowed */
403 if ((ch = input()) == '\n')
405 /* \<newline> is a continuator */
419 dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
421 break; /* carry on */
424 /* if new line we have a new line break, which is illegal */
425 werror(W_NEWLINE_IN_STRING);
426 dbuf_append_char(&dbuf, '\n');
432 /* if this is a quote then we have work to do */
433 /* find the next non whitespace character */
434 /* if that is a double quote then carry on */
435 dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */
436 while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#'))
443 if ((ch = input()) != '\n')
446 werror(W_STRAY_BACKSLASH, column);
468 /* # at the beginning of the line: collect the entire line */
469 struct dbuf_s linebuf;
472 dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN);
473 dbuf_append_char(&linebuf, '#');
475 while ((ch = input()) != EOF && ch != '\n')
476 dbuf_append_char(&linebuf, (char)ch);
484 line = dbuf_c_str(&linebuf);
486 /* process the line */
487 if (startsWith(line, "#pragma"))
488 process_pragma(line);
492 dbuf_destroy(&linebuf);
509 dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */
514 return dbuf_c_str(&dbuf);
533 P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */
534 /* cross-compiling for MINGW32 with gcc 3.2 */
548 /* SAVE/RESTORE stack */
549 #define SAVE_RESTORE_SIZE 128
551 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
552 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
553 STACK_DCL(SDCCERRG_stack, struct SDCCERRG *, SAVE_RESTORE_SIZE)
556 * cloneXxx functions should be updated every time a new set is
557 * added to the options or optimize structure!
560 static struct options *cloneOptions(struct options *opt)
562 struct options *new_opt;
564 new_opt = Safe_malloc(sizeof (struct options));
566 /* clone scalar values */
570 new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
571 new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
572 /* not implemented yet: */
573 /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
578 static struct optimize *cloneOptimize(struct optimize *opt)
580 struct optimize *new_opt;
582 new_opt = Safe_malloc(sizeof (struct optimize));
584 /* clone scalar values */
590 static struct SDCCERRG *cloneSDCCERRG (struct SDCCERRG *val)
592 struct SDCCERRG *new_val;
594 new_val = Safe_malloc(sizeof (struct SDCCERRG));
596 /* clone scalar values */
602 static void copyAndFreeOptions(struct options *dest, struct options *src)
604 /* delete dest sets */
605 deleteSet(&dest->calleeSavesSet);
606 deleteSet(&dest->excludeRegsSet);
607 /* not implemented yet: */
608 /* deleteSet(&dest->olaysSet); */
610 /* copy src to dest */
616 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
618 /* copy src to dest */
624 static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
626 /* copy src to dest */
633 * returns 1 if the pragma was processed, 0 if not
635 static int doPragma(int id, const char *name, const char *cp)
637 struct pragma_token_s token;
641 init_pragma_token(&token);
647 cp = get_pragma_token(cp, &token);
648 if (TOKEN_EOL != token.type)
654 STACK_PUSH(options_stack, cloneOptions(&options));
655 STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
656 STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
662 struct options *optionsp;
663 struct optimize *optimizep;
664 struct SDCCERRG *sdccerrgp;
666 cp = get_pragma_token(cp, &token);
667 if (TOKEN_EOL != token.type)
673 optionsp = STACK_POP(options_stack);
674 copyAndFreeOptions(&options, optionsp);
676 optimizep = STACK_POP(optimize_stack);
677 copyAndFreeOptimize(&optimize, optimizep);
679 sdccerrgp = STACK_POP(SDCCERRG_stack);
680 copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
685 cp = get_pragma_token(cp, &token);
686 if (TOKEN_EOL != token.type)
692 optimize.loopInduction = 0;
696 cp = get_pragma_token(cp, &token);
697 if (TOKEN_EOL != token.type)
703 optimize.loopInvariant = 0;
707 cp = get_pragma_token(cp, &token);
708 if (TOKEN_EOL != token.type)
714 optimize.loopInduction = 1;
718 cp = get_pragma_token(cp, &token);
719 if (TOKEN_EOL != token.type)
725 options.stackAuto = 1;
729 cp = get_pragma_token(cp, &token);
730 if (TOKEN_EOL != token.type)
736 optimize.noJTabBoundary = 1;
740 cp = get_pragma_token(cp, &token);
741 if (TOKEN_EOL != token.type)
747 optimize.global_cse = 0;
751 cp = get_pragma_token(cp, &token);
752 if (TOKEN_EOL != token.type)
758 options.noOverlay = 1;
762 cp = get_pragma_token(cp, &token);
763 if (TOKEN_EOL != token.type)
769 options.lessPedantic = 1;
770 setErrorLogLevel(ERROR_LEVEL_WARNING);
774 /* append to the functions already listed
776 setParseWithComma(&options.calleeSavesSet, cp);
782 deleteSet(&options.excludeRegsSet);
783 setParseWithComma(&options.excludeRegsSet, cp);
789 cp = get_pragma_token(cp, &token);
790 if (TOKEN_EOL != token.type)
800 cp = get_pragma_token(cp, &token);
801 if (TOKEN_EOL != token.type)
807 optimize.noLoopReverse = 1;
811 cp = get_pragma_token(cp, &token);
812 if (TOKEN_EOL != token.type)
824 cp = get_pragma_token(cp, &token);
825 if (TOKEN_INT != token.type)
830 warn = token.val.int_val;
832 cp = get_pragma_token(cp, &token);
833 if (TOKEN_EOL != token.type)
839 if (warn < MAX_ERROR_WARNING)
840 setWarningDisabled(warn);
845 cp = get_pragma_token(cp, &token);
846 if (TOKEN_EOL != token.type)
852 optimize.codeSpeed = 1;
853 optimize.codeSize = 0;
857 cp = get_pragma_token(cp, &token);
858 if (TOKEN_EOL != token.type)
864 optimize.codeSpeed = 0;
865 optimize.codeSize = 1;
868 case P_OPTCODEBALANCED:
869 cp = get_pragma_token(cp, &token);
870 if (TOKEN_EOL != token.type)
876 optimize.codeSpeed = 0;
877 optimize.codeSize = 0;
881 cp = get_pragma_token(cp, &token);
882 if (TOKEN_EOL != token.type)
889 options.std_sdcc = 0;
893 cp = get_pragma_token(cp, &token);
894 if (TOKEN_EOL != token.type)
901 options.std_sdcc = 0;
905 cp = get_pragma_token(cp, &token);
906 if (TOKEN_EOL != token.type)
913 options.std_sdcc = 1;
917 cp = get_pragma_token(cp, &token);
918 if (TOKEN_EOL != token.type)
925 options.std_sdcc = 1;
931 struct dbuf_s segname;
933 cp = get_pragma_token(cp, &token);
934 if (token.type == TOKEN_EOL)
940 dbuf_init(&segname, 16);
941 dbuf_printf(&segname, "%-8s(CODE)", get_pragma_string(&token));
943 cp = get_pragma_token(cp, &token);
944 if (token.type != TOKEN_EOL)
946 dbuf_destroy(&segname);
952 options.code_seg = dbuf_detach(&segname);
954 options.const_seg = dbuf_detach(&segname);
963 get_pragma_token(cp, &token);
965 if (1 == err || (0 == err && token.type != TOKEN_EOL))
966 werror(W_BAD_PRAGMA_ARGUMENTS, name);
968 free_pragma_token(&token);
972 static struct pragma_s pragma_tbl[] = {
973 { "save", P_SAVE, 0, doPragma },
974 { "restore", P_RESTORE, 0, doPragma },
975 { "noinduction", P_NOINDUCTION, 0, doPragma },
976 { "noinvariant", P_NOINVARIANT, 0, doPragma },
977 { "noloopreverse", P_LOOPREV, 0, doPragma },
978 { "induction", P_INDUCTION, 0, doPragma },
979 { "stackauto", P_STACKAUTO, 0, doPragma },
980 { "nojtbound", P_NOJTBOUND, 0, doPragma },
981 { "nogcse", P_NOGCSE, 0, doPragma },
982 { "nooverlay", P_NOOVERLAY, 0, doPragma },
983 { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
984 { "exclude", P_EXCLUDE, 0, doPragma },
985 { "noiv", P_NOIV, 0, doPragma },
986 { "overlay", P_OVERLAY_, 0, doPragma },
987 { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
988 { "disable_warning",P_DISABLEWARN, 0, doPragma },
989 { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
990 { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
991 { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
992 { "std_c89", P_STD_C89, 0, doPragma },
993 { "std_c99", P_STD_C99, 0, doPragma },
994 { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
995 { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
996 { "codeseg", P_CODESEG, 0, doPragma },
997 { "constseg", P_CONSTSEG, 0, doPragma },
998 { NULL, 0, 0, NULL },
1002 * returns 1 if the pragma was processed, 0 if not
1005 process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
1007 struct pragma_token_s token;
1011 init_pragma_token(&token);
1013 s = get_pragma_token(s, &token);
1015 /* skip separating whitespace */
1016 while ('\n' != *s && isspace((unsigned char)*s))
1019 for (i = 0; NULL != pragma_tbl[i].name; ++i)
1021 /* now compare and do what needs to be done */
1022 if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
1024 if (pragma_tbl[i].deprecated != 0)
1025 werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
1027 ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
1032 free_pragma_token(&token);
1036 static int process_pragma(const char *s)
1038 struct pragma_token_s token;
1040 init_pragma_token(&token);
1042 s = get_pragma_token(s, &token);
1043 if (0 != strcmp("#pragma", get_pragma_string(&token)))
1045 /* Oops, womething went totally wrong - internal error */
1046 wassertl(0, "pragma parser internal error");
1050 while ('\n' != *s && isspace((unsigned char)*s))
1053 /* First give the port a chance */
1054 if (port->process_pragma && port->process_pragma(s))
1057 if (process_pragma_tbl(pragma_tbl, s))
1063 werror(W_UNKNOWN_PRAGMA, s);
1068 /* will return 1 if the string is a part
1069 of a target specific keyword */
1070 static int isTargetKeyword(const char *s)
1074 if (port->keywords == NULL)
1077 if (s[0] == '_' && s[1] == '_')
1079 /* Keywords in the port's array have either 0 or 1 underscore, */
1080 /* so skip over the appropriate number of chars when comparing */
1081 for (i = 0 ; port->keywords[i] ; i++ )
1083 if (port->keywords[i][0] == '_' &&
1084 strcmp(port->keywords[i],s+1) == 0)
1086 else if (strcmp(port->keywords[i],s+2) == 0)
1092 for (i = 0 ; port->keywords[i] ; i++ )
1094 if (strcmp(port->keywords[i],s) == 0)
1104 if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
1105 werror(W_SAVE_RESTORE);
1110 int yyerror(char *s)
1114 if(options.vc_err_style)
1115 fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
1116 filename, mylineno, s, yytext, column);
1118 fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
1119 filename, mylineno, s ,yytext, column);