Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.101
 
1.102
 
MAIN:plunky:20121107095159
 
token.c
_>11 /*      $Id$    */
 22 
 33 /*
 44  * Copyright (c) 2004,2009 Anders Magnusson. All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  *
 1515  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1616  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1717  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1818  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 1919  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2121  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2222  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2323  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 
 2727 /*
 2828  * Tokenizer for the C preprocessor.
 2929  * There are three main routines:
 3030  *      - fastscan() loops over the input stream searching for magic
 3131  *              characters that may require actions.
 3232  *      - sloscan() tokenize the input stream and returns tokens.
 3333  *              It may recurse into itself during expansion.
 3434  *      - yylex() returns something from the input stream that
 3535  *              is suitable for yacc.
 3636  *
 3737  *      Other functions of common use:
 3838  *      - inpch() returns a raw character from the current input stream.
 3939  *      - inch() is like inpch but \\n and trigraphs are expanded.
 4040  *      - unch() pushes back a character to the input stream.
 4141  */
 4242 
 4343 #include "config.h"
 4444 
 4545 #include <stdlib.h>
 4646 #include <string.h>
 4747 #ifdef HAVE_UNISTD_H
 4848 #include <unistd.h>
 4949 #endif
 5050 #include <fcntl.h>
 5151 
 5252 #include "compat.h"
 5353 #include "cpp.h"
 5454 #include "cpy.h"
 5555 
 5656 static void cvtdig(int rad);
 5757 static int charcon(usch *);
 5858 static void elsestmt(void);
 5959 static void ifdefstmt(void);
 6060 static void ifndefstmt(void);
 6161 static void endifstmt(void);
 6262 static void ifstmt(void);
 6363 static void cpperror(void);
<>64 -static void pragmastmt(void);
 65 -static void undefstmt(void);
6664 static void cppwarning(void);
<> 65+static void undefstmt(void);
  66+static void pragmastmt(void);
6767 static void elifstmt(void);
<>68 -static int chktg(void);
 69 -static int inpch(void);
 70 -static int inch(void);
7168 
 7269 #define PUTCH(ch) if (!flslvl) putch(ch)
 7370 /* protection against recursion in #include */
 7471 #define MAX_INCLEVEL    100
 7572 static int inclevel;
 7673 
<>77 -/* get next character unaltered */
 78 -#define NXTCH() (ifiles->curptr < ifiles->maxread ? *ifiles->curptr++ : inpch())
 79 -
8074 usch yytext[CPPBUF];
 8175 
 8276 struct includ *ifiles;
 8377 
 8478 /* some common special combos for init */
 8579 #define C_NL    (C_SPEC|C_WSNL)
 8680 #define C_DX    (C_SPEC|C_ID|C_DIGIT|C_HEX)
 8781 #define C_I     (C_SPEC|C_ID|C_ID0)
 8882 #define C_IP    (C_SPEC|C_ID|C_ID0|C_EP)
 8983 #define C_IX    (C_SPEC|C_ID|C_ID0|C_HEX)
 9084 #define C_IXE   (C_SPEC|C_ID|C_ID0|C_HEX|C_EP)
 9185 
 9286 usch spechr[256] = {
 9387         0,      0,      0,      0,      C_SPECC_SPEC0,      0,
 9488         0,      C_WSNLC_NL,   0,      0,      C_WSNL0,      0,
 9589         0,      0,      0,      0,      0,      0,      0,      0,
 9690         0,      0,      0,      0,      0,      0,      0,      0,
 9791 
 9892         C_WSNLC_2,    C_SPEC0,      0,      0,      C_2,    C_SPEC,
 9993         0,      0,      0,      C_2,    0,      C_2,    0,      C_SPEC|C_2,
 10094         C_DX,   C_DX,   C_DX,   C_DX,   C_DX,   C_DX,   C_DX,   C_DX,
<>101 -        C_DX,   C_DX,   0,      0,      C_2,    C_2,    C_2,    C_SPEC,
  95+        C_DX,   C_DX,   0,      0,      C_2,    C_2,    C_2,    0,
10296 
 10397         0,      C_IX,   C_IX,   C_IX,   C_IX,   C_IXE,  C_IX,   C_I,
 10498         C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
 10599         C_IP,   C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
<>106 -        C_I,    C_I,    C_I,    0,      C_SPEC0,      0,      C_I,
  100+        C_I,    C_I,    C_I,    0,      0,      0,      0,      C_I,
107101 
 108102         0,      C_IX,   C_IX,   C_IX,   C_IX,   C_IXE,  C_IX,   C_I,
 109103         C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
 110104         C_IP,   C_I,    C_I,    C_I,    C_I,    C_I,    C_I,    C_I,
 111105         C_I,    C_I,    C_I,    0,      C_2,    0,      0,      0,
 112106 };
 113107 
<> 108+/*
  109+ * fill up the input buffer
  110+ */
  111+static int
  112+inpbuf(void)
  113+{
  114+        int len;
  115+
  116+        if (ifiles->infil == -1)
  117+                return 0;
  118+        len = read(ifiles->infil, ifiles->buffer, CPPBUF);
  119+        if (len == -1)
  120+                error("read error on file %s", ifiles->orgfn);
  121+        if (len > 0) {
  122+                ifiles->buffer[len] = 0;
  123+                ifiles->curptr = ifiles->buffer;
  124+                ifiles->maxread = ifiles->buffer + len;
  125+        }
  126+        return len;
  127+}
  128+
  129+/*
  130+ * return a raw character from the input stream
  131+ */
  132+static inline int
  133+inpch(void)
  134+{
  135+
  136+        do {
  137+                if (ifiles->curptr < ifiles->maxread)
  138+                        return *ifiles->curptr++;
  139+        } while (inpbuf() > 0);
  140+
  141+        return -1;
  142+}
  143+
  144+/*
  145+ * push a character back to the input stream
  146+ */
114147 static void
 115148 unch(int c)
 116149 {
 117150         if (c == -1)
 118151                 return;
 119152                 
<>120 -        --ifiles->curptr;
  153+        ifiles->curptr--;
121154         if (ifiles->curptr < ifiles->bbuf)
 122155                 error("pushback buffer full");
 123156         *ifiles->curptr = (usch)c;
 124157 }
 125158 
<> 159+/*
  160+ * Check for (and convert) trigraphs.
  161+ */
  162+static int
  163+chktg(void)
  164+{
  165+        int ch;
  166+
  167+        if ((ch = inpch()) != '?') {
  168+                unch(ch);
  169+                return 0;
  170+        }
  171+
  172+        switch (ch = inpch()) {
  173+        case '='return '#';
  174+        case '('return '[';
  175+        case ')'return ']';
  176+        case '<'return '{';
  177+        case '>'return '}';
  178+        case '/'return '\\';
  179+        case '\'': return '^';
  180+        case '!'return '|';
  181+        case '-'return '~';
  182+        }
  183+
  184+        unch(ch);
  185+        unch('?');
  186+        return 0;
  187+}
  188+
  189+/*
  190+ * check for (and eat) end-of-line
  191+ */
  192+static int
  193+chkeol(void)
  194+{
  195+        int ch;
  196+
  197+        ch = inpch();
  198+        if (ch == '\r') {
  199+                ch = inpch();
  200+                if (ch == '\n')
  201+                        return '\n';
  202+
  203+                unch(ch);
  204+                unch('\r');
  205+                return 0;
  206+        }
  207+        if (ch == '\n')
  208+                return '\n';
  209+
  210+        unch(ch);
  211+        return 0;
  212+}
  213+
  214+/*
  215+ * return next char, after converting trigraphs and
  216+ * skipping escaped line endings
  217+ */
  218+static inline int
  219+inch(void)
  220+{
  221+        int ch;
  222+
  223+        for (;;) {
  224+                ch = inpch();
  225+                if (ch == '?' && (ch = chktg()) == 0)
  226+                        return '?';
  227+                if (ch != '\\' || chkeol() == 0)
  228+                        return ch;
  229+                ifiles->escln++;
  230+        }
  231+}
  232+
126233 static void
 127234 eatcmnt(void)
 128235 {
 129236         int ch;
 130237 
 131238         if (Cflag) { PUTCH('/'); PUTCH('*'); }
 132239         for (;;) {
 133240                 ch = inch();
 134241                 if (ch == '\n') {
 135242                         ifiles->lineno++;
<>136 -                        if (!Cflag) PUTCH('\n');
  243+                        putch('\n');
  244+                        continue;
137245                 }
 138246                 if (ch == -1)
 139247                         break;
 140248                 if (ch == '*') {
 141249                         ch = inch();
 142250                         if (ch == '/') {
 143251                                 if (Cflag) {
 144252                                         PUTCH('*');
 145253                                         PUTCH('/');
 146254                                 } else
 147255                                         PUTCH(' ');
 148256                                 break;
 149257                         }
 150258                         unch(ch);
 151259                         ch = '*';
 152260                 }
 153261                 if (Cflag) PUTCH(ch);
 154262         }
 155263 }
 156264 
 157265 /*
 158266  * Scan quickly the input file searching for:
 159267  *      - '#' directives
 160268  *      - keywords (if not flslvl)
 161269  *      - comments
 162270  *
 163271  *      Handle strings, numbers and trigraphs with care.
 164272  *      Only data from pp files are scanned here, never any rescans.
 165273  *      TODO: Only print out strings before calling other functions.
 166274  */
 167275 static void
 168276 fastscan(void)
 169277 {
 170278         struct symtab *nl;
<>171 -        int ch, i = 0;
 172 -        int nnl = 0;
  279+        int ch, i;
173280         usch *cp;
 174281 
 175282         goto run;
 176283         for (;;) {
<>177 -                ch = NXTCH();
  284+                ch = inch();
178285 xloop:          if (ch == -1)
 179286                         return;
 180287 #ifdef PCC_DEBUG
 181288                 if (dflag>1)
 182289                         printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
 183290 #endif
 184291                 if ((spechr[ch] & C_SPEC) == 0) {
 185292                         PUTCH(ch);
 186293                         continue;
 187294                 }
 188295                 switch (ch) {
 189296                 case EBLOCK:
 190297                 case WARN:
 191298                 case CONC:
 192299                         error("bad char passed");
 193300                         break;
 194301 
 195302                 case '/': /* Comments */
 196303                         if ((ch = inch()) == '/') {
 197304 cppcmt:                         if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
 198305                                 do {
 199306                                         if (Cflag) PUTCH(ch);
 200307                                         ch = inch();
 201308                                 } while (ch != -1 && ch != '\n');
 202309                                 goto xloop;
 203310                         } else if (ch == '*') {
 204311                                 eatcmnt();
<>205 -                                continue;
206312                         } else {
 207313                                 PUTCH('/');
 208314                                 goto xloop;
 209315                         }
 210316                         break;
 211317 
<>212 -                case '?'/* trigraphs */
 213 -                        if ((ch = chktg()))
 214 -                                goto xloop;
 215 -                        PUTCH('?');
 216 -                        break;
 217 -
 218 -                case '\\':
 219 -                        if ((ch = NXTCH()) == '\n') {
 220 -                                ifiles->lineno++;
 221 -                                continue;
 222 -                        }
 223 -                        PUTCH('\\');
 224 -                        goto xloop;
 225 -
226318                 case '\n': /* newlines, for pp directives */
<>227 -                        while (nnl > 0) { PUTCH('\n'); nnl--; ifiles->lineno++; }
 228 -run2:                   ifiles->lineno++;
 229 -                        do {
 230 -                                PUTCH(ch);
 231 -run:                            ch = NXTCH();
  319+                        i = ifiles->escln + 1;
  320+                        ifiles->lineno += i;
  321+                        ifiles->escln = 0;
  322+                        while (i-- > 0)
  323+                                putch('\n');
  324+run:                    for(;;) {
  325+                                ch = inch();
232326                                 if (ch == '/') {
<>233 -                                        ch = NXTCH();
  327+                                        ch = inch();
234328                                         if (ch == '/')
 235329                                                 goto cppcmt;
 236330                                         if (ch == '*') {
 237331                                                 eatcmnt();
<>238 -                                                goto run;
  332+                                                continue;
239333                                         }
 240334                                         unch(ch);
 241335                                         ch = '/';
 242336                                 }
<>243 -                        } while (ch == ' ' || ch == '\t');
 244 -                        if (ch == '\\') {
 245 -                                ch = NXTCH();
 246 -                                if (ch == '\n')
 247 -                                        goto run2;
 248 -                                unch(ch);
 249 -                                ch = '\\';
  337+                                if (ch != ' ' && ch != '\t')
  338+                                        break;
  339+                                PUTCH(ch);
250340                         }
 251341                         if (ch == '#') {
 252342                                 ppdir();
 253343                                 continue;
 254344                         } else if (ch == '%') {
<>255 -                                ch = NXTCH();
  345+                                ch = inch();
256346                                 if (ch == ':') {
 257347                                         ppdir();
 258348                                         continue;
 259349                                 }
 260350                                 unch(ch);
 261351                                 ch = '%';
<>262 -                        } else if (ch == '?') {
 263 -                                if ((ch = chktg()) == '#') {
 264 -                                        ppdir();
 265 -                                        continue;
 266 -                                } else if (ch == 0)
 267 -                                        ch = '?';
268352                         }
 269353                         goto xloop;
 270354 
 271355                 case '\"': /* strings */
 272356 str:                    PUTCH(ch);
<>273 -                        while ((ch = NXTCH()) != '\"') {
  357+                        while ((ch = inch()) != '\"') {
  358+                                if (ch == '\\') {
  359+                                        PUTCH('\\');
  360+                                        ch = inch();
  361+                                }
274362                                 if (ch == '\n')
 275363                                         goto xloop;
<>276 -                                if (ch == '\\') {
 277 -                                        if ((ch = NXTCH()) != '\n') {
 278 -                                                PUTCH('\\');
 279 -                                                PUTCH(ch);
 280 -                                        } else
 281 -                                                nnl++;
 282 -                                        continue;
 283 -                                }
284364                                 if (ch == -1)
 285365                                         return;
 286366                                 PUTCH(ch);
 287367                         }
 288368                         PUTCH(ch);
 289369                         break;
 290370 
 291371                 case '.'/* for pp-number */
 292372                         PUTCH(ch);
<>293 -                        ch = NXTCH();
  373+                        ch = inch();
294374                         if (ch < '0' || ch > '9')
 295375                                 goto xloop;
<> 376+
296377                         /* FALLTHROUGH */
 297378                 case '0': case '1': case '2': case '3': case '4':
 298379                 case '5': case '6': case '7': case '8': case '9':
 299380                         do {
 300381 nxp:                            PUTCH(ch);
<>301 -nxt:                            ch = NXTCH();
 302 -                                if (ch == '\\') {
 303 -                                        ch = NXTCH();
 304 -                                        if (ch == '\n') {
 305 -                                                nnl++;
 306 -                                                goto nxt;
 307 -                                        }
 308 -                                        unch(ch);
 309 -                                        ch = '\\';
 310 -                                }
  382+                                ch = inch();
311383                                 if (ch == -1)
 312384                                         return;
 313385                                 if (spechr[ch] & C_EP) {
 314386                                         PUTCH(ch);
<>315 -                                        ch = NXTCH();
  387+                                        ch = inch();
316388                                         if (ch == '-' || ch == '+')
 317389                                                 goto nxp;
 318390                                         if (ch == -1)
 319391                                                 return;
 320392                                 }
 321393                         } while ((spechr[ch] & C_ID) || (ch == '.'));
 322394                         goto xloop;
 323395 
 324396                 case '\'': /* character literal */
 325397 con:                    PUTCH(ch);
 326398                         if (tflag)
<>327 -                                continue; /* character constants ignored */
 328 -                        while ((ch = NXTCH()) != '\'') {
 329 -                                if (ch == '\n')
 330 -                                        goto xloop;
  399+                                break; /* character constants ignored */
  400+                        while ((ch = inch()) != '\'') {
331401                                 if (ch == '\\') {
<>332 -                                        if ((ch = NXTCH()) != '\n') {
 333 -                                                PUTCH('\\');
 334 -                                                PUTCH(ch);
 335 -                                        } else
 336 -                                                nnl++;
 337 -                                        continue;
  402+                                        PUTCH('\\');
  403+                                        ch = inch();
338404                                 }
<> 405+                                if (ch == '\n')
  406+                                        goto xloop;
339407                                 if (ch == -1)
 340408                                         return;
 341409                                 PUTCH(ch);
 342410                         }
 343411                         PUTCH(ch);
 344412                         break;
 345413 
 346414                 case 'L':
<>347 -                        ch = NXTCH();
  415+                        ch = inch();
348416                         if (ch == '\"') {
 349417                                 PUTCH('L');
 350418                                 goto str;
 351419                         }
 352420                         if (ch == '\'') {
 353421                                 PUTCH('L');
 354422                                 goto con;
 355423                         }
 356424                         unch(ch);
 357425                         ch = 'L';
<> 426+
358427                         /* FALLTHROUGH */
 359428                 default:
<> 429+#ifdef PCC_DEBUG
360430                         if ((spechr[ch] & C_ID) == 0)
 361431                                 error("fastscan");
<>362 -                        if (flslvl) {
 363 -                                while (ch != -1 && (spechr[ch] & C_ID))
 364 -                                        ch = NXTCH();
 365 -                                goto xloop;
 366 -                        }
  432+#endif
367433                         i = 0;
 368434                         do {
 369435                                 yytext[i++] = (usch)ch;
<>370 -                                ch = NXTCH();
 371 -                                if (ch == '\\') {
 372 -                                        ch = NXTCH();
 373 -                                        if (ch != '\n') {
 374 -                                                unch(ch);
 375 -                                                ch = '\\';
 376 -                                        } else {
 377 -                                                putch('\n');
 378 -                                                ifiles->lineno++;
 379 -                                                ch = NXTCH();
 380 -                                        }
 381 -                                }
 382 -                                if (ch == -1)
 383 -                                        return;
 384 -                        } while (spechr[ch] & C_ID);
  436+                                ch = inch();
  437+                        } while (ch != -1 && (spechr[ch] & C_ID));
385438 
<> 439+                        if (flslvl)
  440+                                goto xloop;
  441+
386442                         yytext[i] = 0;
 387443                         unch(ch);
 388444 
 389445                         cp = stringbuf;
 390446                         if ((nl = lookup(yytext, FIND)) && kfind(nl)) {
 391447                                 putstr(stringbuf);
 392448                         } else
 393449                                 putstr(yytext);
 394450                         stringbuf = cp;
 395451 
 396452                         break;
 397453                 }
 398454         }
 399455 }
 400456 
 401457 int
 402458 sloscan(void)
 403459 {
 404460         int ch;
 405461         int yyp;
 406462 
 407463 zagain:
 408464         yyp = 0;
 409465         ch = inch();
 410466         yytext[yyp++] = (usch)ch;
 411467         switch (ch) {
 412468         case -1:
 413469                 return 0;
 414470         case '\n':
 415471                 /* sloscan() never passes \n, that's up to fastscan() */
 416472                 unch(ch);
 417473                 yytext[yyp] = 0;
 418474                 return ch;
 419475 
 420476         case '\r': /* Ignore CR's */
 421477                 yyp = 0;
 422478                 break;
 423479 
 424480         case '0': case '1': case '2': case '3': case '4': case '5':
 425481         case '6': case '7': case '8': case '9':
 426482                 /* readin a "pp-number" */
 427483 ppnum:          for (;;) {
 428484                         ch = inch();
 429485                         if (ch == -1)
 430486                                 break;
 431487                         if (spechr[ch] & C_EP) {
 432488                                 yytext[yyp++] = (usch)ch;
 433489                                 ch = inch();
 434490                                 if (ch == '-' || ch == '+') {
 435491                                         yytext[yyp++] = (usch)ch;
 436492                                 } else
 437493                                         unch(ch);
 438494                                 continue;
 439495                         }
 440496                         if ((spechr[ch] & C_ID) || ch == '.') {
 441497                                 yytext[yyp++] = (usch)ch;
 442498                                 continue;
 443499                         }
 444500                         break;
 445501                 }
 446502                 unch(ch);
 447503                 yytext[yyp] = 0;
 448504 
 449505                 return NUMBER;
 450506 
 451507         case '\'':
 452508 chlit:          
 453509                 for (;;) {
 454510                         if ((ch = inch()) == '\\') {
 455511                                 yytext[yyp++] = (usch)ch;
 456512                                 yytext[yyp++] = (usch)inch();
 457513                                 continue;
 458514                         } else if (ch == -1 || ch == '\n') {
 459515                                 /* not a constant */
 460516                                 while (yyp > 1)
 461517                                         unch(yytext[--yyp]);
 462518                                 ch = '\'';
 463519                                 goto any;
 464520                         } else
 465521                                 yytext[yyp++] = (usch)ch;
 466522                         if (ch == '\'')
 467523                                 break;
 468524                 }
 469525                 yytext[yyp] = 0;
 470526 
 471527                 return NUMBER;
 472528 
 473529         case ' ':
 474530         case '\t':
 475531                 while ((ch = inch()) == ' ' || ch == '\t')
 476532                         yytext[yyp++] = (usch)ch;
 477533                 unch(ch);
 478534                 yytext[yyp] = 0;
 479535                 return WSPACE;
 480536 
 481537         case '/':
 482538                 if ((ch = inch()) == '/') {
 483539                         do {
 484540                                 yytext[yyp++] = (usch)ch;
 485541                                 ch = inch();
 486542                         } while (ch != -1 && ch != '\n');
 487543                         yytext[yyp] = 0;
 488544                         unch(ch);
 489545                         goto zagain;
 490546                 } else if (ch == '*') {
 491547                         int c, wrn;
 492548                         extern int readmac;
 493549 
 494550                         if (Cflag && !flslvl && readmac) {
 495551                                 unch(ch);
 496552                                 yytext[yyp] = 0;
 497553                                 return CMNT;
 498554                         }
 499555 
 500556                         wrn = 0;
 501557                 more:   while ((c = inch()) != '*') {
 502558                                 if (c == -1)
 503559                                         return 0;       
 504560                                 if (c == '\n')
 505561                                         putch(c), ifiles->lineno++;
 506562                                 else if (c == EBLOCK) {
 507563                                         (void)inch();
 508564                                         (void)inch();
 509565                                 } else if (c == WARN)
 510566                                         wrn = 1;
 511567                         }
 512568                         if ((c = inch()) == -1)
 513569                                 return 0;
 514570                         if (c != '/') {
 515571                                 unch(c);
 516572                                 goto more;
 517573                         }
 518574                         if (!tflag && !Cflag && !flslvl)
 519575                                 unch(' ');
 520576                         if (wrn)
 521577                                 unch(WARN);
 522578                         goto zagain;
 523579                 }
 524580                 unch(ch);
 525581                 ch = '/';
 526582                 goto any;
 527583 
 528584         case '.':
 529585                 if ((ch = inch()) == -1)
 530586                         return 0;
 531587                 if ((spechr[ch] & C_DIGIT)) {
 532588                         yytext[yyp++] = (usch)ch;
 533589                         goto ppnum;
 534590                 } else {
 535591                         unch(ch);
 536592                         ch = '.';
 537593                 }
 538594                 goto any;
 539595 
 540596         case '\"':
 541597                 if (tflag && defining)
 542598                         goto any;
 543599         strng:
 544600                 for (;;) {
 545601                         if ((ch = inch()) == '\\') {
 546602                                 yytext[yyp++] = (usch)ch;
 547603                                 yytext[yyp++] = (usch)inch();
 548604                                 continue;
 549605                         } else if (ch == -1) {
 550606                                 break;
 551607                         } else
 552608                                 yytext[yyp++] = (usch)ch;
 553609                         if (ch == '\"')
 554610                                 break;
 555611                 }
 556612                 yytext[yyp] = 0;
 557613                 return STRING;
 558614 
 559615         case 'L':
 560616                 if ((ch = inch()) == '\"' && !tflag) {
 561617                         yytext[yyp++] = (usch)ch;
 562618                         goto strng;
 563619                 } else if (ch == '\'' && !tflag) {
 564620                         yytext[yyp++] = (usch)ch;
 565621                         goto chlit;
 566622                 }
 567623                 unch(ch);
 568624                 /* FALLTHROUGH */
 569625 
 570626         /* Yetch, all identifiers */
 571627         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 572628         case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
 573629         case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
 574630         case 's': case 't': case 'u': case 'v': case 'w': case 'x':
 575631         case 'y': case 'z':
 576632         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
 577633         case 'G': case 'H': case 'I': case 'J': case 'K':
 578634         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
 579635         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
 580636         case 'Y': case 'Z':
 581637         case '_': /* {L}({L}|{D})* */
 582638 
 583639                 /* Special hacks */
 584640                 for (;;) { /* get chars */
 585641                         if ((ch = inch()) == -1)
 586642                                 break;
 587643                         if ((spechr[ch] & C_ID)) {
 588644                                 yytext[yyp++] = (usch)ch;
 589645                         } else {
 590646                                 unch(ch);
 591647                                 break;
 592648                         }
 593649                 }
 594650                 yytext[yyp] = 0; /* need already string */
 595651                 /* end special hacks */
 596652 
 597653                 return IDENT;
 598654         default:
 599655         any:
 600656                 yytext[yyp] = 0;
 601657                 return yytext[0];
 602658 
 603659         } /* endcase */
 604660         goto zagain;
 605661 }
 606662 
 607663 int
 608664 yylex(void)
 609665 {
 610666         static int ifdef, noex;
 611667         struct symtab *nl;
 612668         int ch, c2;
 613669 
 614670         while ((ch = sloscan()) == WSPACE)
 615671                 ;
 616672         if (ch < 128 && (spechr[ch] & C_2))
<>617 -                c2 = inpch();
  673+                c2 = inch();
618674         else
 619675                 c2 = 0;
 620676 
 621677         switch (ch) {
 622678         case '=':
 623679                 if (c2 == '=') return EQ;
 624680                 break;
 625681         case '!':
 626682                 if (c2 == '=') return NE;
 627683                 break;
 628684         case '|':
 629685                 if (c2 == '|') return OROR;
 630686                 break;
 631687         case '&':
 632688                 if (c2 == '&') return ANDAND;
 633689                 break;
 634690         case '<':
 635691                 if (c2 == '<') return LS;
 636692                 if (c2 == '=') return LE;
 637693                 break;
 638694         case '>':
 639695                 if (c2 == '>') return RS;
 640696                 if (c2 == '=') return GE;
 641697                 break;
 642698         case '+':
 643699         case '-':
 644700                 if (ch == c2)
 645701                         error("invalid preprocessor operator %c%c", ch, c2);
 646702                 break;
 647703 
 648704         case '/':
 649705                 if (Cflag == 0 || c2 != '*')
 650706                         break;
 651707                 /* Found comment that need to be skipped */
 652708                 for (;;) {
<>653 -                        ch = inpch();
  709+                        ch = inch();
654710                 c1:     if (ch != '*')
 655711                                 continue;
<>656 -                        if ((ch = inpch()) == '/')
  712+                        if ((ch = inch()) == '/')
657713                                 break;
 658714                         goto c1;
 659715                 }
 660716                 return yylex();
 661717 
 662718         case NUMBER:
 663719                 if (yytext[0] == '\'') {
 664720                         yylval.node.op = NUMBER;
 665721                         yylval.node.nd_val = charcon(yytext);
 666722                 } else
 667723                         cvtdig(yytext[0] != '0' ? 10 :
 668724                             yytext[1] == 'x' || yytext[1] == 'X' ? 16 : 8);
 669725                 return NUMBER;
 670726 
 671727         case IDENT:
 672728                 if (strcmp((char *)yytext, "defined") == 0) {
 673729                         ifdef = 1;
 674730                         return DEFINED;
 675731                 }
 676732                 nl = lookup(yytext, FIND);
 677733                 if (ifdef) {
 678734                         yylval.node.nd_val = nl != NULL;
 679735                         ifdef = 0;
 680736                 } else if (nl && noex == 0) {
 681737                         usch *och = stringbuf;
 682738                         int i;
 683739 
 684740                         i = kfind(nl);
 685741                         unch(WARN);
 686742                         if (i)
 687743                                 unpstr(stringbuf);
 688744                         else
 689745                                 unpstr(nl->namep);
 690746                         stringbuf = och;
 691747                         noex = 1;
 692748                         return yylex();
 693749                 } else {
 694750                         yylval.node.nd_val = 0;
 695751                 }
 696752                 yylval.node.op = NUMBER;
 697753                 return NUMBER;
 698754         case WARN:
 699755                 noex = 0;
 700756                 /* FALLTHROUGH */
 701757         case PHOLD:
 702758                 return yylex();
 703759         default:
 704760                 return ch;
 705761         }
 706762         unch(c2);
 707763         return ch;
 708764 }
 709765 
<>710 -static int
 711 -inpch(void)
 712 -{
 713 -        int len;
 714 -
 715 -        if (ifiles->curptr < ifiles->maxread)
 716 -                return *ifiles->curptr++;
 717 -
 718 -        if (ifiles->infil == -1)
 719 -                return -1;
 720 -        if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
 721 -                error("read error on file %s", ifiles->orgfn);
 722 -        if (len == 0)
 723 -                return -1;
 724 -        ifiles->buffer[len] = 0;
 725 -        ifiles->curptr = ifiles->buffer;
 726 -        ifiles->maxread = ifiles->buffer + len;
 727 -        return inpch();
 728 -}
 729 -
 730 -static int
 731 -inch(void)
 732 -{
 733 -        int c;
 734 -
 735 -again:  switch (c = inpch()) {
 736 -        case '\\': /* continued lines */
 737 -msdos:          if ((c = inpch()) == '\n') {
 738 -                        ifiles->lineno++;
 739 -                        putch('\n');
 740 -                        goto again;
 741 -                } else if (c == '\r')
 742 -                        goto msdos;
 743 -                unch(c);
 744 -                return '\\';
 745 -        case '?': /* trigraphs */
 746 -                if ((c = chktg())) {
 747 -                        unch(c);
 748 -                        goto again;
 749 -                }
 750 -                return '?';
 751 -        default:
 752 -                return c;
 753 -        }
 754 -}
 755 -
756766 /*
 757767  * Let the command-line args be faked defines at beginning of file.
 758768  */
 759769 static void
 760770 prinit(struct initar *it, struct includ *ic)
 761771 {
 762772         const char *pre, *post;
 763773         char *a;
 764774 
 765775         if (it->next)
 766776                 prinit(it->next, ic);
 767777         pre = post = NULL; /* XXX gcc */
 768778         switch (it->type) {
 769779         case 'D':
 770780                 pre = "#define ";
 771781                 if ((a = strchr(it->str, '=')) != NULL) {
 772782                         *a = ' ';
 773783                         post = "\n";
 774784                 } else
 775785                         post = " 1\n";
 776786                 break;
 777787         case 'U':
 778788                 pre = "#undef ";
 779789                 post = "\n";
 780790                 break;
 781791         case 'i':
 782792                 pre = "#include \"";
 783793                 post = "\"\n";
 784794                 break;
 785795         default:
 786796                 error("prinit");
 787797         }
 788798         strlcat((char *)ic->buffer, pre, CPPBUF+1);
 789799         strlcat((char *)ic->buffer, it->str, CPPBUF+1);
 790800         if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
 791801                 error("line exceeds buffer size");
 792802 
 793803         ic->lineno--;
 794804         while (*ic->maxread)
 795805                 ic->maxread++;
 796806 }
 797807 
 798808 /*
 799809  * A new file included.
 800810  * If ifiles == NULL, this is the first file and already opened (stdin).
 801811  * Return 0 on success, -1 if file to be included is not found.
 802812  */
 803813 int
 804814 pushfile(const usch *file, const usch *fn, int idx, void *incs)
 805815 {
 806816         extern struct initar *initar;
 807817         struct includ ibuf;
 808818         struct includ *ic;
 809819         int otrulvl;
 810820 
 811821         ic = &ibuf;
 812822         ic->next = ifiles;
 813823 
 814824         if (file != NULL) {
 815825                 if ((ic->infil = open((const char *)file, O_RDONLY)) < 0)
 816826                         return -1;
 817827                 ic->orgfn = ic->fname = file;
 818828                 if (++inclevel > MAX_INCLEVEL)
<>819 -                        error("Limit for nested includes exceeded");
  829+                        error("limit for nested includes exceeded");
820830         } else {
 821831                 ic->infil = 0;
 822832                 ic->orgfn = ic->fname = (const usch *)"<stdin>";
 823833         }
 824834 #ifndef BUF_STACK
 825835         ic->bbuf = malloc(BBUFSZ);
 826836 #endif
 827837         ic->buffer = ic->bbuf+NAMEMAX;
 828838         ic->curptr = ic->buffer;
 829839         ifiles = ic;
 830840         ic->lineno = 1;
<> 841+        ic->escln = 0;
831842         ic->maxread = ic->curptr;
 832843         ic->idx = idx;
 833844         ic->incs = incs;
 834845         ic->fn = fn;
 835846         prtline();
 836847         if (initar) {
 837848                 int oin = ic->infil;
 838849                 ic->infil = -1;
 839850                 *ic->maxread = 0;
 840851                 prinit(initar, ic);
 841852                 initar = NULL;
 842853                 if (dMflag)
 843854                         xwrite(ofd, ic->buffer, strlen((char *)ic->buffer));
 844855                 fastscan();
 845856                 prtline();
 846857                 ic->infil = oin;
 847858         }
 848859 
 849860         otrulvl = trulvl;
 850861 
 851862         fastscan();
 852863 
 853864         if (otrulvl != trulvl || flslvl)
 854865                 error("unterminated conditional");
 855866 
 856867 #ifndef BUF_STACK
 857868         free(ic->bbuf);
 858869 #endif
 859870         ifiles = ic->next;
 860871         close(ic->infil);
 861872         inclevel--;
 862873         return 0;
 863874 }
 864875 
 865876 /*
 866877  * Print current position to output file.
 867878  */
 868879 void
 869880 prtline(void)
 870881 {
 871882         usch *sb = stringbuf;
 872883 
 873884         if (Mflag) {
 874885                 if (dMflag)
 875886                         return; /* no output */
 876887                 if (ifiles->lineno == 1) {
 877888                         sheap("%s: %s\n", Mfile, ifiles->fname);
 878889                         if (MPflag &&
 879890                             strcmp((const char *)ifiles->fname, (char *)MPfile))
 880891                                 sheap("%s:\n", ifiles->fname);
 881892                         xwrite(ofd, sb, stringbuf - sb);
 882893                 }
 883894         } else if (!Pflag) {
 884895                 sheap("\n# %d \"%s\"", ifiles->lineno, ifiles->fname);
 885896                 if (ifiles->idx == SYSINC)
 886897                         sheap(" 3");
 887898                 sheap("\n");
 888899                 putstr(sb);
 889900         }
 890901         stringbuf = sb;
 891902 }
 892903 
 893904 void
 894905 cunput(int c)
 895906 {
 896907 #ifdef PCC_DEBUG
 897908 //      if (dflag)printf(": '%c'(%d)\n", c > 31 ? c : ' ', c);
 898909 #endif
 899910         unch(c);
 900911 }
 901912 
 902913 static int
 903914 dig2num(int c)
 904915 {
 905916         if (c >= 'a')
 906917                 c = c - 'a' + 10;
 907918         else if (c >= 'A')
 908919                 c = c - 'A' + 10;
 909920         else
 910921                 c = c - '0';
 911922         return c;
 912923 }
 913924 
 914925 /*
 915926  * Convert string numbers to unsigned long long and check overflow.
 916927  */
 917928 static void
 918929 cvtdig(int rad)
 919930 {
 920931         unsigned long long rv = 0;
 921932         unsigned long long rv2 = 0;
 922933         usch *y = yytext;
 923934         int c;
 924935 
 925936         c = *y++;
 926937         if (rad == 16)
 927938                 y++;
 928939         while ((spechr[c] & C_HEX)) {
 929940                 rv = rv * rad + dig2num(c);
 930941                 /* check overflow */
 931942                 if (rv / rad < rv2)
<>932 -                        error("Constant \"%s\" is out of range", yytext);
  943+                        error("constant \"%s\" is out of range", yytext);
933944                 rv2 = rv;
 934945                 c = *y++;
 935946         }
 936947         y--;
 937948         while (*y == 'l' || *y == 'L')
 938949                 y++;
 939950         yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
 940951         yylval.node.nd_uval = rv;
 941952         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
 942953                 yylval.node.op = UNUMBER;
 943954         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
 944955                 /* too large for signed, see 6.4.4.1 */
<>945 -                error("Constant \"%s\" is out of range", yytext);
  956+                error("constant \"%s\" is out of range", yytext);
946957 }
 947958 
 948959 static int
 949960 charcon(usch *p)
 950961 {
 951962         int val, c;
 952963 
 953964         p++; /* skip first ' */
 954965         val = 0;
 955966         if (*p++ == '\\') {
 956967                 switch (*p++) {
 957968                 case 'a': val = '\a'; break;
 958969                 case 'b': val = '\b'; break;
 959970                 case 'f': val = '\f'; break;
 960971                 case 'n': val = '\n'; break;
 961972                 case 'r': val = '\r'; break;
 962973                 case 't': val = '\t'; break;
 963974                 case 'v': val = '\v'; break;
 964975                 case '\"': val = '\"'; break;
 965976                 case '\'': val = '\''; break;
 966977                 case '\\': val = '\\'; break;
 967978                 case 'x':
 968979                         while ((spechr[c = *p] & C_HEX)) {
 969980                                 val = val * 16 + dig2num(c);
 970981                                 p++;
 971982                         }
 972983                         break;
 973984                 case '0': case '1': case '2': case '3': case '4':
 974985                 case '5': case '6': case '7':
 975986                         p--;
 976987                         while ((spechr[c = *p] & C_DIGIT)) {
 977988                                 val = val * 8 + (c - '0');
 978989                                 p++;
 979990                         }
 980991                         break;
 981992                 default: val = p[-1];
 982993                 }
 983994 
 984995         } else
 985996                 val = p[-1];
 986997         return val;
 987998 }
 988999 
 9891000 static void
 9901001 chknl(int ignore)
 9911002 {
 9921003         int t;
 9931004 
 9941005         while ((t = sloscan()) == WSPACE)
 9951006                 ;
 9961007         if (t != '\n') {
 9971008                 if (t) {
 9981009                         if (ignore) {
 9991010                                 warning("newline expected, got \"%s\"", yytext);
 10001011                                 /* ignore rest of line */
 10011012                                 while ((t = sloscan()) && t != '\n')
 10021013                                         ;
 10031014                         }
 10041015                         else
 10051016                                 error("newline expected, got \"%s\"", yytext);
 10061017                 } else {
 10071018                         if (ignore)
 10081019                                 warning("no newline at end of file");
 10091020                         else
 10101021                                 error("no newline at end of file");
 10111022                 }
 10121023         }
 10131024 }
 10141025 
 10151026 static void
 10161027 elsestmt(void)
 10171028 {
 10181029         if (flslvl) {
 10191030                 if (elflvl > trulvl)
 10201031                         ;
<>1021 -                else if (--flslvl!=0) {
  1032+                else if (--flslvl!=0)
10221033                         flslvl++;
<>1023 -                } else {
  1034+                else
10241035                         trulvl++;
<>1025 -                        prtline();
 1026 -                }
10271036         } else if (trulvl) {
 10281037                 flslvl++;
 10291038                 trulvl--;
 10301039         } else
<>1031 -                error("If-less else");
  1040+                error("#else in non-conditional section");
10321041         if (elslvl==trulvl+flslvl)
<>1033 -                error("Too many else");
  1042+                error("too many #else");
10341043         elslvl=trulvl+flslvl;
 10351044         chknl(1);
 10361045 }
 10371046 
 10381047 static void
 10391048 skpln(void)
 10401049 {
 10411050         int ch;
 10421051 
 10431052         /* just ignore the rest of the line */
 10441053         while ((ch = inch()) != -1) {
 10451054                 if (ch == '\n') {
 10461055                         unch('\n');
 10471056                         break;
 10481057                 }
 10491058         }
 10501059 }
 10511060 
 10521061 static void
 10531062 ifdefstmt(void)         
 10541063 {
 10551064         int t;
 10561065 
 10571066         if (flslvl) {
 10581067                 flslvl++;
 10591068                 skpln();
 10601069                 return;
 10611070         }
 10621071         do
 10631072                 t = sloscan();
 10641073         while (t == WSPACE);
 10651074         if (t != IDENT)
 10661075                 error("bad #ifdef");
<>1067 -        if (lookup(yytext, FIND) == NULL) {
 1068 -                putch('\n');
  1076+        if (lookup(yytext, FIND) == NULL)
10691077                 flslvl++;
<>1070 -        } else
  1078+        else
10711079                 trulvl++;
 10721080         chknl(0);
 10731081 }
 10741082 
 10751083 static void
 10761084 ifndefstmt(void)         
 10771085 {
 10781086         int t;
 10791087 
 10801088         if (flslvl) {
 10811089                 flslvl++;
 10821090                 skpln();
 10831091                 return;
 10841092         }
 10851093         do
 10861094                 t = sloscan();
 10871095         while (t == WSPACE);
 10881096         if (t != IDENT)
 10891097                 error("bad #ifndef");
<>1090 -        if (lookup(yytext, FIND) != NULL) {
 1091 -                putch('\n');
  1098+        if (lookup(yytext, FIND) != NULL)
10921099                 flslvl++;
<>1093 -        } else
  1100+        else
10941101                 trulvl++;
 10951102         chknl(0);
 10961103 }
 10971104 
 10981105 static void
 10991106 endifstmt(void)         
 11001107 {
<>1101 -        if (flslvl) {
  1108+        if (flslvl)
11021109                 flslvl--;
<>1103 -                if (flslvl == 0) {
 1104 -                        putch('\n');
 1105 -                        prtline();
 1106 -                }
 1107 -        } else if (trulvl)
  1110+        else if (trulvl)
11081111                 trulvl--;
 11091112         else
<>1110 -                error("If-less endif");
  1113+                error("#endif in non-conditional section");
11111114         if (flslvl == 0)
 11121115                 elflvl = 0;
 11131116         elslvl = 0;
 11141117         chknl(1);
 11151118 }
 11161119 
 11171120 static void
 11181121 ifstmt(void)
 11191122 {
<>1120 -        if (flslvl == 0) {
 1121 -                if (yyparse() == 0) {
 1122 -                        putch('\n');
 1123 -                        ++flslvl;
 1124 -                } else
 1125 -                        ++trulvl;
 1126 -        } else
 1127 -                ++flslvl;
  1123+        if (flslvl || yyparse() == 0)
  1124+                flslvl++;
  1125+        else
  1126+                trulvl++;
11281127 }
 11291128 
 11301129 static void
 11311130 elifstmt(void)
 11321131 {
 11331132         if (flslvl == 0)
 11341133                 elflvl = trulvl;
 11351134         if (flslvl) {
 11361135                 if (elflvl > trulvl)
 11371136                         ;
 11381137                 else if (--flslvl!=0)
<>1139 -                        ++flslvl;
 1140 -                else {
 1141 -                        if (yyparse()) {
 1142 -                                ++trulvl;
 1143 -                                prtline();
 1144 -                        } else {
 1145 -                                putch('\n');
 1146 -                                ++flslvl;
 1147 -                        }
  1138+                        flslvl++;
  1139+                else if (yyparse())
  1140+                        trulvl++;
  1141+                else
  1142+                        flslvl++;
11481143                 }
 11491144         } else if (trulvl) {
<>1150 -                ++flslvl;
 1151 -                --trulvl;
  1145+                flslvl++;
  1146+                trulvl--;
11521147         } else
<>1153 -                error("If-less elif");
  1148+                error("#elif in non-conditional section");
11541149 }
 11551150 
 11561151 /* save line into stringbuf */
 11571152 static usch *
 11581153 savln(void)
 11591154 {
 11601155         int c;
 11611156         usch *cp = stringbuf;
 11621157 
 11631158         while ((c = inch()) != -1) {
 11641159                 if (c == '\n') {
 11651160                         unch(c);
 11661161                         break;
 11671162                 }
 11681163                 savch(c);
 11691164         }
 11701165         savch(0);
 11711166 
 11721167         return cp;
 11731168 }
 11741169 
 11751170 static void
 11761171 cpperror(void)
 11771172 {
 11781173         usch *cp;
 11791174         int c;
 11801175 
 11811176         if (flslvl)
 11821177                 return;
 11831178         c = sloscan();
 11841179         if (c != WSPACE && c != '\n')
 11851180                 error("bad #error");
 11861181         cp = savln();
 11871182         error("#error %s", cp);
 11881183 }
 11891184 
 11901185 static void
 11911186 cppwarning(void)
 11921187 {
 11931188         usch *cp;
 11941189         int c;
 11951190 
 11961191         if (flslvl)
 11971192                 return;
 11981193         c = sloscan();
 11991194         if (c != WSPACE && c != '\n')
 12001195                 error("bad #warning");
 12011196         cp = savln();
 12021197         warning("#warning %s", cp);
 12031198         stringbuf = cp;
 12041199 }
 12051200 
 12061201 static void
 12071202 undefstmt(void)
 12081203 {
 12091204         struct symtab *np;
 12101205 
 12111206         if (flslvl)
 12121207                 return;
 12131208         if (sloscan() != WSPACE || sloscan() != IDENT)
 12141209                 error("bad #undef");
 12151210         if ((np = lookup(yytext, FIND)) != NULL)
 12161211                 np->value = 0;
 12171212         chknl(0);
 12181213 }
 12191214 
 12201215 static void
 12211216 pragmastmt(void)
 12221217 {
 12231218         usch *sb;
 12241219 
 12251220         if (flslvl)
 12261221                 return;
 12271222         if (sloscan() != WSPACE)
 12281223                 error("bad #pragma");
 12291224         sb = stringbuf;
 12301225         savstr((const usch *)"#pragma ");
 12311226         savln();
 12321227         putstr(sb);
 12331228         stringbuf = sb;
 12341229 }
 12351230 
 12361231 int
 12371232 cinput(void)
 12381233 {
 12391234         return inch();
 12401235 }
 12411236 
<>1242 -/*
 1243 - * Check for (and convert) trigraphs.
 1244 - */
 1245 -int
 1246 -chktg(void)
 1247 -{
 1248 -        int c;
 1249 -
 1250 -        if ((c = inpch()) != '?') {
 1251 -                unch(c);
 1252 -                return 0;
 1253 -        }
 1254 -        switch (c = inpch()) {
 1255 -        case '=': c = '#'; break;
 1256 -        case '(': c = '['; break;
 1257 -        case ')': c = ']'; break;
 1258 -        case '<': c = '{'; break;
 1259 -        case '>': c = '}'; break;
 1260 -        case '/': c = '\\'; break;
 1261 -        case '\'': c = '^'; break;
 1262 -        case '!': c = '|'; break;
 1263 -        case '-': c = '~'; break;
 1264 -        default:
 1265 -                unch(c);
 1266 -                unch('?');
 1267 -                c = 0;
 1268 -        }
 1269 -        return c;
 1270 -}
 1271 -
<_12721237 static struct {
 12731238         const char *name;
 12741239         void (*fun)(void);
 12751240 } ppd[] = {
 12761241         { "ifndef", ifndefstmt },
 12771242         { "ifdef", ifdefstmt },
 12781243         { "if", ifstmt },
 12791244         { "include", include },
 12801245         { "else", elsestmt },
 12811246         { "endif", endifstmt },
 12821247         { "error", cpperror },
 12831248         { "warning", cppwarning },
 12841249         { "define", define },
 12851250         { "undef", undefstmt },
 12861251         { "line", line },
 12871252         { "pragma", pragmastmt },
 12881253         { "elif", elifstmt },
 12891254 #ifdef GCC_COMPAT
 12901255         { "include_next", include_next },
 12911256 #endif
 12921257 };
 12931258 #define NPPD    (int)(sizeof(ppd) / sizeof(ppd[0]))
 12941259 
 12951260 /*
 12961261  * Handle a preprocessor directive.
 12971262  */
 12981263 void
 12991264 ppdir(void)
 13001265 {
 13011266         char bp[20];
 13021267         int ch, i;
 13031268 
 13041269 redo:   while ((ch = inch()) == ' ' || ch == '\t')
 13051270                 ;
 13061271         if (ch == '/') {
 13071272                 if ((ch = inch()) == '/') {
 13081273                         skpln();
 13091274                         return;
 13101275                 }
 13111276                 if (ch == '*') {
 13121277                         while ((ch = inch()) != -1) {
 13131278                                 if (ch == '*') {
 13141279                                         if ((ch = inch()) == '/')
 13151280                                                 goto redo;
 13161281                                         unch(ch);
 13171282                                 } else if (ch == '\n') {
 13181283                                         putch('\n');
 13191284                                         ifiles->lineno++;
 13201285                                 }
 13211286                         }
 13221287                 }
 13231288         }
 13241289         if (ch == '\n') { /* empty directive */
 13251290                 unch(ch);
 13261291                 return;
 13271292         }
 13281293         if (ch < 'a' || ch > 'z')
 13291294                 goto out; /* something else, ignore */
 13301295         i = 0;
 13311296         do {
 13321297                 bp[i++] = (usch)ch;
 13331298                 if (i == sizeof(bp)-1)
 13341299                         goto out; /* too long */
 13351300                 ch = inch();
 13361301         } while ((ch >= 'a' && ch <= 'z') || (ch == '_'));
 13371302         unch(ch);
 13381303         bp[i++] = 0;
 13391304 
 13401305         /* got keyword */
 13411306         for (i = 0; i < NPPD; i++) {
 13421307                 if (bp[0] == ppd[i].name[0] && strcmp(bp, ppd[i].name) == 0) {
 13431308                         (*ppd[i].fun)();
 13441309                         return;
 13451310                 }
 13461311         }
 13471312 
 13481313 out:    error("invalid preprocessor directive");
 13491314 }
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-20 09:59 +0200