Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20110603154245

Diff

Diff from 1.50 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cpp/scanner.l

Annotated File View

ragge
1.1
1 %{
plunky
1.50
2 /*      $Id: scanner.l,v 1.50 2011/06/03 15:42:45 plunky Exp $   */
ragge
1.1
3
4 /*
5  * Copyright (c) 2004 Anders Magnusson. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
gmcgarry
1.38
30 #include "config.h"
31
ragge
1.1
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
gmcgarry
1.38
35 #ifdef HAVE_UNISTD_H
ragge
1.1
36 #include <unistd.h>
gmcgarry
1.38
37 #endif
ragge
1.1
38 #include <fcntl.h>
ragge
1.30
39 #include <errno.h>
ragge
1.1
40
gmcgarry
1.38
41 #include "compat.h"
ragge
1.1
42 #include "cpp.h"
43 #include "y.tab.h"
44 %}
45
46 %{
ragge
1.25
47 static void cvtdig(int rad);
ragge
1.42
48 static int charcon(usch *);
ragge
1.1
49 static void elsestmt(void);
50 static void ifdefstmt(void);
51 static void ifndefstmt(void);
52 static void endifstmt(void);
53 static void ifstmt(void);
54 static void cpperror(void);
55 static void pragmastmt(void);
56 static void undefstmt(void);
57 static void cpperror(void);
58 static void elifstmt(void);
ragge
1.7
59 static void storepb(void);
stefan
1.27
60 static void badop(const char *);
ragge
1.1
61 void  include(void);
62 void  define(void);
63
ragge
1.18
64 extern int yyget_lineno (void);
65 extern void yyset_lineno (int);
66
ragge
1.1
67 static int inch(void);
68
ragge
1.13
69 static int scale, gotdef, contr;
ragge
1.7
70 int inif;
ragge
1.1
71
72 #ifdef FLEX_SCANNER /* should be set by autoconf instead */
73 static int
74 yyinput(char *b, int m)
75 {
76         int c, i;
77
78         for (i = 0; i < m; i++) {
79                 if ((c = inch()) < 0)
80                         break;
81                 *b++ = c;
82                 if (c == '\n') {
83                         i++;
84                         break;
85                 }
86         }
87         return i;
88 }
89 #undef YY_INPUT
ragge
1.13
90 #undef YY_BUF_SIZE
ragge
1.45
91 #define YY_BUF_SIZE (8*65536)
ragge
1.1
92 #define YY_INPUT(b,r,m) (r = yyinput(b, m))
gmcgarry
1.38
93 #ifdef HAVE_CPP_VARARG_MACRO_GCC
ragge
1.2
94 #define fprintf(x, ...) error(__VA_ARGS__)
gmcgarry
1.38
95 #endif
ragge
1.6
96 #define ECHO putstr((usch *)yytext)
ragge
1.3
97 #undef fileno
ragge
1.2
98 #define fileno(x) 0
99
100 #if YY_FLEX_SUBMINOR_VERSION >= 31
ragge
1.40
101 /* Hack to avoid unnecessary warnings */
ragge
1.2
102 FILE *yyget_in  (void);
103 FILE *yyget_out  (void);
104 int yyget_leng  (void);
105 char *yyget_text  (void);
106 void yyset_in (FILE *  in_str );
107 void yyset_out (FILE *  out_str );
108 int yyget_debug  (void);
109 void yyset_debug (int  bdebug );
110 int yylex_destroy  (void);
111 #endif
ragge
1.1
112 #else   /* Assume lex here */
113 #undef input
114 #undef unput
115 #define input() inch()
116 #define unput(ch) unch(ch)
117 #endif
ragge
1.6
118 #define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
ragge
1.30
119 /* protection against recursion in #include */
120 #define MAX_INCLEVEL    100
121 static int inclevel;
ragge
1.1
122 %}
123
124 D       [0-9]
125 L       [a-zA-Z_]
126 H       [a-fA-F0-9]
127 E       [Ee][+-]?{D}+
128 FS      (f|F|l|L)
129 IS      (u|U|l|L)*
130 WS      [\t ]
131
ragge
1.36
132 %s IFR CONTR DEF COMMENT
ragge
1.1
133
134 %%
135
136 "\n"                    {       int os = YYSTATE;
ragge
1.7
137                                 if (os != IFR)
138                                         BEGIN 0;
ragge
1.1
139                                 ifiles->lineno++;
140                                 if (flslvl == 0) {
ragge
1.2
141                                         if (ifiles->lineno == 1)
ragge
1.1
142                                                 prtline();
143                                         else
144                                                 putch('\n');
145                                 }
ragge
1.13
146                                 if ((os != 0 || slow) && !contr)
ragge
1.1
147                                         return '\n';
ragge
1.13
148                                 contr = 0;
ragge
1.1
149                         }
150
ragge
1.10
151 "\r"                    { ; /* Ignore CR's */ }
152
stefan
1.27
153 <IFR>"++"               { badop("++"); }
154 <IFR>"--"               { badop("--"); }
ragge
1.1
155 <IFR>"=="               { return EQ; }
156 <IFR>"!="               { return NE; }
157 <IFR>"<="               { return LE; }
158 <IFR>"<<"               { return LS; }
159 <IFR>">>"               { return RS; }
160 <IFR>">="               { return GE; }
161 <IFR>"||"               { return OROR; }
162 <IFR>"&&"               { return ANDAND; }
ragge
1.2
163 <IFR>"defined"          {       int p, c;
ragge
1.7
164                                 gotdef = 1;
ragge
1.2
165                                 if ((p = c = yylex()) == '(')
166                                         c = yylex();
167                                 if (c != IDENT || (p != IDENT && p != '('))
168                                         error("syntax error");
169                                 if (p == '(' && yylex() != ')')
170                                         error("syntax error");
ragge
1.7
171                                 return NUMBER;
ragge
1.2
172                         }
173
ragge
1.1
174 <IFR>{WS}+              { ; }
ragge
1.2
175 <IFR>{L}({L}|{D})*      {
ragge
1.25
176                                 yylval.node.op = NUMBER;
ragge
1.7
177                                 if (gotdef) {
ragge
1.25
178                                         yylval.node.nd_val
179                                             = lookup((usch *)yytext, FIND) != 0;
ragge
1.7
180                                         gotdef = 0;
ragge
1.2
181                                         return IDENT;
182                                 }
ragge
1.25
183                                 yylval.node.nd_val = 0;
ragge
1.7
184                                 return NUMBER;
ragge
1.2
185                         }
ragge
1.1
186
ragge
1.41
187 [0-9][0-9]*             {
188                                 if (slow && !YYSTATE)
189                                         return IDENT;
190                                 scale = yytext[0] == '0' ? 8 : 10;
191                                 goto num;
192                         }
ragge
1.13
193
ragge
1.2
194 0[xX]{H}+{IS}?          {       scale = 16;
ragge
1.29
195                         num:    if (YYSTATE == IFR) 
ragge
1.25
196                                         cvtdig(scale);
ragge
1.1
197                                 PRTOUT(NUMBER);
198                         }
199 0{D}+{IS}?              { scale = 8; goto num; }
200 {D}+{IS}?               { scale = 10; goto num; }
ragge
1.42
201 '(\\.|[^\\'])+'         {
202                                 if (YYSTATE || slow) {
ragge
1.25
203                                         yylval.node.op = NUMBER;
gmcgarry
1.43
204                                         yylval.node.nd_val = charcon((usch *)yytext);
ragge
1.42
205                                         return (NUMBER);
otto
1.24
206                                 }
ragge
1.42
207                                 if (tflag)
208                                         yyless(1);
209                                 if (!flslvl)
210                                         putstr((usch *)yytext);
ragge
1.1
211                         }
212
213 <IFR>.                  { return yytext[0]; }
214
215 {D}+{E}{FS}?            { PRTOUT(FPOINT); }
216 {D}*"."{D}+({E})?{FS}?  { PRTOUT(FPOINT); }
217 {D}+"."{D}*({E})?{FS}?  { PRTOUT(FPOINT); }
218
ragge
1.32
219 ^{WS}*#{WS}*            {       extern int inmac;
220
221                                 if (inmac)
222                                         error("preprocessor directive found "
223                                             "while expanding macro");
224                                 contr = 1;
225                                 BEGIN CONTR;
226                         }
ragge
1.1
227 {WS}+                   { PRTOUT(WSPACE); }
228
ragge
1.13
229 <CONTR>"ifndef"         { contr = 0; ifndefstmt(); }
230 <CONTR>"ifdef"          { contr = 0; ifdefstmt(); }
ragge
1.16
231 <CONTR>"if"             { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; }
ragge
1.13
232 <CONTR>"include"        { contr = 0; BEGIN 0; include(); prtline(); }
233 <CONTR>"else"           { contr = 0; elsestmt(); }
234 <CONTR>"endif"          { contr = 0; endifstmt(); }
235 <CONTR>"error"          { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; }
236 <CONTR>"define"         { contr = 0; BEGIN DEF; define(); BEGIN 0; }
237 <CONTR>"undef"          { contr = 0; if (slow) return IDENT; undefstmt(); }
238 <CONTR>"line"           { contr = 0; storepb(); BEGIN 0; line(); }
ragge
1.21
239 <CONTR>"pragma"         { contr = 0; pragmastmt(); BEGIN 0; }
ragge
1.16
240 <CONTR>"elif"           { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; }
ragge
1.1
241
242
243
244 "//".*$                 { /* if (tflag) yyless(..) */
ragge
1.36
245                                 if (Cflag && !flslvl && !slow)
ragge
1.6
246                                         putstr((usch *)yytext);
ragge
1.2
247                                 else if (!flslvl)
ragge
1.1
248                                         putch(' ');
249                         }
ragge
1.8
250 "/*"                    {       int c, wrn;
ragge
1.36
251                                 int prtcm = Cflag && !flslvl && !slow;
252                                 extern int readmac;
253
254                                 if (Cflag && !flslvl && readmac)
255                                         return CMNT;
256
257                                 if (prtcm)
ragge
1.6
258                                         putstr((usch *)yytext);
ragge
1.8
259                                 wrn = 0;
ragge
1.1
260                         more:   while ((c = input()) && c != '*') {
261                                         if (c == '\n')
262                                                 putch(c), ifiles->lineno++;
ragge
1.8
263                                         else if (c == 1) /* WARN */
264                                                 wrn = 1;
ragge
1.36
265                                         else if (prtcm)
ragge
1.1
266                                                 putch(c);
267                                 }
268                                 if (c == 0)
269                                         return 0;
ragge
1.36
270                                 if (prtcm)
ragge
1.1
271                                         putch(c);
272                                 if ((c = input()) && c != '/') {
273                                         unput(c);
274                                         goto more;
275                                 }
ragge
1.36
276                                 if (prtcm)
ragge
1.1
277                                         putch(c);
278                                 if (c == 0)
279                                         return 0;
ragge
1.2
280                                 if (!tflag && !Cflag && !flslvl)
ragge
1.1
281                                         unput(' ');
ragge
1.8
282                                 if (wrn)
283                                         unput(1);
ragge
1.1
284                         }
285
286 <DEF>"##"               { return CONCAT; }
287 <DEF>"#"                { return MKSTR; }
288 <DEF>"..."              { return ELLIPS; }
ragge
1.2
289 <DEF>"__VA_ARGS__"      { return VA_ARGS; }
ragge
1.1
290
291 L?\"(\\.|[^\\"])*\"     { PRTOUT(STRING); }
ragge
1.12
292 [a-zA-Z_0-9]+           { /* {L}({L}|{D})* */
ragge
1.1
293                                 struct symtab *nl;
294                                 if (slow)
295                                         return IDENT;
ragge
1.9
296                                 if (YYSTATE == CONTR) {
ragge
1.13
297                                         if (flslvl == 0) {
298                                                 /*error("undefined control");*/
299                                                 while (input() != '\n')
300                                                         ;
301                                                 unput('\n');
302                                                 BEGIN 0;
303                                                 goto xx;
304                                         } else {
ragge
1.9
305                                                 BEGIN 0; /* do nothing */
ragge
1.13
306                                         }
ragge
1.9
307                                 }
308                                 if (flslvl) {
ragge
1.1
309                                         ; /* do nothing */
ragge
1.12
310                                 } else if (isdigit((int)yytext[0]) == 0 &&
311                                     (nl = lookup((usch *)yytext, FIND)) != 0) {
ragge
1.2
312                                         usch *op = stringbuf;
313                                         putstr(gotident(nl));
314                                         stringbuf = op;
ragge
1.1
315                                 } else
ragge
1.6
316                                         putstr((usch *)yytext);
ragge
1.13
317                                 xx: ;
ragge
1.1
318                         }
319
ragge
1.46
320 .                       {
ragge
1.47
321                                 if (contr) {
322                                         while (input() != '\n')
323                                                 ;
324                                         unput('\n');
325                                         BEGIN 0;
326                                         contr = 0;
327                                         goto yy;
328                                 }
ragge
1.46
329                                 if (YYSTATE || slow)
330                                         return yytext[0];
331                                 if (yytext[0] == 6) { /* PRAGS */
332                                         usch *obp = stringbuf;
333                                         extern usch *prtprag(usch *);
334                                         *stringbuf++ = yytext[0];
335                                         do {
336                                                 *stringbuf = input();
337                                         } while (*stringbuf++ != 14);
338                                         prtprag(obp);
339                                         stringbuf = obp;
340                                 } else {
341                                         PRTOUT(yytext[0]);
342                                 }
ragge
1.47
343                                 yy:;
ragge
1.46
344                         }
ragge
1.1
345
346 %%
347
348 usch *yyp, yybuf[CPPBUF];
349
350 int yylex(void);
351 int yywrap(void);
352
353 static int
354 inpch(void)
355 {
356         int len;
357
358         if (ifiles->curptr < ifiles->maxread)
359                 return *ifiles->curptr++;
360
361         if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
ragge
1.12
362                 error("read error on file %s", ifiles->orgfn);
ragge
1.1
363         if (len == 0)
364                 return -1;
365         ifiles->curptr = ifiles->buffer;
366         ifiles->maxread = ifiles->buffer + len;
367         return inpch();
368 }
369
370 #define unch(c) *--ifiles->curptr = c
371
372 static int
373 inch(void)
374 {
375         int c;
376
377 again:  switch (c = inpch()) {
378         case '\\': /* continued lines */
ragge
1.49
379 msdos:          if ((c = inpch()) == '\n') {
ragge
1.1
380                         ifiles->lineno++;
ragge
1.2
381                         putch('\n');
ragge
1.1
382                         goto again;
ragge
1.49
383                 } else if (c == '\r')
384                         goto msdos;
ragge
1.1
385                 unch(c);
386                 return '\\';
387         case '?': /* trigraphs */
388                 if ((c = inpch()) != '?') {
389                         unch(c);
390                         return '?';
391                 }
392                 switch (c = inpch()) {
393                 case '=': c = '#'; break;
394                 case '(': c = '['; break;
395                 case ')': c = ']'; break;
396                 case '<': c = '{'; break;
397                 case '>': c = '}'; break;
398                 case '/': c = '\\'; break;
399                 case '\'': c = '^'; break;
400                 case '!': c = '|'; break;
401                 case '-': c = '~'; break;
402                 default:
403                         unch(c);
404                         unch('?');
405                         return '?';
406                 }
407                 unch(c);
408                 goto again;
409         default:
410                 return c;
411         }
412 }
413
414 /*
ragge
1.14
415  * Let the command-line args be faked defines at beginning of file.
416  */
417 static void
418 prinit(struct initar *it, struct includ *ic)
419 {
420         char *a, *pre, *post;
421
422         if (it->next)
423                 prinit(it->next, ic);
ragge
1.15
424         pre = post = NULL; /* XXX gcc */
ragge
1.14
425         switch (it->type) {
426         case 'D':
427                 pre = "#define ";
428                 if ((a = strchr(it->str, '=')) != NULL) {
429                         *a = ' ';
430                         post = "\n";
431                 } else
432                         post = " 1\n";
433                 break;
434         case 'U':
435                 pre = "#undef ";
436                 post = "\n";
437                 break;
438         case 'i':
439                 pre = "#include \"";
440                 post = "\"\n";
441                 break;
ragge
1.17
442         default:
443                 error("prinit");
ragge
1.14
444         }
ragge
1.19
445         strlcat((char *)ic->buffer, pre, CPPBUF+1);
446         strlcat((char *)ic->buffer, it->str, CPPBUF+1);
447         if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
448                 error("line exceeds buffer size");
449
ragge
1.14
450         ic->lineno--;
451         while (*ic->maxread)
452                 ic->maxread++;
453 }
454
455 /*
ragge
1.1
456  * A new file included.
457  * If ifiles == NULL, this is the first file and already opened (stdin).
ragge
1.30
458  * Return 0 on success, -1 if file to be included is not found.
ragge
1.1
459  */
460 int
ragge
1.6
461 pushfile(usch *file)
ragge
1.1
462 {
ragge
1.14
463         extern struct initar *initar;
ragge
1.1
464         struct includ ibuf;
465         struct includ *ic;
ragge
1.2
466         int c, otrulvl;
ragge
1.1
467
468         ic = &ibuf;
ragge
1.30
469         ic->next = ifiles;
ragge
1.1
470
471         slow = 0;
472         if (file != NULL) {
ragge
1.39
473                 if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
ragge
1.1
474                         return -1;
ragge
1.12
475                 ic->orgfn = ic->fname = file;
ragge
1.30
476                 if (++inclevel > MAX_INCLEVEL)
477                         error("Limit for nested includes exceeded");
ragge
1.1
478         } else {
479                 ic->infil = 0;
ragge
1.12
480                 ic->orgfn = ic->fname = (usch *)"<stdin>";
ragge
1.1
481         }
482         ic->buffer = ic->bbuf+NAMEMAX;
483         ic->curptr = ic->buffer;
484         ifiles = ic;
485         ic->lineno = 1;
486         ic->maxread = ic->curptr;
487         prtline();
ragge
1.14
488         if (initar) {
489                 *ic->maxread = 0;
490                 prinit(initar, ic);
ragge
1.17
491                 if (dMflag)
492                         write(ofd, ic->buffer, strlen((char *)ic->buffer));
ragge
1.14
493                 initar = NULL;
494         }
ragge
1.1
495
ragge
1.2
496         otrulvl = trulvl;
497
ragge
1.1
498         if ((c = yylex()) != 0)
499                 error("yylex returned %d", c);
500
ragge
1.2
501         if (otrulvl != trulvl || flslvl)
ragge
1.1
502                 error("unterminated conditional");
503
ragge
1.30
504         ifiles = ic->next;
ragge
1.1
505         close(ic->infil);
ragge
1.30
506         inclevel--;
ragge
1.1
507         return 0;
508 }
509
510 /*
511  * Print current position to output file.
512  */
513 void
514 prtline()
515 {
ragge
1.12
516         usch *s, *os = stringbuf;
ragge
1.2
517
ragge
1.12
518         if (Mflag) {
ragge
1.17
519                 if (dMflag)
520                         return; /* no output */
ragge
1.12
521                 if (ifiles->lineno == 1) {
522                         s = sheap("%s: %s\n", Mfile, ifiles->fname);
523                         write(ofd, s, strlen((char *)s));
524                 }
gmcgarry
1.44
525         } else if (!Pflag)
ragge
1.12
526                 putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
ragge
1.2
527         stringbuf = os;
ragge
1.1
528 }
529
530 void
531 cunput(int c)
532 {
plunky
1.50
533 #ifdef PCC_DEBUG
ragge
1.2
534         extern int dflag;
ragge
1.46
535         if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
ragge
1.2
536 #endif
ragge
1.1
537         unput(c);
538 }
539
ragge
1.2
540 int yywrap(void) { return 1; }
ragge
1.1
541
ragge
1.2
542 static int
543 dig2num(int c)
ragge
1.1
544 {
ragge
1.2
545         if (c >= 'a')
546                 c = c - 'a' + 10;
547         else if (c >= 'A')
548                 c = c - 'A' + 10;
549         else
550                 c = c - '0';
551         return c;
ragge
1.1
552 }
553
ragge
1.6
554 /*
ragge
1.26
555  * Convert string numbers to unsigned long long and check overflow.
ragge
1.6
556  */
ragge
1.26
557 static void
ragge
1.1
558 cvtdig(int rad)
559 {
ragge
1.26
560         unsigned long long rv = 0;
561         unsigned long long rv2 = 0;
ragge
1.1
562         char *y = yytext;
563         int c;
564
565         c = *y++;
ragge
1.5
566         if (rad == 16)
567                 y++;
ragge
1.1
568         while (isxdigit(c)) {
ragge
1.2
569                 rv = rv * rad + dig2num(c);
ragge
1.26
570                 /* check overflow */
571                 if (rv / rad < rv2)
572                         error("Constant \"%s\" is out of range", yytext);
573                 rv2 = rv;
ragge
1.1
574                 c = *y++;
575         }
ragge
1.25
576         y--;
577         while (*y == 'l' || *y == 'L')
otto
1.24
578                 y++;
ragge
1.25
579         yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
ragge
1.26
580         yylval.node.nd_uval = rv;
ragge
1.28
581         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
582                 yylval.node.op = UNUMBER;
ragge
1.26
583         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
584                 /* too large for signed */
585                 error("Constant \"%s\" is out of range", yytext);
otto
1.24
586 }
587
ragge
1.2
588 static int
ragge
1.42
589 charcon(usch *p)
ragge
1.1
590 {
ragge
1.2
591         int val, c;
592
ragge
1.42
593         p++; /* skip first ' */
ragge
1.2
594         val = 0;
595         if (*p++ == '\\') {
596                 switch (*p++) {
597                 case 'a': val = '\a'; break;
598                 case 'b': val = '\b'; break;
599                 case 'f': val = '\f'; break;
600                 case 'n': val = '\n'; break;
601                 case 'r': val = '\r'; break;
602                 case 't': val = '\t'; break;
603                 case 'v': val = '\v'; break;
604                 case '\"': val = '\"'; break;
605                 case '\'': val = '\''; break;
606                 case '\\': val = '\\'; break;
607                 case 'x':
608                         while (isxdigit(c = *p)) {
609                                 val = val * 16 + dig2num(c);
610                                 p++;
611                         }
612                         break;
613                 case '0': case '1': case '2': case '3': case '4':
614                 case '5': case '6': case '7':
615                         p--;
616                         while (isdigit(c = *p)) {
617                                 val = val * 8 + (c - '0');
618                                 p++;
619                         }
620                         break;
621                 default: val = p[-1];
622                 }
623
624         } else
625                 val = p[-1];
626         return val;
ragge
1.1
627 }
628
629 static void
reed
1.33
630 chknl(int ignore)
ragge
1.1
631 {
632         int t;
633
ragge
1.30
634         slow = 1;
ragge
1.2
635         while ((t = yylex()) == WSPACE)
636                 ;
gmcgarry
1.34
637         if (t != '\n') {
reed
1.33
638                 if (ignore) {
639                         warning("newline expected, got \"%s\"", yytext);
640                         /* ignore rest of line */
641                         while ((t = yylex()) && t != '\n')
642                                 ;
643                 }
644                 else
645                         error("newline expected, got \"%s\"", yytext);
gmcgarry
1.34
646         }
ragge
1.30
647         slow = 0;
ragge
1.1
648 }
649
650 static void
651 elsestmt(void)
652 {
653         if (flslvl) {
654                 if (elflvl > trulvl)
655                         ;
656                 else if (--flslvl!=0) {
657                         flslvl++;
658                 } else {
659                         trulvl++;
660                         prtline();
661                 }
662         } else if (trulvl) {
663                 flslvl++;
664                 trulvl--;
665         } else
666                 error("If-less else");
667         if (elslvl==trulvl+flslvl)
668                 error("Too many else");
669         elslvl=trulvl+flslvl;
reed
1.33
670         chknl(1);
ragge
1.1
671 }
672
673 static void
ragge
1.2
674 ifdefstmt(void)          
ragge
1.1
675
ragge
1.31
676         int t;
677
ragge
1.13
678         if (flslvl) {
679                 /* just ignore the rest of the line */
680                 while (input() != '\n')
681                         ;
682                 unput('\n');
683                 yylex();
684                 flslvl++;
685                 return;
686         }
ragge
1.2
687         slow = 1;
ragge
1.31
688         do
689                 t = yylex();
690         while (t == WSPACE);
691         if (t != IDENT)
ragge
1.1
692                 error("bad ifdef");
ragge
1.2
693         slow = 0;
ragge
1.6
694         if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
ragge
1.1
695                 trulvl++;
696         else
697                 flslvl++;
reed
1.33
698         chknl(0);
ragge
1.1
699 }
700
701 static void
ragge
1.2
702 ifndefstmt(void)          
ragge
1.1
703
ragge
1.31
704         int t;
705
ragge
1.2
706         slow = 1;
ragge
1.31
707         do
708                 t = yylex();
709         while (t == WSPACE);
710         if (t != IDENT)
ragge
1.1
711                 error("bad ifndef");
ragge
1.2
712         slow = 0;
ragge
1.6
713         if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
ragge
1.1
714                 trulvl++;
715         else
716                 flslvl++;
reed
1.33
717         chknl(0);
ragge
1.1
718 }
719
720 static void
ragge
1.2
721 endifstmt(void)          
ragge
1.1
722 {
723         if (flslvl) {
724                 flslvl--;
725                 if (flslvl == 0)
726                         prtline();
727         } else if (trulvl)
728                 trulvl--;
729         else
730                 error("If-less endif");
731         if (flslvl == 0)
732                 elflvl = 0;
733         elslvl = 0;
reed
1.33
734         chknl(1);
ragge
1.1
735 }
736
ragge
1.7
737 /*
738  * Note! Ugly!
739  * Walk over the string s and search for defined, and replace it with 
740  * spaces and a 1 or 0. 
741  */
742 static void
743 fixdefined(usch *s)
744 {
745         usch *bc, oc;
746
747         for (; *s; s++) {
748                 if (*s != 'd')
749                         continue;
750                 if (memcmp(s, "defined", 7))
751                         continue;
752                 /* Ok, got defined, can scratch it now */
753                 memset(s, ' ', 7);
754                 s += 7;
755 #define WSARG(x) (x == ' ' || x == '\t')
756                 if (*s != '(' && !WSARG(*s))
757                         continue;
758                 while (WSARG(*s))
759                         s++;
760                 if (*s == '(')
761                         s++;
762                 while (WSARG(*s))
763                         s++;
764 #define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
765 #define NUMARG(x) (x >= '0' && x <= '9')
766                 if (!IDARG(*s))
767                         error("bad defined arg");
768                 bc = s;
769                 while (IDARG(*s) || NUMARG(*s))
770                         s++;
771                 oc = *s;
772                 *s = 0;
773                 *bc = (lookup(bc, FIND) != 0) + '0';
774                 memset(bc+1, ' ', s-bc-1);
775                 *s = oc;
776         }
777 }
778
779 /*
780  * get the full line of identifiers after an #if, pushback a WARN and
781  * the line and prepare for expmac() to expand.
782  * This is done before switching state.  When expmac is finished,
783  * pushback the expanded line, change state and call yyparse.
784  */
785 static void
786 storepb(void)
787 {
788         usch *opb = stringbuf;
789         int c;
790
ragge
1.37
791         while ((c = input()) != '\n') {
792                 if (c == '/') {
793                          if ((c = input()) == '*') {
794                                 /* ignore comments here whatsoever */
795                                 usch *g = stringbuf;
796                                 getcmnt();
797                                 stringbuf = g;
798                                 continue;
ragge
1.48
799                         } else if (c == '/') {
800                                 while ((c = input()) && c != '\n')
801                                         ;
802                                 break;
ragge
1.37
803                         }
804                         unput(c);
805                         c = '/';
806                 }
ragge
1.7
807                 savch(c);
ragge
1.37
808         }
ragge
1.7
809         cunput('\n');
810         savch(0);
ragge
1.13
811         fixdefined(opb); /* XXX can fail if #line? */
ragge
1.7
812         cunput(1); /* WARN XXX */
813         unpstr(opb);
814         stringbuf = opb;
815         slow = 1;
816         expmac(NULL);
817         slow = 0;
818         /* line now expanded */
819         while (stringbuf > opb)
820                 cunput(*--stringbuf);
821 }
822
ragge
1.1
823 static void
824 ifstmt(void)
825 {
826         if (flslvl == 0) {
ragge
1.2
827                 slow = 1;
ragge
1.1
828                 if (yyparse())
829                         ++trulvl;
830                 else
831                         ++flslvl;
ragge
1.2
832                 slow = 0;
ragge
1.1
833         } else
834                 ++flslvl;
835 }
836
837 static void
838 elifstmt(void)
839 {
840         if (flslvl == 0)
841                 elflvl = trulvl;
842         if (flslvl) {
843                 if (elflvl > trulvl)
844                         ;
845                 else if (--flslvl!=0)
846                         ++flslvl;
847                 else {
ragge
1.2
848                         slow = 1;
ragge
1.1
849                         if (yyparse()) {
850                                 ++trulvl;
851                                 prtline();
852                         } else
853                                 ++flslvl;
ragge
1.2
854                         slow = 0;
ragge
1.1
855                 }
856         } else if (trulvl) {
857                 ++flslvl;
858                 --trulvl;
859         } else
860                 error("If-less elif");
861 }
862
863 static usch *
864 svinp(void)
865 {
866         int c;
867         usch *cp = stringbuf;
868
869         while ((c = input()) && c != '\n')
870                 savch(c);
ragge
1.11
871         savch('\n');
872         savch(0);
ragge
1.1
873         BEGIN 0;
874         return cp;
875 }
876
877 static void
878 cpperror(void)
879 {
880         usch *cp;
ragge
1.2
881         int c;
ragge
1.1
882
ragge
1.2
883         if (flslvl)
884                 return;
885         c = yylex();
886         if (c != WSPACE && c != '\n')
ragge
1.1
887                 error("bad error");
888         cp = svinp();
889         if (flslvl)
890                 stringbuf = cp;
891         else
ragge
1.26
892                 error("%s", cp);
ragge
1.1
893 }
894
895 static void
896 undefstmt(void)
897 {
898         struct symtab *np;
899
900         slow = 1;
901         if (yylex() != WSPACE || yylex() != IDENT)
902                 error("bad undef");
ragge
1.6
903         if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
ragge
1.1
904                 np->value = 0;
905         slow = 0;
reed
1.33
906         chknl(0);
ragge
1.1
907 }
908
909 static void
910 pragmastmt(void)
911 {
ragge
1.20
912         int c;
913
ragge
1.4
914         slow = 1;
ragge
1.1
915         if (yylex() != WSPACE)
916                 error("bad pragma");
ragge
1.23
917         if (!flslvl)
918                 putstr((usch *)"#pragma ");
ragge
1.20
919         do {
ragge
1.23
920                 c = input();
921                 if (!flslvl)
922                         putch(c);       /* Do arg expansion instead? */
ragge
1.20
923         } while (c && c != '\n');
924         ifiles->lineno++;
925         prtline();
ragge
1.4
926         slow = 0;
ragge
1.1
927 }
stefan
1.27
928
929 static void
930 badop(const char *op)
931 {
932         error("invalid operator in preprocessor expression: %s", op);
933 }
ragge
1.36
934
935 int
936 cinput()
937 {
938         return input();
939 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-09-16 06:52 +0200