Quick Search:

Mode

Context

Displaying 3 lines of context. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.18
 
1.19
 
MAIN:ragge:20090801155306
 
token.c
_>2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 
<> 27+/*
  28+ * Tokenizer for the C preprocessor.
  29+ * There are three main routines:
  30+ *      - fastscan() loops over the input stream searching for magic
  31+ *              characters that may require actions.
  32+ *      - sloscan() tokenize the input stream and returns tokens.
  33+ *              It may recurse into itself during expansion.
  34+ *      - yylex() returns something from the input stream that
  35+ *              is suitable for yacc.
  36+ *
  37+ *      Other functions of common use:
  38+ *      - inpch() returns a raw character from the current input stream.
  39+ *      - inch() is like inpch but \\n and trigraphs are expanded.
  40+ *      - unch() pushes back a character to the input stream.
  41+ */
  42+
2743 #include "config.h"
 2844 
 2945 #include <stdlib.h>
     
 !
5167 static void undefstmt(void);
 5268 static void cpperror(void);
 5369 static void elifstmt(void);
<>54 -static void storepb(void);
5570 static void badop(const char *);
<> 71+static int chktg(void);
  72+static void ppdir(void);
5673 void  include(void);
 5774 void  define(void);
<> 75+static int inpch(void);
5876 
 5977 extern int yyget_lineno (void);
 6078 extern void yyset_lineno (int);
 6179 
 6280 static int inch(void);
 6381 
<>64 -static int scale, gotdef, contr;
6582 int inif;
 6683 
<>67 -#undef input
 68 -#undef unput
 69 -#define input() inch()
 70 -#define unput(ch) unch(ch)
 71 -#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
  84+#define PUTCH(ch) if (!flslvl) putch(ch)
7285 /* protection against recursion in #include */
 7386 #define MAX_INCLEVEL    100
 7487 static int inclevel;
 7588 
<>76 -#define IFR     1
 77 -#define CONTR   2
 78 -#define DEF     3
 79 -#define COMMENT 4
 80 -static int state;
 81 -#define BEGIN state =
 82 -#define YYSTATE state
  89+/* get next character unaltered */
  90+#define NXTCH() (ifiles->curptr < ifiles->maxread ? *ifiles->curptr++ : inpch())
8391 
 8492 #ifdef YYTEXT_POINTER
 8593 static char buf[CPPBUF];
     
 !
8896 char yytext[CPPBUF];
 8997 #endif
 9098 
<>91 -static int owasnl, wasnl = 1;
  99+#define C_SPEC  1
  100+#define C_EP    2
  101+#define C_ID    4
  102+#define C_I     (C_SPEC|C_ID)
  103+#define C_2     8               /* for yylex() tokenizing */
  104+static char spechr[256] = {
  105+        0,      0,      0,      0,      0,      0,      0,      0,
  106+        0,      0,      C_SPEC, 0,      0,      C_SPEC, 0,      0,
  107+        0,      0,      0,      0,      0,      0,      0,      0,
  108+        0,      0,      0,      0,      0,      0,      0,      0,
92109 
<> 110+        0,      C_2,    C_SPEC0,      0,      0,      C_2,    C_SPEC,
  111+        0,      0,      0,      C_2,    0,      C_2,    0,      C_SPEC,
  112+        C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
  113+        C_I,    C_I,    0,      0,      C_2,    C_2,    C_2,    C_SPEC,
  114+
  115+        0,      C_I,    C_I,    C_I,    C_I,    C_I|C_EP, C_I,  C_I,
  116+        C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
  117+        C_I|C_EP, C_I,  C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
  118+        C_I,    C_I,    C_I,    0,      0,      0,      0,      C_I,
  119+
  120+        0,      C_I,    C_I,    C_I,    C_I,    C_I|C_EP, C_I,  C_I,
  121+        C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
  122+        C_I|C_EP, C_I,  C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
  123+        C_I,    C_I,    C_I,    0,      C_2,    0,      0,      0,
  124+
  125+};
  126+
93127 static void
 94128 unch(int c)
 95129 {
     
 !
100134         *ifiles->curptr = c;
 101135 }
 102136 
<> 137+/*
  138+ * Scan quickly the input file searching for:
  139+ *      - '#' directives
  140+ *      - keywords (if not flslvl)
  141+ *      - comments
  142+ *
  143+ *      Handle strings, numbers and trigraphs with care.
  144+ *      Only data from pp files are scanned here, never any rescans.
  145+ *      TODO: Only print out strings before calling other functions.
  146+ */
  147+static void
  148+fastscan(void)
  149+{
  150+        struct symtab *nl;
  151+        int ch, i;
103152 
<> 153+        goto run;
  154+        for (;;) {
  155+                ch = NXTCH();
  156+xloop:          if (ch == -1)
  157+                        return;
  158+                if ((spechr[ch] & C_SPEC) == 0) {
  159+                        PUTCH(ch);
  160+                        continue;
  161+                }
  162+                switch (ch) {
  163+                case '/': /* Comments */
  164+                        if ((ch = inch()) == '/') {
  165+                                if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
  166+                                do {
  167+                                        if (Cflag) PUTCH(ch);
  168+                                        ch = inch();
  169+                                } while (ch != -1 && ch != '\n');
  170+                                goto xloop;
  171+                        } else if (ch == '*') {
  172+                                if (Cflag) { PUTCH('/'); PUTCH('*'); }
  173+                                for (;;) {
  174+                                        ch = inch();
  175+                                        if (ch == '\n') {
  176+                                                ifiles->lineno++;
  177+                                                PUTCH('\n');
  178+                                        }
  179+                                        if (ch == -1)
  180+                                                return;
  181+                                        if (ch == '*') {
  182+                                                ch = inch();
  183+                                                if (ch == '/') {
  184+                                                        if (Cflag) {
  185+                                                                PUTCH('*');
  186+                                                                PUTCH('/');
  187+                                                        } else
  188+                                                                PUTCH(' ');
  189+                                                        break;
  190+                                                } else
  191+                                                        unch(ch);
  192+                                        }
  193+                                        if (Cflag) PUTCH(ch);
  194+                                }
  195+                        } else {
  196+                                PUTCH('/');
  197+                                goto xloop;
  198+                        }
  199+                        break;
  200+
  201+                case '?'/* trigraphs */
  202+                        if ((ch = chktg()))
  203+                                goto xloop;
  204+                        PUTCH('?');
  205+                        break;
  206+
  207+                case '\n': /* newlines, for pp directives */
  208+                        ifiles->lineno++;
  209+                        do {
  210+                                PUTCH(ch);
  211+run:                            ch = NXTCH();
  212+                        } while (ch == ' ' || ch == '\t');
  213+                        if (ch == '#') {
  214+                                ppdir();
  215+                                continue;
  216+                        }
  217+                        goto xloop;
  218+
  219+                case '\"': /* strings */
  220+str:                    do {
  221+                                PUTCH(ch);
  222+                                ch = NXTCH();
  223+                                if (ch == '\\') {
  224+                                        PUTCH(ch);
  225+                                        ch = NXTCH();
  226+                                }
  227+                                if (ch < 0)
  228+                                        return;
  229+                        } while (ch != '\"');
  230+                        PUTCH(ch);
  231+                        break;
  232+
  233+                case '.'/* for pp-number */
  234+                        PUTCH(ch);
  235+                        ch = NXTCH();
  236+                        if (ch < '0' || ch > '9')
  237+                                goto xloop;
  238+                        /* FALLTHROUGH */
  239+                case '0': case '1': case '2': case '3': case '4':
  240+                case '5': case '6': case '7': case '8': case '9':
  241+                        do {
  242+                                PUTCH(ch);
  243+                                ch = NXTCH();
  244+                                if (spechr[ch] & C_EP) {
  245+                                        PUTCH(ch);
  246+                                        ch = NXTCH();
  247+                                        if (ch == '-' || ch == '+')
  248+                                                continue;
  249+                                }
  250+                        } while ((spechr[ch] & C_ID) || (ch == '.'));
  251+                        goto xloop;
  252+
  253+                case '\'': /* character literal */
  254+con:                    do {
  255+                                PUTCH(ch);
  256+                                ch = NXTCH();
  257+                                if (ch == '\\') {
  258+                                        PUTCH(ch);
  259+                                        ch = NXTCH();
  260+                                }
  261+                                if (ch < 0)
  262+                                        return;
  263+                                if (ch == '\n')
  264+                                        goto xloop;
  265+                        } while (ch != '\'');
  266+                        PUTCH(ch);
  267+                        break;
  268+                case 'L':
  269+                        ch = NXTCH();
  270+                        if (ch == '\"') {
  271+                                PUTCH('L');
  272+                                goto str;
  273+                        }
  274+                        if (ch == '\'') {
  275+                                PUTCH('L');
  276+                                goto con;
  277+                        }
  278+                        unch(ch);
  279+                        ch = 'L';
  280+                        /* FALLTHROUGH */
  281+                default:
  282+                        if ((spechr[ch] & C_ID) == 0)
  283+                                error("fastscan");
  284+                        if (flslvl) {
  285+                                while (spechr[ch] & C_ID)
  286+                                        ch = NXTCH();
  287+                                goto xloop;
  288+                        }
  289+                        i = 0;
  290+                        do {
  291+                                yytext[i++] = ch;
  292+                                ch = NXTCH();
  293+                                if (ch < 0)
  294+                                        return;
  295+                        } while (spechr[ch] & C_ID);
  296+                        yytext[i] = 0;
  297+                        unch(ch);
  298+                        if ((nl = lookup((usch *)yytext, FIND)) != 0) {
  299+                                usch *op = stringbuf;
  300+                                putstr(gotident(nl));
  301+                                stringbuf = op;
  302+                        } else
  303+                                putstr((usch *)yytext);
  304+                        break;
  305+                }
  306+        }
  307+}
  308+
104309 int
<>105 -yylex()
  310+sloscan()
106311 {
 107312         int ch;
 108313         int yyp;
<>109 -        int os, mixed, haspmd;
110314 
 111315 zagain:
 112316         yyp = 0;
 113317         yytext[yyp++] = ch = inch();
<>114 -        owasnl = wasnl;
 115 -        wasnl = 0;
116318         switch (ch) {
 117319         case -1:
 118320                 return 0;
 119321         case '\n':
<>120 -                os = YYSTATE;
  322+                /* sloscan() never passes \n, that's up to fastscan() */
  323+                unch(ch);
  324+                goto yyret;
121325 
<>122 -                wasnl = 1;
 123 -                if (os != IFR)
 124 -                        BEGIN 0;
 125 -                ifiles->lineno++;
 126 -                if (flslvl == 0) {
 127 -                        if (ifiles->lineno == 1)
 128 -                                prtline();
 129 -                        else
 130 -                                putch('\n');
 131 -                }
 132 -                if ((os != 0 || slow) && !contr)
 133 -                        goto yyret;
 134 -                contr = 0;
 135 -                break;
 136 -
137326         case '\r': /* Ignore CR's */
 138327                 yyp = 0;
 139328                 break;
 140329 
<>141 -#define CHK(x,y) if (state != IFR) goto any; \
 142 -        if ((ch = input()) != y) { unput(ch); ch = x; goto any; } \
 143 -        yytext[yyp++] = ch
 144 -
 145 -        case '+': CHK('+','+'); badop("++"); break;
 146 -        case '-': CHK('-','-'); badop("--"); break;
 147 -        case '=': CHK('=','='); ch = EQ; goto yyret;
 148 -        case '!': CHK('!','='); ch = NE; goto yyret;
 149 -        case '|': CHK('|','|'); ch = OROR; goto yyret;
 150 -        case '&': CHK('&','&'); ch = ANDAND; goto yyret;
 151 -        case '<':
 152 -                if (state != IFR) goto any;
 153 -                if ((ch = inch()) == '=') {
 154 -                        yytext[yyp++] = ch; ch = LE; goto yyret;
 155 -                }
 156 -                if (ch == '<') { yytext[yyp++] = ch; ch = LS; goto yyret; }
 157 -                unch(ch);
 158 -                ch = '<';
 159 -                goto any;
 160 -        case '>':
 161 -                if (state != IFR) goto any;
 162 -                if ((ch = inch()) == '=') {
 163 -                        yytext[yyp++] = ch; ch = GE; goto yyret;
 164 -                }
 165 -                if (ch == '>') { yytext[yyp++] = ch; ch = RS; goto yyret; }
 166 -                unch(ch);
 167 -                ch = '>';
 168 -                goto any;
 169 -
 170 -
171330         case '0': case '1': case '2': case '3': case '4': case '5':
 172331         case '6': case '7': case '8': case '9':
 173332                 /* readin a "pp-number" */
<>174 -                mixed = haspmd = 0;
175333 ppnum:          for (;;) {
<>176 -                        ch = input();
 177 -                        if (ch == 'e' || ch == 'E' || ch == 'p' || ch == 'P') {
  334+                        ch = inch();
  335+                        if (spechr[ch] & C_EP) {
178336                                 yytext[yyp++] = ch;
<>179 -                                mixed = 1;
 180 -                                ch = input();
  337+                                ch = inch();
181338                                 if (ch == '-' || ch == '+') {
 182339                                         yytext[yyp++] = ch;
<>183 -                                        haspmd = 1;
184340                                 } else
<>185 -                                        unput(ch);
  341+                                        unch(ch);
186342                                 continue;
 187343                         }
<>188 -                        if (isdigit(ch) || isalpha(ch) ||
 189 -                            ch == '_' || ch == '.') {
  344+                        if ((spechr[ch] & C_ID) || ch == '.') {
190345                                 yytext[yyp++] = ch;
<>191 -                                if (ch == '.')
 192 -                                        haspmd = 1;
 193 -                                if (!isdigit(ch))
 194 -                                        mixed = 1;
195346                                 continue;
 196347                         }
 197348                         break;
 198349                 }
<>199 -                unput(ch);
  350+                unch(ch);
200351                 yytext[yyp] = 0;
 201352 
<>202 -                if (mixed == 1 && slow && (state == 0 || state == DEF))
 203 -                        return IDENT;
  353+                return NUMBER;
204354 
<>205 -                if (mixed == 0) {
 206 -                        if (slow && !YYSTATE)
 207 -                                return IDENT;
 208 -                        scale = yytext[0] == '0' ? 8 : 10;
 209 -                        goto num;
 210 -                } else if (yytext[0] == '0' &&
 211 -                    (yytext[1] == 'x' || yytext[1] == 'X')) {
 212 -                        scale = 16;
 213 -num:                    if (YYSTATE == IFR)
 214 -                                cvtdig(scale);
 215 -                        PRTOUT(NUMBER);
 216 -                } else if (yytext[0] == '0' && isdigit((int)yytext[1])) {
 217 -                        scale = 8; goto num;
 218 -                } else if (haspmd) {
 219 -                        PRTOUT(FPOINT);
 220 -                } else {
 221 -                        scale = 10; goto num;
 222 -                }
 223 -                goto zagain;
 224 -
 225 -
226355         case '\'':
<>227 -chlit:          if (tflag && !(YYSTATE || slow))
 228 -                        goto any;
  356+chlit:          
229357                 for (;;) {
<>230 -                        if ((ch = input()) == '\\') {
  358+                        if ((ch = inch()) == '\\') {
231359                                 yytext[yyp++] = ch;
<>232 -                                yytext[yyp++] = input();
  360+                                yytext[yyp++] = inch();
233361                                 continue;
 234362                         } else if (ch == '\n') {
 235363                                 /* not a constant */
 236364                                 while (yyp > 1)
<>237 -                                        unput(yytext[--yyp]);
  365+                                        unch(yytext[--yyp]);
238366                                 ch = '\'';
 239367                                 goto any;
 240368                         } else
     
 !
244372                 }
 245373                 yytext[yyp] = 0;
 246374 
<>247 -                if (YYSTATE || slow) {
 248 -                        yylval.node.op = NUMBER;
 249 -                        yylval.node.nd_val = charcon((usch *)yytext);
 250 -                        return (NUMBER);
 251 -                }
 252 -                if (!flslvl)
 253 -                        putstr((usch *)yytext);
 254 -                goto zagain;
  375+                yylval.node.op = NUMBER;
  376+                yylval.node.nd_val = charcon((usch *)yytext);
  377+                return (NUMBER);
255378 
 256379         case ' ':
 257380         case '\t':
<>258 -                if (state == IFR)
 259 -                        goto zagain;
 260 -
 261 -                while ((ch = input()) == ' ' || ch == '\t')
  381+                while ((ch = inch()) == ' ' || ch == '\t')
262382                         yytext[yyp++] = ch;
<>263 -                if (owasnl == 0) {
 264 -b1:                     unput(ch);
 265 -                        yytext[yyp] = 0;
 266 -                        PRTOUT(WSPACE);
 267 -                } else if (ch != '#') {
 268 -                        goto b1;
 269 -                } else {
 270 -                        extern int inmac;
  383+                unch(ch);
  384+                yytext[yyp] = 0;
  385+                return(WSPACE);
271386 
<>272 -contr:                  while ((ch = input()) == ' ' || ch == '\t')
 273 -                                ;
 274 -                        unch(ch);
 275 -                        if (inmac)
 276 -                                error("preprocessor directive found "
 277 -                                    "while expanding macro");
 278 -                        contr = 1;
 279 -                        BEGIN CONTR;
 280 -
 281 -                }
 282 -                goto zagain;
 283 -
284387         case '/':
<>285 -                if ((ch = input()) == '/') {
  388+                if ((ch = inch()) == '/') {
286389                         do {
 287390                                 yytext[yyp++] = ch;
<>288 -                                ch = input();
  391+                                ch = inch();
289392                         } while (ch && ch != '\n');
 290393                         yytext[yyp] = 0;
 291394                         unch(ch);
<>292 -                        if (Cflag && !flslvl && !slow)
 293 -                                putstr((usch *)yytext);
 294 -                        else if (!flslvl)
 295 -                                putch(' ');
296395                         goto zagain;
 297396                 } else if (ch == '*') {
 298397                         int c, wrn;
<>299 -                        int prtcm = Cflag && !flslvl && !slow;
300398                         extern int readmac;
 301399 
 302400                         if (Cflag && !flslvl && readmac)
 303401                                 return CMNT;
 304402 
<>305 -                        if (prtcm)
 306 -                                putstr((usch *)yytext);
307403                         wrn = 0;
<>308 -                more:   while ((c = input()) && c != '*') {
  404+                more:   while ((c = inch()) && c != '*') {
309405                                 if (c == '\n')
 310406                                         putch(c), ifiles->lineno++;
 311407                                 else if (c == 1) /* WARN */
 312408                                         wrn = 1;
<>313 -                                else if (prtcm)
 314 -                                        putch(c);
315409                         }
 316410                         if (c == 0)
 317411                                 return 0;
<>318 -                        if (prtcm)
 319 -                                putch(c);
 320 -                        if ((c = input()) && c != '/') {
 321 -                                unput(c);
  412+                        if ((c = inch()) && c != '/') {
  413+                                unch(c);
322414                                 goto more;
 323415                         }
<>324 -                        if (prtcm)
 325 -                                putch(c);
326416                         if (c == 0)
 327417                                 return 0;
 328418                         if (!tflag && !Cflag && !flslvl)
<>329 -                                unput(' ');
  419+                                unch(' ');
330420                         if (wrn)
<>331 -                                unput(1);
  421+                                unch(1);
332422                         goto zagain;
 333423                 }
 334424                 unch(ch);
 335425                 ch = '/';
 336426                 goto any;
 337427 
<>338 -        case '#':
 339 -                if (state != DEF) {
 340 -                        if (owasnl)
 341 -                                goto contr;
 342 -                        goto any;
 343 -                }
 344 -                if ((ch = input()) == '#') {
  428+        case '.':
  429+                ch = inch();
  430+                if (isdigit(ch)) {
345431                         yytext[yyp++] = ch;
<>346 -                        ch = CONCAT;
  432+                        goto ppnum;
347433                 } else {
<>348 -                        unput(ch);
 349 -                        ch = MKSTR;
 350 -                }
 351 -                goto yyret;
 352 -                
 353 -        case '.':
 354 -                if (state != DEF) {
 355 -                        ch = input();
 356 -                        if (isdigit(ch)) {
 357 -                                yytext[yyp++] = ch;
 358 -                                mixed = haspmd = 1;
 359 -                                goto ppnum;
 360 -                        } else {
 361 -                                unput(ch);
 362 -                                ch = '.';
 363 -                        }
 364 -                        goto any;
 365 -                }
 366 -                if ((ch = input()) != '.') {
 367 -                        unput(ch);
  434+                        unch(ch);
368435                         ch = '.';
<>369 -                        goto any;
370436                 }
<>371 -                if ((ch = input()) != '.') {
 372 -                        unput(ch);
 373 -                        unput('.');
 374 -                        ch = '.';
 375 -                        goto any;
 376 -                }
 377 -                yytext[yyp++] = ch;
 378 -                yytext[yyp++] = ch;
 379 -                ch = ELLIPS;
 380 -                goto yyret;
  437+                goto any;
381438 
<>382 -
383439         case '\"':
 384440         strng:
 385441                 for (;;) {
<>386 -                        if ((ch = input()) == '\\') {
  442+                        if ((ch = inch()) == '\\') {
387443                                 yytext[yyp++] = ch;
<>388 -                                yytext[yyp++] = input();
  444+                                yytext[yyp++] = inch();
389445                                 continue;
 390446                         } else
 391447                                 yytext[yyp++] = ch;
 392448                         if (ch == '\"')
 393449                                 break;
 394450                 }
 395451                 yytext[yyp] = 0;
<>396 -                { PRTOUT(STRING); }
 397 -                break;
  452+                return(STRING);
398453 
 399454         case 'L':
<>400 -                if ((ch = input()) == '\"') {
  455+                if ((ch = inch()) == '\"') {
401456                         yytext[yyp++] = ch;
 402457                         goto strng;
 403458                 } else if (ch == '\'') {
 404459                         yytext[yyp++] = ch;
 405460                         goto chlit;
 406461                 }
<>407 -                unput(ch);
  462+                unch(ch);
408463                 /* FALLTHROUGH */
 409464 
 410465         /* Yetch, all identifiers */
     
 !
418473         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
 419474         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
 420475         case 'Y': case 'Z':
<>421 -        case '_': { /* {L}({L}|{D})* */
 422 -                struct symtab *nl;
  476+        case '_': /* {L}({L}|{D})* */
423477 
 424478                 /* Special hacks */
 425479                 for (;;) { /* get chars */
<>426 -                        ch = input();
  480+                        ch = inch();
427481                         if (isalpha(ch) || isdigit(ch) || ch == '_') {
 428482                                 yytext[yyp++] = ch;
 429483                         } else {
<>430 -                                unput(ch);
  484+                                unch(ch);
431485                                 break;
 432486                         }
 433487                 }
 434488                 yytext[yyp] = 0; /* need already string */
<>435 -
 436 -                switch (state) {
 437 -                case DEF:
 438 -                        if (strcmp(yytext, "__VA_ARGS__") == 0)
 439 -                                return VA_ARGS;
 440 -                        break;
 441 -                case CONTR:
 442 -#define CC(s)   if (strcmp(yytext, s) == 0)
 443 -                        CC("ifndef") {
 444 -                                contr = 0; ifndefstmt();
 445 -                                BEGIN 0;
 446 -                                goto zagain;
 447 -                        } else CC("ifdef") {
 448 -                                contr = 0; ifdefstmt();
 449 -                                BEGIN 0;
 450 -                                goto zagain;
 451 -                        } else CC("if") {
 452 -                                contr = 0; storepb(); BEGIN IFR;
 453 -                                ifstmt(); BEGIN 0;
 454 -                                goto zagain;
 455 -                        } else CC("include") {
 456 -                                contr = 0; BEGIN 0; include(); prtline();
 457 -                                goto zagain;
 458 -                        } else CC("else") {
 459 -                                contr = 0; elsestmt();
 460 -                                goto zagain;
 461 -                        } else CC("endif") {
 462 -                                contr = 0; endifstmt();
 463 -                                goto zagain;
 464 -                        } else CC("error") {
 465 -                                contr = 0; if (slow) return IDENT;
 466 -                                cpperror(); BEGIN 0;
 467 -                                goto zagain;
 468 -                        } else CC("define") {
 469 -                                contr = 0; BEGIN DEF; define(); BEGIN 0;
 470 -                                goto zagain;
 471 -                        } else CC("undef") {
 472 -                                contr = 0; if (slow) return IDENT; undefstmt();
 473 -                                goto zagain;
 474 -                        } else CC("line") {
 475 -                                contr = 0; storepb(); BEGIN 0; line();
 476 -                                goto zagain;
 477 -                        } else CC("pragma") {
 478 -                                contr = 0; pragmastmt(); BEGIN 0;
 479 -                                goto zagain;
 480 -                        } else CC("elif") {
 481 -                                contr = 0; storepb(); BEGIN IFR;
 482 -                                elifstmt(); BEGIN 0;
 483 -                                goto zagain;
 484 -                        }
 485 -                        break;
 486 -                case  IFR:
 487 -                        CC("defined") {
 488 -                                int p, c;
 489 -                                gotdef = 1;
 490 -                                if ((p = c = yylex()) == '(')
 491 -                                        c = yylex();
 492 -                                if (c != IDENT || (p != IDENT && p != '('))
 493 -                                        error("syntax error");
 494 -                                if (p == '(' && yylex() != ')')
 495 -                                        error("syntax error");
 496 -                                return NUMBER;
 497 -                        } else {
 498 -                                yylval.node.op = NUMBER;
 499 -                                if (gotdef) {
 500 -                                        yylval.node.nd_val
 501 -                                            = lookup((usch *)yytext, FIND) != 0;
 502 -                                        gotdef = 0;
 503 -                                        return IDENT;
 504 -                                }
 505 -                                yylval.node.nd_val = 0;
 506 -                                return NUMBER;
 507 -                        }
 508 -                }
 509 -
510489                 /* end special hacks */
 511490 
<>512 -                if (slow)
 513 -                        return IDENT;
 514 -                if (YYSTATE == CONTR) {
 515 -                        if (flslvl == 0) {
 516 -                                /*error("undefined control");*/
 517 -                                while (input() != '\n')
 518 -                                        ;
 519 -                                unput('\n');
 520 -                                BEGIN 0;
 521 -                                goto xx;
 522 -                        } else {
 523 -                                BEGIN 0; /* do nothing */
 524 -                        }
 525 -                }
 526 -                if (flslvl) {
 527 -                        ; /* do nothing */
 528 -                } else if (isdigit((int)yytext[0]) == 0 &&
 529 -                    (nl = lookup((usch *)yytext, FIND)) != 0) {
 530 -                        usch *op = stringbuf;
 531 -                        putstr(gotident(nl));
 532 -                        stringbuf = op;
 533 -                } else
 534 -                        putstr((usch *)yytext);
 535 -                xx:
 536 -                goto zagain;
 537 -        }
 538 -
  491+                return IDENT;
539492         default:
 540493         any:
<>541 -                if (state == IFR)
 542 -                        goto yyret;
543494                 yytext[yyp] = 0;
<>544 -                if (contr) {
 545 -                        while (input() != '\n')
 546 -                                ;
 547 -                        unput('\n');
 548 -                        BEGIN 0;
 549 -                        contr = 0;
 550 -                        goto yy;
 551 -                }
 552 -                if (YYSTATE || slow)
 553 -                        return yytext[0];
 554 -                if (yytext[0] == 6) { /* PRAGS */
 555 -                        usch *obp = stringbuf;
 556 -                        extern usch *prtprag(usch *);
 557 -                        *stringbuf++ = yytext[0];
 558 -                        do {
 559 -                                *stringbuf = input();
 560 -                        } while (*stringbuf++ != 14);
 561 -                        prtprag(obp);
 562 -                        stringbuf = obp;
 563 -                } else {
 564 -                        PRTOUT(yytext[0]);
 565 -                }
 566 -                yy:
 567 -                yyp = 0;
 568 -                break;
  495+                return yytext[0];
569496 
 570497         } /* endcase */
 571498         goto zagain;
     
 !
575502         return ch;
 576503 }
 577504 
<> 505+int
  506+yylex()
  507+{
  508+        static int ifdef, noex;
  509+        struct symtab *nl;
  510+        int ch, c2;
  511+
  512+        while ((ch = sloscan()) == WSPACE)
  513+                ;
  514+        if (ch < 128 && spechr[ch] & C_2)
  515+                c2 = inpch();
  516+        else
  517+                c2 = 0;
  518+
  519+#define C2(a,b,c) case a: if (c2 == b) return c; break
  520+        switch (ch) {
  521+        C2('=', '=', EQ);
  522+        C2('!', '=', NE);
  523+        C2('|', '|', OROR);
  524+        C2('&', '&', ANDAND);
  525+        case '<':
  526+                if (c2 == '<') return LS;
  527+                if (c2 == '=') return LE;
  528+                break;
  529+        case '>':
  530+                if (c2 == '>') return RS;
  531+                if (c2 == '=') return GE;
  532+                break;
  533+        case '+':
  534+        case '-':
  535+                if (ch == c2)
  536+                        badop("");
  537+                break;
  538+        case NUMBER:
  539+                cvtdig(yytext[0] != '0' ? 10 :
  540+                    yytext[1] == 'x' || yytext[1] == 'X' ? 16 : 8);
  541+                return NUMBER;
  542+        case IDENT:
  543+                if (strcmp(yytext, "defined") == 0) {
  544+                        ifdef = 1;
  545+                        return DEFINED;
  546+                }
  547+                nl = lookup((usch *)yytext, FIND);
  548+                if (ifdef) {
  549+                        yylval.node.nd_val = nl != NULL;
  550+                        ifdef = 0;
  551+                } else if (nl && noex == 0) {
  552+                        usch *c, *och = stringbuf;
  553+
  554+                        c = gotident(nl);
  555+                        unch(1);
  556+                        unpstr(c);
  557+                        stringbuf = och;
  558+                        noex = 1;
  559+                        return yylex();
  560+                } else {
  561+                        yylval.node.nd_val = 0;
  562+                }
  563+                yylval.node.op = NUMBER;
  564+                return NUMBER;
  565+        case 1: /* WARN */
  566+                noex = 0;
  567+                return yylex();
  568+        default:
  569+                return ch;
  570+        }
  571+        unch(c2);
  572+        return ch;
  573+}
  574+
578575 usch *yyp, yybuf[CPPBUF];
 579576 
<>580 -int yylex(void);
581577 int yywrap(void);
 582578 
 583579 static int
     
 !
613609                 unch(c);
 614610                 return '\\';
 615611         case '?': /* trigraphs */
<>616 -                if ((c = inpch()) != '?') {
  612+                if ((c = chktg())) {
617613                         unch(c);
<>618 -                        return '?';
  614+                        goto again;
619615                 }
<>620 -                switch (c = inpch()) {
 621 -                case '=': c = '#'; break;
 622 -                case '(': c = '['; break;
 623 -                case ')': c = ']'; break;
 624 -                case '<': c = '{'; break;
 625 -                case '>': c = '}'; break;
 626 -                case '/': c = '\\'; break;
 627 -                case '\'': c = '^'; break;
 628 -                case '!': c = '|'; break;
 629 -                case '-': c = '~'; break;
 630 -                default:
 631 -                        unch(c);
 632 -                        unch('?');
 633 -                        return '?';
 634 -                }
 635 -                unch(c);
 636 -                goto again;
  616+                return '?';
637617         default:
 638618                 return c;
 639619         }
     
 !
691671         extern struct initar *initar;
 692672         struct includ ibuf;
 693673         struct includ *ic;
<>694 -        int c, otrulvl;
  674+        int otrulvl;
695675 
 696676         ic = &ibuf;
 697677         ic->next = ifiles;
 698678 
<>699 -        slow = 0;
700679         if (file != NULL) {
 701680                 if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
 702681                         return -1;
     
 !
723702 
 724703         otrulvl = trulvl;
 725704 
<>726 -        if ((c = yylex()) != 0)
 727 -                error("yylex returned %d", c);
  705+        fastscan();
728706 
<>729 -wasnl = owasnl;
730707         if (otrulvl != trulvl || flslvl)
 731708                 error("unterminated conditional");
 732709 
     
 !
763740         extern int dflag;
 764741         if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
 765742 #endif
<>766 -        unput(c);
  743+#if 0
  744+if (c == 10) {
  745+        printf("c == 10!!!\n");
767746 }
<> 747+#endif
  748+        unch(c);
  749+}
768750 
 769751 int yywrap(void) { return 1; }
 770752 
     
 !
810792         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
 811793                 yylval.node.op = UNUMBER;
 812794         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
<>813 -                /* too large for signed */
  795+                /* too large for signed, see 6.4.4.1 */
814796                 error("Constant \"%s\" is out of range", yytext);
 815797 }
 816798 
     
 !
860842 {
 861843         int t;
 862844 
<>863 -        slow = 1;
 864 -        while ((t = yylex()) == WSPACE)
  845+        while ((t = sloscan()) == WSPACE)
865846                 ;
 866847         if (t != '\n') {
 867848                 if (ignore) {
 868849                         warning("newline expected, got \"%s\"", yytext);
 869850                         /* ignore rest of line */
<>870 -                        while ((t = yylex()) && t != '\n')
  851+                        while ((t = sloscan()) && t != '\n')
871852                                 ;
 872853                 }
 873854                 else
 874855                         error("newline expected, got \"%s\"", yytext);
 875856         }
<>876 -        slow = 0;
877857 }
 878858 
 879859 static void
     
 !
906886 
 907887         if (flslvl) {
 908888                 /* just ignore the rest of the line */
<>909 -                while (input() != '\n')
  889+                while (inch() != '\n')
910890                         ;
<>911 -                unput('\n');
  891+                unch('\n');
912892                 flslvl++;
 913893                 return;
 914894         }
<>915 -        slow = 1;
916895         do
<>917 -                t = yylex();
  896+                t = sloscan();
918897         while (t == WSPACE);
 919898         if (t != IDENT)
 920899                 error("bad ifdef");
<>921 -        slow = 0;
922900         if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
 923901                 trulvl++;
 924902         else
     
 !
931909 {
 932910         int t;
 933911 
<>934 -        slow = 1;
935912         do
<>936 -                t = yylex();
  913+                t = sloscan();
937914         while (t == WSPACE);
 938915         if (t != IDENT)
 939916                 error("bad ifndef");
<>940 -        slow = 0;
941917         if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
 942918                 trulvl++;
 943919         else
     
 !
962938         chknl(1);
 963939 }
 964940 
<>965 -/*
 966 - * Note! Ugly!
 967 - * Walk over the string s and search for defined, and replace it with
 968 - * spaces and a 1 or 0.
 969 - */
970941 static void
<>971 -fixdefined(usch *s)
 972 -{
 973 -        usch *bc, oc;
 974 -
 975 -        for (; *s; s++) {
 976 -                if (*s != 'd')
 977 -                        continue;
 978 -                if (memcmp(s, "defined", 7))
 979 -                        continue;
 980 -                /* Ok, got defined, can scratch it now */
 981 -                memset(s, ' ', 7);
 982 -                s += 7;
 983 -#define WSARG(x) (x == ' ' || x == '\t')
 984 -                if (*s != '(' && !WSARG(*s))
 985 -                        continue;
 986 -                while (WSARG(*s))
 987 -                        s++;
 988 -                if (*s == '(')
 989 -                        s++;
 990 -                while (WSARG(*s))
 991 -                        s++;
 992 -#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
 993 -#define NUMARG(x) (x >= '0' && x <= '9')
 994 -                if (!IDARG(*s))
 995 -                        error("bad defined arg");
 996 -                bc = s;
 997 -                while (IDARG(*s) || NUMARG(*s))
 998 -                        s++;
 999 -                oc = *s;
 1000 -                *s = 0;
 1001 -                *bc = (lookup(bc, FIND) != 0) + '0';
 1002 -                memset(bc+1, ' ', s-bc-1);
 1003 -                *s = oc;
 1004 -        }
 1005 -}
 1006 -
 1007 -/*
 1008 - * get the full line of identifiers after an #if, pushback a WARN and
 1009 - * the line and prepare for expmac() to expand.
 1010 - * This is done before switching state.  When expmac is finished,
 1011 - * pushback the expanded line, change state and call yyparse.
 1012 - */
 1013 -static void
 1014 -storepb(void)
 1015 -{
 1016 -        usch *opb = stringbuf;
 1017 -        int c;
 1018 -
 1019 -        while ((c = input()) != '\n') {
 1020 -                if (c == '/') {
 1021 -                         if ((c = input()) == '*') {
 1022 -                                /* ignore comments here whatsoever */
 1023 -                                usch *g = stringbuf;
 1024 -                                getcmnt();
 1025 -                                stringbuf = g;
 1026 -                                continue;
 1027 -                        } else if (c == '/') {
 1028 -                                while ((c = input()) && c != '\n')
 1029 -                                        ;
 1030 -                                break;
 1031 -                        }
 1032 -                        unput(c);
 1033 -                        c = '/';
 1034 -                }
 1035 -                savch(c);
 1036 -        }
 1037 -        cunput('\n');
 1038 -        savch(0);
 1039 -        fixdefined(opb); /* XXX can fail if #line? */
 1040 -        cunput(1); /* WARN XXX */
 1041 -        unpstr(opb);
 1042 -        stringbuf = opb;
 1043 -        slow = 1;
 1044 -        expmac(NULL);
 1045 -        slow = 0;
 1046 -        /* line now expanded */
 1047 -        while (stringbuf > opb)
 1048 -                cunput(*--stringbuf);
 1049 -}
 1050 -
 1051 -static void
1052942 ifstmt(void)
 1053943 {
 1054944         if (flslvl == 0) {
<>1055 -                slow = 1;
1056945                 if (yyparse())
 1057946                         ++trulvl;
 1058947                 else
 1059948                         ++flslvl;
<>1060 -                slow = 0;
1061949         } else
 1062950                 ++flslvl;
 1063951 }
     
 !
1073961                 else if (--flslvl!=0)
 1074962                         ++flslvl;
 1075963                 else {
<>1076 -                        slow = 1;
1077964                         if (yyparse()) {
 1078965                                 ++trulvl;
 1079966                                 prtline();
 1080967                         } else
 1081968                                 ++flslvl;
<>1082 -                        slow = 0;
1083969                 }
 1084970         } else if (trulvl) {
 1085971                 ++flslvl;
     
 !
1094980         int c;
 1095981         usch *cp = stringbuf;
 1096982 
<>1097 -        while ((c = input()) && c != '\n')
  983+        while ((c = inch()) && c != '\n')
1098984                 savch(c);
 1099985         savch('\n');
 1100986         savch(0);
<>1101 -        BEGIN 0;
1102987         return cp;
 1103988 }
 1104989 
     
 !
1110995 
 1111996         if (flslvl)
 1112997                 return;
<>1113 -        c = yylex();
  998+        c = sloscan();
1114999         if (c != WSPACE && c != '\n')
 11151000                 error("bad error");
 11161001         cp = svinp();
     
 !
11251010 {
 11261011         struct symtab *np;
 11271012 
<>1128 -        slow = 1;
 1129 -        if (yylex() != WSPACE || yylex() != IDENT)
  1013+        if (sloscan() != WSPACE || sloscan() != IDENT)
11301014                 error("bad undef");
 11311015         if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
 11321016                 np->value = 0;
<>1133 -        slow = 0;
11341017         chknl(0);
 11351018 }
 11361019 
     
 !
11391022 {
 11401023         int c;
 11411024 
<>1142 -        slow = 1;
 1143 -        if (yylex() != WSPACE)
  1025+        if (sloscan() != WSPACE)
11441026                 error("bad pragma");
 11451027         if (!flslvl)
 11461028                 putstr((usch *)"#pragma ");
 11471029         do {
<>1148 -                c = input();
  1030+                c = inch();
11491031                 if (!flslvl)
 11501032                         putch(c);       /* Do arg expansion instead? */
 11511033         } while (c && c != '\n');
 11521034         if (c == '\n')
 11531035                 unch(c);
 11541036         prtline();
<>1155 -        slow = 0;
11561037 }
 11571038 
 11581039 static void
     
 !
11641045 int
 11651046 cinput()
 11661047 {
<>1167 -        return input();
  1048+        return inch();
11681049 }
<_ 1050+
  1051+/*
  1052+ * Check for (and convert) trigraphs.
  1053+ */
  1054+int
  1055+chktg()
  1056+{
  1057+        int c;
  1058+
  1059+        if ((c = inpch()) != '?') {
  1060+                unch(c);
  1061+                return 0;
  1062+        }
  1063+        switch (c = inpch()) {
  1064+        case '=': c = '#'; break;
  1065+        case '(': c = '['; break;
  1066+        case ')': c = ']'; break;
  1067+        case '<': c = '{'; break;
  1068+        case '>': c = '}'; break;
  1069+        case '/': c = '\\'; break;
  1070+        case '\'': c = '^'; break;
  1071+        case '!': c = '|'; break;
  1072+        case '-': c = '~'; break;
  1073+        default:
  1074+                unch(c);
  1075+                unch('?');
  1076+                c = 0;
  1077+        }
  1078+        return c;
  1079+}
  1080+
  1081+static struct {
  1082+        char *name;
  1083+        void (*fun)(void);
  1084+} ppd[] = {
  1085+        { "ifndef", ifndefstmt },
  1086+        { "ifdef", ifdefstmt },
  1087+        { "if", ifstmt },
  1088+        { "include", include },
  1089+        { "else", elsestmt },
  1090+        { "endif", endifstmt },
  1091+        { "error", cpperror },
  1092+        { "define", define },
  1093+        { "undef", undefstmt },
  1094+        { "line", line },
  1095+        { "pragma", pragmastmt },
  1096+        { "elif", elifstmt },
  1097+};
  1098+
  1099+/*
  1100+ * Handle a preprocessor directive.
  1101+ */
  1102+void
  1103+ppdir(void)
  1104+{
  1105+        char bp[10];
  1106+        int ch, i;
  1107+
  1108+        while ((ch = inch()) == ' ' || ch == '\n')
  1109+                ;
  1110+        if (ch < 'a' || ch > 'z')
  1111+                goto out; /* something else, ignore */
  1112+        i = 0;
  1113+        do {
  1114+                bp[i++] = ch;
  1115+                if (i == sizeof(bp)-1)
  1116+                        goto out; /* too long */
  1117+                ch = inch();
  1118+        } while (ch >= 'a' && ch <= 'z');
  1119+        unch(ch);
  1120+        bp[i++] = 0;
  1121+
  1122+        /* got keyword */
  1123+#define SZ (int)(sizeof(ppd)/sizeof(ppd[0]))
  1124+        for (i = 0; i < SZ; i++)
  1125+                if (bp[0] == ppd[i].name[0] && strcmp(bp, ppd[i].name) == 0)
  1126+                        break;
  1127+        if (i == SZ)
  1128+                goto out;
  1129+
  1130+        /* Found matching keyword */
  1131+        (*ppd[i].fun)();
  1132+        return;
  1133+
  1134+out:    while ((ch = inch()) != '\n' && ch != -1)
  1135+                ;
  1136+        unch('\n');
  1137+}
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-10-31 13:12 +0100