60820b75b9c19702456f7bc31ae4ec534de81d2f
[fw/sdcc] / src / SDCC.lex
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)
5   
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
9    later version.
10    
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.
15    
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.
19     
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 -------------------------------------------------------------------------*/
24
25 D       [0-9]
26 L       [a-zA-Z_]
27 H       [a-fA-F0-9]
28 E       [Ee][+-]?{D}+
29 FS      (f|F|l|L)
30 IS      (u|U|l|L)*
31
32 %{
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "common.h"
37 #include "newalloc.h"
38 #include "dbuf.h"
39
40 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
41                                 check_type())
42
43 extern int lineno, column;
44 extern char *filename;
45
46 /* global definitions */
47 char *currFname;
48 int mylineno = 1;
49
50 /* local definitions */
51 static struct dbuf_s asmbuff;
52
53 /* forward declarations */
54 static char *stringLiteral(void);
55 static void count(void);
56 static int process_pragma(char *);
57 static int check_type(void);
58 static int isTargetKeyword(char *s);
59 static int checkCurrFile(char *s);
60 %}
61
62 %x asm
63 %%
64 "_asm"         {
65   count();
66   assert(asmbuff.alloc == 0 && asmbuff.len == 0 && asmbuff.buf == NULL);
67   dbuf_init(&asmbuff, INITIAL_INLINEASM);
68   BEGIN(asm);
69 }
70 <asm>"_endasm" {
71   count();
72   yylval.yyinline = dbuf_c_str(&asmbuff);
73   dbuf_detach(&asmbuff);
74   BEGIN(INITIAL);
75   return (INLINEASM);
76 }
77 <asm>\n        {
78   count();
79   dbuf_append(&asmbuff, yytext, 1);
80 }
81 <asm>.         {
82   dbuf_append(&asmbuff, yytext, 1);
83 }
84 "at"           { count(); TKEYWORD(AT); }
85 "auto"         { count(); return(AUTO); }
86 "bit"          { count(); TKEYWORD(BIT); }
87 "break"        { count(); return(BREAK); }
88 "case"         { count(); return(CASE); }
89 "char"         { count(); return(CHAR); }
90 "code"         { count(); TKEYWORD(CODE); }
91 "const"        { count(); return(CONST); }
92 "continue"     { count(); return(CONTINUE); }
93 "critical"     { count(); TKEYWORD(CRITICAL); }
94 "data"         { count(); TKEYWORD(DATA); }
95 "default"      { count(); return(DEFAULT); }
96 "do"           { count(); return(DO); }
97 "double"       { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
98 "else"         { count(); return(ELSE); }
99 "enum"         { count(); return(ENUM); }
100 "extern"       { count(); return(EXTERN); }
101 "far"          { count(); TKEYWORD(XDATA); }
102 "eeprom"       { count(); TKEYWORD(EEPROM); }
103 "float"        { count(); return(FLOAT); }
104 "flash"        { count(); TKEYWORD(CODE); }
105 "for"          { count(); return(FOR); }
106 "goto"         { count(); return(GOTO); }
107 "idata"        { count(); TKEYWORD(IDATA); }
108 "if"           { count(); return(IF); }
109 "int"          { count(); return(INT); }
110 "interrupt"    { count(); return(INTERRUPT); }
111 "nonbanked"    { count(); TKEYWORD(NONBANKED); }
112 "banked"       { count(); TKEYWORD(BANKED); }
113 "long"         { count(); return(LONG); }
114 "near"         { count(); TKEYWORD(DATA); }
115 "pdata"        { count(); TKEYWORD(PDATA); }
116 "reentrant"    { count(); TKEYWORD(REENTRANT); }
117 "shadowregs"   { count(); TKEYWORD(SHADOWREGS); }
118 "wparam"       { count(); TKEYWORD(WPARAM); }
119 "register"     { count(); return(REGISTER); }
120 "return"       { count(); return(RETURN); }
121 "sfr"          { count(); TKEYWORD(SFR); }
122 "sbit"         { count(); TKEYWORD(SBIT); }
123 "short"        { count(); return(SHORT); }
124 "signed"       { count(); return(SIGNED); }
125 "sizeof"       { count(); return(SIZEOF); }
126 "sram"         { count(); TKEYWORD(XDATA); }
127 "static"       { count(); return(STATIC); }
128 "struct"       { count(); return(STRUCT); }
129 "switch"       { count(); return(SWITCH); }
130 "typedef"      { count(); return(TYPEDEF); }
131 "union"        { count(); return(UNION); }
132 "unsigned"     { count(); return(UNSIGNED); }
133 "void"         { count(); return(VOID); }
134 "volatile"     { count(); return(VOLATILE); }
135 "using"        { count(); TKEYWORD(USING); }
136 "_naked"       { count(); TKEYWORD(NAKED); }
137 "while"        { count(); return(WHILE); }
138 "xdata"        { count(); TKEYWORD(XDATA); }
139 "..."          { count(); return(VAR_ARGS); }
140 "__typeof"     { count(); return TYPEOF; }
141 "_JavaNative"  { count(); TKEYWORD(JAVANATIVE); }
142 "_overlay"     { count(); TKEYWORD(OVERLAY); }
143 {L}({L}|{D})*  { count(); return(check_type()); }
144 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
145 0[0-7]*{IS}?     { count(); yylval.val = constVal(yytext); return(CONSTANT); }
146 [1-9]{D}*{IS}?      { count(); yylval.val = constVal(yytext); return(CONSTANT); }
147 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
148 {D}+{E}{FS}?   { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
149 {D}*"."{D}+({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
150 {D}+"."{D}*({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
151 \"             { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
152 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
153 "<<=" { count(); yylval.yyint = LEFT_ASSIGN  ; return(LEFT_ASSIGN); }
154 "+="  { count(); yylval.yyint = ADD_ASSIGN   ; return(ADD_ASSIGN); }
155 "-="  { count(); yylval.yyint = SUB_ASSIGN   ; return(SUB_ASSIGN); }
156 "*="  { count(); yylval.yyint = MUL_ASSIGN   ; return(MUL_ASSIGN); }
157 "/="  { count(); yylval.yyint = DIV_ASSIGN   ; return(DIV_ASSIGN); }
158 "%="  { count(); yylval.yyint = MOD_ASSIGN   ; return(MOD_ASSIGN); }
159 "&="  { count(); yylval.yyint = AND_ASSIGN   ; return(AND_ASSIGN); }
160 "^="  { count(); yylval.yyint = XOR_ASSIGN   ; return(XOR_ASSIGN); }
161 "|="  { count(); yylval.yyint = OR_ASSIGN    ; return(OR_ASSIGN); }
162 ">>"           { count(); return(RIGHT_OP); }
163 "<<"           { count(); return(LEFT_OP); }
164 "++"           { count(); return(INC_OP); }
165 "--"           { count(); return(DEC_OP); }
166 "->"           { count(); return(PTR_OP); }
167 "&&"           { count(); return(AND_OP); }
168 "||"           { count(); return(OR_OP); }
169 "<="           { count(); return(LE_OP); }
170 ">="           { count(); return(GE_OP); }
171 "=="           { count(); return(EQ_OP); }
172 "!="           { count(); return(NE_OP); }
173 ";"            { count(); return(';'); }
174 "{"            { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
175 "}"            { count(); NestLevel--; return('}'); }
176 ","            { count(); return(','); }
177 ":"            { count(); return(':'); }
178 "="            { count(); return('='); }
179 "("            { count(); ignoreTypedefType = 0; return('('); }
180 ")"            { count(); return(')'); }
181 "["            { count(); return('['); }
182 "]"            { count(); return(']'); }
183 "."            { count(); return('.'); }
184 "&"            { count(); return('&'); }
185 "!"            { count(); return('!'); }
186 "~"            { count(); return('~'); }
187 "-"            { count(); return('-'); }
188 "+"            { count(); return('+'); }
189 "*"            { count(); return('*'); }
190 "/"            { count(); return('/'); }
191 "%"            { count(); return('%'); }
192 "<"            { count(); return('<'); }
193 ">"            { count(); return('>'); }
194 "^"            { count(); return('^'); }
195 "|"            { count(); return('|'); }
196 "?"            { count(); return('?'); }
197 ^#pragma.*"\n" { count(); process_pragma(yytext); }
198 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
199
200 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
201 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
202 "\r\n"         { count(); }
203 "\n"           { count(); }
204 [ \t\v\f]      { count(); }
205 \\ {
206   int ch = input();
207   if (ch != '\n') {
208     /* that could have been removed by the preprocessor anyway */
209     werror (W_STRAY_BACKSLASH, column);
210     unput(ch);
211   }
212 }
213 .              { count(); }
214 %%
215
216 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
217 #ifndef yytext_ptr
218 #define yytext_ptr yytext
219 #endif
220
221
222 static int checkCurrFile (char *s)
223 {
224     int  lNum;
225     char *tptr;
226
227     /* skip '#' character */
228     if (*s++ != '#')
229       return 0;
230
231     /* check if this is a #line
232        this is not standard and can be removed in the future */
233 #define LINE_STR  "line"
234 #define LINE_LEN  ((sizeof LINE_STR) - 1)
235
236     if (strncmp(s, LINE_STR, LINE_LEN) == 0)
237       s += LINE_LEN;
238
239     /* get the line number */
240     lNum = strtol(s, &tptr, 10);
241     if (tptr == s || !isspace(*tptr))
242       return 0;
243     s = tptr;
244
245     /* now see if we have a file name */
246     while (*s != '\"' && *s)
247       s++;
248
249     /* if we don't have a filename then */
250     /* set the current line number to   */
251     /* line number if printFlag is on   */
252     if (!*s) {
253       lineno = mylineno = lNum;
254       return 0;
255     }
256
257     /* if we have a filename then check */
258     /* if it is "standard in" if yes then */
259     /* get the currentfile name info    */
260     s++ ;
261
262     /* in c1mode fullSrcFileName is NULL */
263     if (fullSrcFileName &&
264          strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0) {
265       lineno = mylineno = lNum;
266       currFname = fullSrcFileName;
267     } else {
268         char *sb = s;
269         /* mark the end of the filename */
270         while (*s != '"') s++;
271         *s = '\0';
272         currFname = strdup (sb);
273         lineno = mylineno = lNum;
274     }
275     filename = currFname ;
276     return 0;
277 }
278
279 int column = 0;
280 int plineIdx =0;
281
282 static void count(void)
283 {
284   int i;
285   for (i = 0; yytext[i] != '\0'; i++) {
286     if (yytext[i] == '\n') {
287       column = 0;
288       lineno = ++mylineno;
289     }
290     else
291       if (yytext[i] == '\t')
292         column += 8 - (column % 8);
293       else
294         column++;
295   }
296   /* ECHO; */
297 }
298
299 static int check_type(void)
300 {
301   symbol *sym = findSym(SymbolTab, NULL, yytext);
302
303   /* check if it is in the table as a typedef */
304   if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
305       && SPEC_TYPEDEF (sym->etype)) {
306     strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
307     return (TYPE_NAME);
308   }
309   else {
310     strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX);
311     return(IDENTIFIER);
312   }
313 }
314
315 /*
316  * Change by JTV 2001-05-19 to not concantenate strings
317  * to support ANSI hex and octal escape sequences in string literals
318  */
319
320 static char *stringLiteral(void)
321 {
322 #define STR_BUF_CHUNCK_LEN  1024
323   int ch;
324   static struct dbuf_s dbuf;
325   char buf[2];
326
327   if (dbuf.alloc == 0)
328     dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
329   else
330     dbuf_set_size(&dbuf, 0);
331
332   dbuf_append(&dbuf, "\"", 1);
333   /* put into the buffer till we hit the first \" */
334
335   while ((ch = input()) != 0) {
336     switch (ch) {
337     case '\\':
338       /* if it is a \ then escape char's are allowed */
339       ch = input();
340       if (ch == '\n') {
341         /* \<newline> is a continuator */
342         lineno = ++mylineno;
343         column = 0;
344       }
345       else {
346         buf[0] = '\\';
347         buf[1] = ch;
348         dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
349       }
350       break; /* carry on */
351
352     case '\n':
353       /* if new line we have a new line break, which is illegal */
354       werror(W_NEWLINE_IN_STRING);
355       dbuf_append(&dbuf, "\n", 1);
356       lineno = ++mylineno;
357       column = 0;
358       break;
359
360     case '"':
361       /* if this is a quote then we have work to do */
362       /* find the next non whitespace character     */
363       /* if that is a double quote then carry on    */
364       dbuf_append(&dbuf, "\"", 1);  /* Pass end of this string or substring to evaluator */
365       while ((ch = input()) && (isspace(ch) || ch == '\\')) {
366         switch (ch) {
367         case '\\':
368           if ((ch = input()) != '\n') {
369             werror(W_STRAY_BACKSLASH, column);
370             unput(ch);
371           }
372           else {
373             lineno = ++mylineno;
374             column = 0;
375           }
376           break;
377
378         case '\n':
379           mylineno++;
380           break;
381         }
382       }
383
384       if (!ch)
385         goto out;
386
387       if (ch != '\"') {
388         unput(ch);
389         goto out;
390       }
391       break;
392
393     default:
394       buf[0] = ch;
395       dbuf_append(&dbuf, buf, 1);  /* Put next substring introducer into output string */
396     }
397   }
398
399 out:
400   return (char *)dbuf_c_str(&dbuf);
401 }
402
403
404 enum pragma_id {
405      P_SAVE = 1,
406      P_RESTORE,
407      P_NOINDUCTION,
408      P_NOINVARIANT,
409      P_INDUCTION,
410      P_STACKAUTO,
411      P_NOJTBOUND,
412      P_NOOVERLAY,
413      P_LESSPEDANTIC,
414      P_NOGCSE,
415      P_CALLEE_SAVES,
416      P_EXCLUDE,
417      P_NOIV,
418      P_LOOPREV,
419      P_OVERLAY_,     /* I had a strange conflict with P_OVERLAY while */
420                      /* cross-compiling for MINGW32 with gcc 3.2 */
421      P_DISABLEWARN,
422      P_OPTCODESPEED,
423      P_OPTCODESIZE,
424      P_OPTCODEBALANCED
425 };
426
427
428 /* SAVE/RESTORE stack */
429 #define SAVE_RESTORE_SIZE 128
430
431 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
432 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
433
434 /*
435  * cloneXxx functions should be updated every time a new set is
436  * added to the options or optimize structure!
437  */
438
439 static struct options *cloneOptions(struct options *opt)
440 {
441   struct options *new_opt;
442
443   new_opt = Safe_malloc(sizeof (struct options));
444
445   /* clone scalar values */
446   *new_opt = *opt;
447
448   /* clone sets */
449   new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
450   new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
451   /* not implemented yet: */
452   /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
453
454   return new_opt;
455 }
456
457 static struct optimize *cloneOptimize(struct optimize *opt)
458 {
459   struct optimize *new_opt;
460
461   new_opt = Safe_malloc(sizeof (struct options));
462
463   /* clone scalar values */
464   *new_opt = *opt;
465
466   return new_opt;
467 }
468
469 static void copyAndFreeOptions(struct options *dest, struct options *src)
470 {
471   /* delete dest sets */
472   deleteSet(&dest->calleeSavesSet);
473   deleteSet(&dest->excludeRegsSet);
474   /* not implemented yet: */
475   /* deleteSet(&dest->olaysSet); */
476
477   /* dopy src to dest */
478   *dest = *src;
479
480   Safe_free(src);
481 }
482
483 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
484 {
485   /* dopy src to dest */
486   *dest = *src;
487
488   Safe_free(src);
489 }
490
491 static void doPragma(int op, char *cp)
492 {
493   int i;
494
495   switch (op) {
496   case P_SAVE:
497     {
498       STACK_PUSH(options_stack, cloneOptions(&options));
499       STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
500     }
501     break;
502
503   case P_RESTORE:
504     {
505       struct options *optionsp;
506       struct optimize *optimizep;
507
508       optionsp = STACK_POP(options_stack);
509       copyAndFreeOptions(&options, optionsp);
510
511       optimizep = STACK_POP(optimize_stack);
512       copyAndFreeOptimize(&optimize, optimizep);
513     }
514     break;
515
516   case P_NOINDUCTION:
517     optimize.loopInduction = 0;
518     break;
519
520   case P_NOINVARIANT:
521     optimize.loopInvariant = 0;
522     break;
523
524   case P_INDUCTION:
525     optimize.loopInduction = 1;
526     break;
527
528   case P_STACKAUTO:
529     options.stackAuto = 1;
530     break;
531
532   case P_NOJTBOUND:
533     optimize.noJTabBoundary = 1;
534     break;
535
536   case P_NOGCSE:
537     optimize.global_cse = 0;
538     break;
539
540   case P_NOOVERLAY:
541     options.noOverlay = 1;
542     break;
543
544   case P_LESSPEDANTIC:
545     options.lessPedantic = 1;
546     break;
547
548   case P_CALLEE_SAVES:
549     /* append to the functions already listed
550        in callee-saves */
551     setParseWithComma(&options.calleeSavesSet, cp);
552     break;
553
554   case P_EXCLUDE:
555     {
556       deleteSet(&options.excludeRegsSet);
557       setParseWithComma(&options.excludeRegsSet, cp);
558     }
559     break;
560
561   case P_NOIV:
562     options.noiv = 1;
563     break;
564
565   case P_LOOPREV:
566     optimize.noLoopReverse = 1;
567     break;
568
569   case P_OVERLAY_:
570     break; /* notyet */
571
572   case P_DISABLEWARN:
573     if (sscanf(cp, "%d", &i) && (i<MAX_ERROR_WARNING))
574       {
575         setWarningDisabled(i);
576       }
577     break;
578   
579   case P_OPTCODESPEED:
580     optimize.codeSpeed = 1;
581     optimize.codeSize = 0;
582     break;
583
584   case P_OPTCODESIZE:
585     optimize.codeSpeed = 0;
586     optimize.codeSize = 1;
587     break;
588
589   case P_OPTCODEBALANCED:
590     optimize.codeSpeed = 0;
591     optimize.codeSize = 0;
592     break;
593
594   }
595 }
596
597 static int process_pragma(char *s)
598 {
599 #define NELEM(x)    (sizeof (x) / sizeof (x)[0])
600 #define PRAGMA_STR  "#pragma"
601 #define PRAGMA_LEN  ((sizeof PRAGMA_STR) - 1)
602
603   static struct pragma_s
604     {
605       const char *name;
606       enum pragma_id id;
607       char deprecated;
608     } pragma_tbl[] = {
609     { "save",           P_SAVE,         0 },
610     { "restore",        P_RESTORE,      0 },
611     { "noinduction",    P_NOINDUCTION,  0 },
612     { "noinvariant",    P_NOINVARIANT,  0 },
613     { "noloopreverse",  P_LOOPREV,      0 },
614     { "induction",      P_INDUCTION,    0 },
615     { "stackauto",      P_STACKAUTO,    0 },
616     { "nojtbound",      P_NOJTBOUND,    0 },
617     { "nogcse",         P_NOGCSE,       0 },
618     { "nooverlay",      P_NOOVERLAY,    0 },
619     { "callee_saves",   P_CALLEE_SAVES, 0 },
620     { "exclude",        P_EXCLUDE,      0 },
621     { "noiv",           P_NOIV,         0 },
622     { "overlay",        P_OVERLAY_,     0 },
623     { "less_pedantic",  P_LESSPEDANTIC, 0 },
624     { "disable_warning",P_DISABLEWARN,  0 },
625     { "opt_code_speed", P_OPTCODESPEED, 0 },
626     { "opt_code_size",  P_OPTCODESIZE,  0 },
627     { "opt_code_balanced",  P_OPTCODEBALANCED,  0 },
628
629     /*
630      * The following lines are deprecated pragmas,
631      * only for bacward compatibility.
632      * They should be removed in next major release after 1.4.0
633      */
634
635     { "SAVE",           P_SAVE,         1 },
636     { "RESTORE",        P_RESTORE,      1 },
637     { "NOINDUCTION",    P_NOINDUCTION,  1 },
638     { "NOINVARIANT",    P_NOINVARIANT,  1 },
639     { "NOLOOPREVERSE",  P_LOOPREV,      1 },
640     { "INDUCTION",      P_INDUCTION,    1 },
641     { "STACKAUTO",      P_STACKAUTO,    1 },
642     { "NOJTBOUND",      P_NOJTBOUND,    1 },
643     { "NOGCSE",         P_NOGCSE,       1 },
644     { "NOOVERLAY",      P_NOOVERLAY,    1 },
645     { "CALLEE-SAVES",   P_CALLEE_SAVES, 1 },
646     { "EXCLUDE",        P_EXCLUDE,      1 },
647     { "NOIV",           P_NOIV,         1 },
648     { "OVERLAY",        P_OVERLAY_,     1 },
649     { "LESS_PEDANTIC",  P_LESSPEDANTIC, 1 },
650   };
651   char *cp;
652   int i;
653
654   /* find the pragma */
655   while (strncmp(s, PRAGMA_STR, PRAGMA_LEN))
656     s++;
657   s += PRAGMA_LEN;
658
659   /* look for the directive */
660   while(isspace(*s))
661     s++;
662
663   cp = s;
664   /* look for the end of the directive */
665   while ((!isspace(*s)) && (*s != '\n'))
666     s++ ;
667
668   /* First give the port a chance */
669   if (port->process_pragma && !port->process_pragma(cp))
670     return 0;
671
672   for (i = 0; i < NELEM(pragma_tbl); i++)
673     {
674       /* now compare and do what needs to be done */
675       size_t len = strlen(pragma_tbl[i].name);
676
677       if (strncmp(cp, pragma_tbl[i].name, len) == 0)
678         {
679           if (pragma_tbl[i].deprecated != 0)
680             werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
681
682           doPragma(pragma_tbl[i].id, cp + len);
683           return 0;
684         }
685     }
686
687   werror(W_UNKNOWN_PRAGMA, cp);
688   return 0;
689 }
690
691 /* will return 1 if the string is a part
692    of a target specific keyword */
693 static int isTargetKeyword(char *s)
694 {
695   int i;
696
697   if (port->keywords == NULL)
698     return 0;
699   for (i = 0 ; port->keywords[i] ; i++ ) {
700     if (strcmp(port->keywords[i],s) == 0)
701       return 1;
702   }
703
704     return 0;
705 }
706
707 int yywrap(void)
708 {
709   if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
710     werror(W_SAVE_RESTORE);
711
712   return 1;
713 }
714
715 int yyerror(char *s)
716 {
717   fflush(stdout);
718
719   if (mylineno && filename) {
720     if(options.vc_err_style)
721       fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
722         filename, mylineno, s, yytext, column);
723     else
724       fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
725         filename, mylineno, s ,yytext, column);
726     fatalError++;
727   } else {
728     /* this comes from an empy file, no problem */
729   }
730   return 0;
731 }