Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.16
 
1.17
 
MAIN:gmcgarry:20090419091547
 
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 #include "config.h"
 2828 
 2929 #include <stdlib.h>
 3030 #include <string.h>
 3131 #include <ctype.h>
 3232 #ifdef HAVE_UNISTD_H
 3333 #include <unistd.h>
 3434 #endif
 3535 #include <fcntl.h>
 3636 #include <errno.h>
 3737 
 3838 #include "compat.h"
 3939 #include "cpp.h"
 4040 #include "y.tab.h"
 4141 
 4242 static void cvtdig(int rad);
 4343 static int charcon(usch *);
 4444 static void elsestmt(void);
 4545 static void ifdefstmt(void);
 4646 static void ifndefstmt(void);
 4747 static void endifstmt(void);
 4848 static void ifstmt(void);
 4949 static void cpperror(void);
 5050 static void pragmastmt(void);
 5151 static void undefstmt(void);
 5252 static void cpperror(void);
 5353 static void elifstmt(void);
 5454 static void storepb(void);
 5555 static void badop(const char *);
 5656 void  include(void);
 5757 void  define(void);
 5858 
 5959 extern int yyget_lineno (void);
 6060 extern void yyset_lineno (int);
 6161 
 6262 static int inch(void);
 6363 
 6464 static int scale, gotdef, contr;
 6565 int inif;
 6666 
 6767 #undef input
 6868 #undef unput
 6969 #define input() inch()
 7070 #define unput(ch) unch(ch)
 7171 #define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
 7272 /* protection against recursion in #include */
 7373 #define MAX_INCLEVEL    100
 7474 static int inclevel;
 7575 
 7676 #define IFR     1
 7777 #define CONTR   2
 7878 #define DEF     3
 7979 #define COMMENT 4
 8080 static int state;
 8181 #define BEGIN state =
 8282 #define YYSTATE state
 8383 
 8484 #ifdef YYTEXT_POINTER
 8585 static char buf[CPPBUF];
 8686 char *yytext = buf;
 8787 #else
 8888 char yytext[CPPBUF];
 8989 #endif
 9090 
 9191 static int owasnl, wasnl = 1;
 9292 
 9393 static void
 9494 unch(int c)
 9595 {
 9696                 
 9797         --ifiles->curptr;
 9898         if (ifiles->curptr < ifiles->bbuf)
 9999                 error("pushback buffer full");
 100100         *ifiles->curptr = c;
 101101 }
 102102 
 103103 
 104104 int
 105105 yylex()
 106106 {
 107107         int ch;
 108108         int yyp;
 109109         int os, mixed, haspmd;
 110110 
 111111 zagain:
 112112         yyp = 0;
 113113         yytext[yyp++] = ch = inch();
 114114         owasnl = wasnl;
 115115         wasnl = 0;
 116116         switch (ch) {
 117117         case -1:
 118118                 return 0;
 119119         case '\n':
 120120                 os = YYSTATE;
 121121 
 122122                 wasnl = 1;
 123123                 if (os != IFR)
 124124                         BEGIN 0;
 125125                 ifiles->lineno++;
 126126                 if (flslvl == 0) {
 127127                         if (ifiles->lineno == 1)
 128128                                 prtline();
 129129                         else
 130130                                 putch('\n');
 131131                 }
 132132                 if ((os != 0 || slow) && !contr)
 133133                         goto yyret;
 134134                 contr = 0;
 135135                 break;
 136136 
 137137         case '\r': /* Ignore CR's */
 138138                 yyp = 0;
 139139                 break;
 140140 
 141141 #define CHK(x,y) if (state != IFR) goto any; \
 142142         if ((ch = input()) != y) { unput(ch); ch = x; goto any; } \
 143143         yytext[yyp++] = ch
 144144 
 145145         case '+': CHK('+','+'); badop("++"); break;
 146146         case '-': CHK('-','-'); badop("--"); break;
 147147         case '=': CHK('=','='); ch = EQ; goto yyret;
 148148         case '!': CHK('!','='); ch = NE; goto yyret;
 149149         case '|': CHK('|','|'); ch = OROR; goto yyret;
 150150         case '&': CHK('&','&'); ch = ANDAND; goto yyret;
 151151         case '<':
 152152                 if (state != IFR) goto any;
 153153                 if ((ch = inch()) == '=') {
 154154                         yytext[yyp++] = ch; ch = LE; goto yyret;
 155155                 }
 156156                 if (ch == '<') { yytext[yyp++] = ch; ch = LS; goto yyret; }
 157157                 unch(ch);
 158158                 ch = '<';
 159159                 goto any;
 160160         case '>':
 161161                 if (state != IFR) goto any;
 162162                 if ((ch = inch()) == '=') {
 163163                         yytext[yyp++] = ch; ch = GE; goto yyret;
 164164                 }
 165165                 if (ch == '>') { yytext[yyp++] = ch; ch = RS; goto yyret; }
 166166                 unch(ch);
 167167                 ch = '>';
 168168                 goto any;
 169169 
 170170 
 171171         case '0': case '1': case '2': case '3': case '4': case '5':
 172172         case '6': case '7': case '8': case '9':
 173173                 /* readin a "pp-number" */
 174174                 mixed = haspmd = 0;
 175175 ppnum:          for (;;) {
 176176                         ch = input();
 177177                         if (ch == 'e' || ch == 'E' || ch == 'p' || ch == 'P') {
 178178                                 yytext[yyp++] = ch;
 179179                                 mixed = 1;
 180180                                 ch = input();
 181181                                 if (ch == '-' || ch == '+') {
 182182                                         yytext[yyp++] = ch;
 183183                                         haspmd = 1;
 184184                                 } else
 185185                                         unput(ch);
 186186                                 continue;
 187187                         }
 188188                         if (isdigit(ch) || isalpha(ch) ||
 189189                             ch == '_' || ch == '.') {
 190190                                 yytext[yyp++] = ch;
 191191                                 if (ch == '.')
 192192                                         haspmd = 1;
 193193                                 if (!isdigit(ch))
 194194                                         mixed = 1;
 195195                                 continue;
 196196                         }
 197197                         break;
 198198                 }
 199199                 unput(ch);
 200200                 yytext[yyp] = 0;
 201201 
 202202                 if (mixed == 1 && slow && (state == 0 || state == DEF))
 203203                         return IDENT;
 204204 
 205205                 if (mixed == 0) {
 206206                         if (slow && !YYSTATE)
 207207                                 return IDENT;
 208208                         scale = yytext[0] == '0' ? 8 : 10;
 209209                         goto num;
 210210                 } else if (yytext[0] == '0' &&
 211211                     (yytext[1] == 'x' || yytext[1] == 'X')) {
 212212                         scale = 16;
 213213 num:                    if (YYSTATE == IFR)
 214214                                 cvtdig(scale);
 215215                         PRTOUT(NUMBER);
<>216 -                } else if (yytext[0] == '0' && isdigit(yytext[1])) {
  216+                } else if (yytext[0] == '0' && isdigit((int)yytext[1])) {
<_217217                         scale = 8; goto num;
 218218                 } else if (haspmd) {
 219219                         PRTOUT(FPOINT);
 220220                 } else {
 221221                         scale = 10; goto num;
 222222                 }
 223223                 goto zagain;
 224224 
 225225 
 226226         case '\'':
 227227 chlit:          if (tflag && !(YYSTATE || slow))
 228228                         goto any;
 229229                 for (;;) {
 230230                         if ((ch = input()) == '\\') {
 231231                                 yytext[yyp++] = ch;
 232232                                 yytext[yyp++] = input();
 233233                                 continue;
 234234                         } else if (ch == '\n') {
 235235                                 /* not a constant */
 236236                                 while (yyp > 1)
 237237                                         unput(yytext[--yyp]);
 238238                                 ch = '\'';
 239239                                 goto any;
 240240                         } else
 241241                                 yytext[yyp++] = ch;
 242242                         if (ch == '\'')
 243243                                 break;
 244244                 }
 245245                 yytext[yyp] = 0;
 246246 
 247247                 if (YYSTATE || slow) {
 248248                         yylval.node.op = NUMBER;
 249249                         yylval.node.nd_val = charcon((usch *)yytext);
 250250                         return (NUMBER);
 251251                 }
 252252                 if (!flslvl)
 253253                         putstr((usch *)yytext);
 254254                 goto zagain;
 255255 
 256256         case ' ':
 257257         case '\t':
 258258                 if (state == IFR)
 259259                         goto zagain;
 260260 
 261261                 while ((ch = input()) == ' ' || ch == '\t')
 262262                         yytext[yyp++] = ch;
 263263                 if (owasnl == 0) {
 264264 b1:                     unput(ch);
 265265                         yytext[yyp] = 0;
 266266                         PRTOUT(WSPACE);
 267267                 } else if (ch != '#') {
 268268                         goto b1;
 269269                 } else {
 270270                         extern int inmac;
 271271 
 272272 contr:                  while ((ch = input()) == ' ' || ch == '\t')
 273273                                 ;
 274274                         unch(ch);
 275275                         if (inmac)
 276276                                 error("preprocessor directive found "
 277277                                     "while expanding macro");
 278278                         contr = 1;
 279279                         BEGIN CONTR;
 280280 
 281281                 }
 282282                 goto zagain;
 283283 
 284284         case '/':
 285285                 if ((ch = input()) == '/') {
 286286                         do {
 287287                                 yytext[yyp++] = ch;
 288288                                 ch = input();
 289289                         } while (ch && ch != '\n');
 290290                         yytext[yyp] = 0;
 291291                         unch(ch);
 292292                         if (Cflag && !flslvl && !slow)
 293293                                 putstr((usch *)yytext);
 294294                         else if (!flslvl)
 295295                                 putch(' ');
 296296                         goto zagain;
 297297                 } else if (ch == '*') {
 298298                         int c, wrn;
 299299                         int prtcm = Cflag && !flslvl && !slow;
 300300                         extern int readmac;
 301301 
 302302                         if (Cflag && !flslvl && readmac)
 303303                                 return CMNT;
 304304 
 305305                         if (prtcm)
 306306                                 putstr((usch *)yytext);
 307307                         wrn = 0;
 308308                 more:   while ((c = input()) && c != '*') {
 309309                                 if (c == '\n')
 310310                                         putch(c), ifiles->lineno++;
 311311                                 else if (c == 1) /* WARN */
 312312                                         wrn = 1;
 313313                                 else if (prtcm)
 314314                                         putch(c);
 315315                         }
 316316                         if (c == 0)
 317317                                 return 0;
 318318                         if (prtcm)
 319319                                 putch(c);
 320320                         if ((c = input()) && c != '/') {
 321321                                 unput(c);
 322322                                 goto more;
 323323                         }
 324324                         if (prtcm)
 325325                                 putch(c);
 326326                         if (c == 0)
 327327                                 return 0;
 328328                         if (!tflag && !Cflag && !flslvl)
 329329                                 unput(' ');
 330330                         if (wrn)
 331331                                 unput(1);
 332332                         goto zagain;
 333333                 }
 334334                 unch(ch);
 335335                 ch = '/';
 336336                 goto any;
 337337 
 338338         case '#':
 339339                 if (state != DEF) {
 340340                         if (owasnl)
 341341                                 goto contr;
 342342                         goto any;
 343343                 }
 344344                 if ((ch = input()) == '#') {
 345345                         yytext[yyp++] = ch;
 346346                         ch = CONCAT;
 347347                 } else {
 348348                         unput(ch);
 349349                         ch = MKSTR;
 350350                 }
 351351                 goto yyret;
 352352                 
 353353         case '.':
 354354                 if (state != DEF) {
 355355                         ch = input();
 356356                         if (isdigit(ch)) {
 357357                                 yytext[yyp++] = ch;
 358358                                 mixed = haspmd = 1;
 359359                                 goto ppnum;
 360360                         } else {
 361361                                 unput(ch);
 362362                                 ch = '.';
 363363                         }
 364364                         goto any;
 365365                 }
 366366                 if ((ch = input()) != '.') {
 367367                         unput(ch);
 368368                         ch = '.';
 369369                         goto any;
 370370                 }
 371371                 if ((ch = input()) != '.') {
 372372                         unput(ch);
 373373                         unput('.');
 374374                         ch = '.';
 375375                         goto any;
 376376                 }
 377377                 yytext[yyp++] = ch;
 378378                 yytext[yyp++] = ch;
 379379                 ch = ELLIPS;
 380380                 goto yyret;
 381381 
 382382 
 383383         case '\"':
 384384         strng:
 385385                 for (;;) {
 386386                         if ((ch = input()) == '\\') {
 387387                                 yytext[yyp++] = ch;
 388388                                 yytext[yyp++] = input();
 389389                                 continue;
 390390                         } else
 391391                                 yytext[yyp++] = ch;
 392392                         if (ch == '\"')
 393393                                 break;
 394394                 }
 395395                 yytext[yyp] = 0;
 396396                 { PRTOUT(STRING); }
 397397                 break;
 398398 
 399399         case 'L':
 400400                 if ((ch = input()) == '\"') {
 401401                         yytext[yyp++] = ch;
 402402                         goto strng;
 403403                 } else if (ch == '\'') {
 404404                         yytext[yyp++] = ch;
 405405                         goto chlit;
 406406                 }
 407407                 unput(ch);
 408408                 /* FALLTHROUGH */
 409409 
 410410         /* Yetch, all identifiers */
 411411         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 412412         case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
 413413         case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
 414414         case 's': case 't': case 'u': case 'v': case 'w': case 'x':
 415415         case 'y': case 'z':
 416416         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
 417417         case 'G': case 'H': case 'I': case 'J': case 'K':
 418418         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
 419419         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
 420420         case 'Y': case 'Z':
 421421         case '_': { /* {L}({L}|{D})* */
 422422                 struct symtab *nl;
 423423 
 424424                 /* Special hacks */
 425425                 for (;;) { /* get chars */
 426426                         ch = input();
 427427                         if (isalpha(ch) || isdigit(ch) || ch == '_') {
 428428                                 yytext[yyp++] = ch;
 429429                         } else {
 430430                                 unput(ch);
 431431                                 break;
 432432                         }
 433433                 }
 434434                 yytext[yyp] = 0; /* need already string */
 435435 
 436436                 switch (state) {
 437437                 case DEF:
 438438                         if (strcmp(yytext, "__VA_ARGS__") == 0)
 439439                                 return VA_ARGS;
 440440                         break;
 441441                 case CONTR:
 442442 #define CC(s)   if (strcmp(yytext, s) == 0)
 443443                         CC("ifndef") {
 444444                                 contr = 0; ifndefstmt();
 445445                                 goto zagain;
 446446                         } else CC("ifdef") {
 447447                                 contr = 0; ifdefstmt();
 448448                                 goto zagain;
 449449                         } else CC("if") {
 450450                                 contr = 0; storepb(); BEGIN IFR;
 451451                                 ifstmt(); BEGIN 0;
 452452                                 goto zagain;
 453453                         } else CC("include") {
 454454                                 contr = 0; BEGIN 0; include(); prtline();
 455455                                 goto zagain;
 456456                         } else CC("else") {
 457457                                 contr = 0; elsestmt();
 458458                                 goto zagain;
 459459                         } else CC("endif") {
 460460                                 contr = 0; endifstmt();
 461461                                 goto zagain;
 462462                         } else CC("error") {
 463463                                 contr = 0; if (slow) return IDENT;
 464464                                 cpperror(); BEGIN 0;
 465465                                 goto zagain;
 466466                         } else CC("define") {
 467467                                 contr = 0; BEGIN DEF; define(); BEGIN 0;
 468468                                 goto zagain;
 469469                         } else CC("undef") {
 470470                                 contr = 0; if (slow) return IDENT; undefstmt();
 471471                                 goto zagain;
 472472                         } else CC("line") {
 473473                                 contr = 0; storepb(); BEGIN 0; line();
 474474                                 goto zagain;
 475475                         } else CC("pragma") {
 476476                                 contr = 0; pragmastmt(); BEGIN 0;
 477477                                 goto zagain;
 478478                         } else CC("elif") {
 479479                                 contr = 0; storepb(); BEGIN IFR;
 480480                                 elifstmt(); BEGIN 0;
 481481                                 goto zagain;
 482482                         }
 483483                         break;
 484484                 case  IFR:
 485485                         CC("defined") {
 486486                                 int p, c;
 487487                                 gotdef = 1;
 488488                                 if ((p = c = yylex()) == '(')
 489489                                         c = yylex();
 490490                                 if (c != IDENT || (p != IDENT && p != '('))
 491491                                         error("syntax error");
 492492                                 if (p == '(' && yylex() != ')')
 493493                                         error("syntax error");
 494494                                 return NUMBER;
 495495                         } else {
 496496                                 yylval.node.op = NUMBER;
 497497                                 if (gotdef) {
 498498                                         yylval.node.nd_val
 499499                                             = lookup((usch *)yytext, FIND) != 0;
 500500                                         gotdef = 0;
 501501                                         return IDENT;
 502502                                 }
 503503                                 yylval.node.nd_val = 0;
 504504                                 return NUMBER;
 505505                         }
 506506                 }
 507507 
 508508                 /* end special hacks */
 509509 
 510510                 if (slow)
 511511                         return IDENT;
 512512                 if (YYSTATE == CONTR) {
 513513                         if (flslvl == 0) {
 514514                                 /*error("undefined control");*/
 515515                                 while (input() != '\n')
 516516                                         ;
 517517                                 unput('\n');
 518518                                 BEGIN 0;
 519519                                 goto xx;
 520520                         } else {
 521521                                 BEGIN 0; /* do nothing */
 522522                         }
 523523                 }
 524524                 if (flslvl) {
 525525                         ; /* do nothing */
 526526                 } else if (isdigit((int)yytext[0]) == 0 &&
 527527                     (nl = lookup((usch *)yytext, FIND)) != 0) {
 528528                         usch *op = stringbuf;
 529529                         putstr(gotident(nl));
 530530                         stringbuf = op;
 531531                 } else
 532532                         putstr((usch *)yytext);
 533533                 xx:
 534534                 goto zagain;
 535535         }
 536536 
 537537         default:
 538538         any:
 539539                 if (state == IFR)
 540540                         goto yyret;
 541541                 yytext[yyp] = 0;
 542542                 if (contr) {
 543543                         while (input() != '\n')
 544544                                 ;
 545545                         unput('\n');
 546546                         BEGIN 0;
 547547                         contr = 0;
 548548                         goto yy;
 549549                 }
 550550                 if (YYSTATE || slow)
 551551                         return yytext[0];
 552552                 if (yytext[0] == 6) { /* PRAGS */
 553553                         usch *obp = stringbuf;
 554554                         extern usch *prtprag(usch *);
 555555                         *stringbuf++ = yytext[0];
 556556                         do {
 557557                                 *stringbuf = input();
 558558                         } while (*stringbuf++ != 14);
 559559                         prtprag(obp);
 560560                         stringbuf = obp;
 561561                 } else {
 562562                         PRTOUT(yytext[0]);
 563563                 }
 564564                 yy:
 565565                 yyp = 0;
 566566                 break;
 567567 
 568568         } /* endcase */
 569569         goto zagain;
 570570 
 571571 yyret:
 572572         yytext[yyp] = 0;
 573573         return ch;
 574574 }
 575575 
 576576 usch *yyp, yybuf[CPPBUF];
 577577 
 578578 int yylex(void);
 579579 int yywrap(void);
 580580 
 581581 static int
 582582 inpch(void)
 583583 {
 584584         int len;
 585585 
 586586         if (ifiles->curptr < ifiles->maxread)
 587587                 return *ifiles->curptr++;
 588588 
 589589         if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
 590590                 error("read error on file %s", ifiles->orgfn);
 591591         if (len == 0)
 592592                 return -1;
 593593         ifiles->curptr = ifiles->buffer;
 594594         ifiles->maxread = ifiles->buffer + len;
 595595         return inpch();
 596596 }
 597597 
 598598 static int
 599599 inch(void)
 600600 {
 601601         int c;
 602602 
 603603 again:  switch (c = inpch()) {
 604604         case '\\': /* continued lines */
 605605 msdos:          if ((c = inpch()) == '\n') {
 606606                         ifiles->lineno++;
 607607                         putch('\n');
 608608                         goto again;
 609609                 } else if (c == '\r')
 610610                         goto msdos;
 611611                 unch(c);
 612612                 return '\\';
 613613         case '?': /* trigraphs */
 614614                 if ((c = inpch()) != '?') {
 615615                         unch(c);
 616616                         return '?';
 617617                 }
 618618                 switch (c = inpch()) {
 619619                 case '=': c = '#'; break;
 620620                 case '(': c = '['; break;
 621621                 case ')': c = ']'; break;
 622622                 case '<': c = '{'; break;
 623623                 case '>': c = '}'; break;
 624624                 case '/': c = '\\'; break;
 625625                 case '\'': c = '^'; break;
 626626                 case '!': c = '|'; break;
 627627                 case '-': c = '~'; break;
 628628                 default:
 629629                         unch(c);
 630630                         unch('?');
 631631                         return '?';
 632632                 }
 633633                 unch(c);
 634634                 goto again;
 635635         default:
 636636                 return c;
 637637         }
 638638 }
 639639 
 640640 /*
 641641  * Let the command-line args be faked defines at beginning of file.
 642642  */
 643643 static void
 644644 prinit(struct initar *it, struct includ *ic)
 645645 {
 646646         char *a, *pre, *post;
 647647 
 648648         if (it->next)
 649649                 prinit(it->next, ic);
 650650         pre = post = NULL; /* XXX gcc */
 651651         switch (it->type) {
 652652         case 'D':
 653653                 pre = "#define ";
 654654                 if ((a = strchr(it->str, '=')) != NULL) {
 655655                         *a = ' ';
 656656                         post = "\n";
 657657                 } else
 658658                         post = " 1\n";
 659659                 break;
 660660         case 'U':
 661661                 pre = "#undef ";
 662662                 post = "\n";
 663663                 break;
 664664         case 'i':
 665665                 pre = "#include \"";
 666666                 post = "\"\n";
 667667                 break;
 668668         default:
 669669                 error("prinit");
 670670         }
 671671         strlcat((char *)ic->buffer, pre, CPPBUF+1);
 672672         strlcat((char *)ic->buffer, it->str, CPPBUF+1);
 673673         if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
 674674                 error("line exceeds buffer size");
 675675 
 676676         ic->lineno--;
 677677         while (*ic->maxread)
 678678                 ic->maxread++;
 679679 }
 680680 
 681681 /*
 682682  * A new file included.
 683683  * If ifiles == NULL, this is the first file and already opened (stdin).
 684684  * Return 0 on success, -1 if file to be included is not found.
 685685  */
 686686 int
 687687 pushfile(usch *file)
 688688 {
 689689         extern struct initar *initar;
 690690         struct includ ibuf;
 691691         struct includ *ic;
 692692         int c, otrulvl;
 693693 
 694694         ic = &ibuf;
 695695         ic->next = ifiles;
 696696 
 697697         slow = 0;
 698698         if (file != NULL) {
 699699                 if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
 700700                         return -1;
 701701                 ic->orgfn = ic->fname = file;
 702702                 if (++inclevel > MAX_INCLEVEL)
 703703                         error("Limit for nested includes exceeded");
 704704         } else {
 705705                 ic->infil = 0;
 706706                 ic->orgfn = ic->fname = (usch *)"<stdin>";
 707707         }
 708708         ic->buffer = ic->bbuf+NAMEMAX;
 709709         ic->curptr = ic->buffer;
 710710         ifiles = ic;
 711711         ic->lineno = 1;
 712712         ic->maxread = ic->curptr;
 713713         prtline();
 714714         if (initar) {
 715715                 *ic->maxread = 0;
 716716                 prinit(initar, ic);
 717717                 if (dMflag)
 718718                         write(ofd, ic->buffer, strlen((char *)ic->buffer));
 719719                 initar = NULL;
 720720         }
 721721 
 722722         otrulvl = trulvl;
 723723 
 724724         if ((c = yylex()) != 0)
 725725                 error("yylex returned %d", c);
 726726 
 727727 wasnl = owasnl;
 728728         if (otrulvl != trulvl || flslvl)
 729729                 error("unterminated conditional");
 730730 
 731731         ifiles = ic->next;
 732732         close(ic->infil);
 733733         inclevel--;
 734734         return 0;
 735735 }
 736736 
 737737 /*
 738738  * Print current position to output file.
 739739  */
 740740 void
 741741 prtline()
 742742 {
 743743         usch *s, *os = stringbuf;
 744744 
 745745         if (Mflag) {
 746746                 if (dMflag)
 747747                         return; /* no output */
 748748                 if (ifiles->lineno == 1) {
 749749                         s = sheap("%s: %s\n", Mfile, ifiles->fname);
 750750                         write(ofd, s, strlen((char *)s));
 751751                 }
 752752         } else if (!Pflag)
 753753                 putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
 754754         stringbuf = os;
 755755 }
 756756 
 757757 void
 758758 cunput(int c)
 759759 {
 760760 #ifdef CPP_DEBUG
 761761         extern int dflag;
 762762         if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
 763763 #endif
 764764         unput(c);
 765765 }
 766766 
 767767 int yywrap(void) { return 1; }
 768768 
 769769 static int
 770770 dig2num(int c)
 771771 {
 772772         if (c >= 'a')
 773773                 c = c - 'a' + 10;
 774774         else if (c >= 'A')
 775775                 c = c - 'A' + 10;
 776776         else
 777777                 c = c - '0';
 778778         return c;
 779779 }
 780780 
 781781 /*
 782782  * Convert string numbers to unsigned long long and check overflow.
 783783  */
 784784 static void
 785785 cvtdig(int rad)
 786786 {
 787787         unsigned long long rv = 0;
 788788         unsigned long long rv2 = 0;
 789789         char *y = yytext;
 790790         int c;
 791791 
 792792         c = *y++;
 793793         if (rad == 16)
 794794                 y++;
 795795         while (isxdigit(c)) {
 796796                 rv = rv * rad + dig2num(c);
 797797                 /* check overflow */
 798798                 if (rv / rad < rv2)
 799799                         error("Constant \"%s\" is out of range", yytext);
 800800                 rv2 = rv;
 801801                 c = *y++;
 802802         }
 803803         y--;
 804804         while (*y == 'l' || *y == 'L')
 805805                 y++;
 806806         yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
 807807         yylval.node.nd_uval = rv;
 808808         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
 809809                 yylval.node.op = UNUMBER;
 810810         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
 811811                 /* too large for signed */
 812812                 error("Constant \"%s\" is out of range", yytext);
 813813 }
 814814 
 815815 static int
 816816 charcon(usch *p)
 817817 {
 818818         int val, c;
 819819 
 820820         p++; /* skip first ' */
 821821         val = 0;
 822822         if (*p++ == '\\') {
 823823                 switch (*p++) {
 824824                 case 'a': val = '\a'; break;
 825825                 case 'b': val = '\b'; break;
 826826                 case 'f': val = '\f'; break;
 827827                 case 'n': val = '\n'; break;
 828828                 case 'r': val = '\r'; break;
 829829                 case 't': val = '\t'; break;
 830830                 case 'v': val = '\v'; break;
 831831                 case '\"': val = '\"'; break;
 832832                 case '\'': val = '\''; break;
 833833                 case '\\': val = '\\'; break;
 834834                 case 'x':
 835835                         while (isxdigit(c = *p)) {
 836836                                 val = val * 16 + dig2num(c);
 837837                                 p++;
 838838                         }
 839839                         break;
 840840                 case '0': case '1': case '2': case '3': case '4':
 841841                 case '5': case '6': case '7':
 842842                         p--;
 843843                         while (isdigit(c = *p)) {
 844844                                 val = val * 8 + (c - '0');
 845845                                 p++;
 846846                         }
 847847                         break;
 848848                 default: val = p[-1];
 849849                 }
 850850 
 851851         } else
 852852                 val = p[-1];
 853853         return val;
 854854 }
 855855 
 856856 static void
 857857 chknl(int ignore)
 858858 {
 859859         int t;
 860860 
 861861         slow = 1;
 862862         while ((t = yylex()) == WSPACE)
 863863                 ;
 864864         if (t != '\n') {
 865865                 if (ignore) {
 866866                         warning("newline expected, got \"%s\"", yytext);
 867867                         /* ignore rest of line */
 868868                         while ((t = yylex()) && t != '\n')
 869869                                 ;
 870870                 }
 871871                 else
 872872                         error("newline expected, got \"%s\"", yytext);
 873873         }
 874874         slow = 0;
 875875 }
 876876 
 877877 static void
 878878 elsestmt(void)
 879879 {
 880880         if (flslvl) {
 881881                 if (elflvl > trulvl)
 882882                         ;
 883883                 else if (--flslvl!=0) {
 884884                         flslvl++;
 885885                 } else {
 886886                         trulvl++;
 887887                         prtline();
 888888                 }
 889889         } else if (trulvl) {
 890890                 flslvl++;
 891891                 trulvl--;
 892892         } else
 893893                 error("If-less else");
 894894         if (elslvl==trulvl+flslvl)
 895895                 error("Too many else");
 896896         elslvl=trulvl+flslvl;
 897897         chknl(1);
 898898 }
 899899 
 900900 static void
 901901 ifdefstmt(void)         
 902902 {
 903903         int t;
 904904 
 905905         if (flslvl) {
 906906                 /* just ignore the rest of the line */
 907907                 while (input() != '\n')
 908908                         ;
 909909                 unput('\n');
 910910                 yylex();
 911911                 flslvl++;
 912912                 return;
 913913         }
 914914         slow = 1;
 915915         do
 916916                 t = yylex();
 917917         while (t == WSPACE);
 918918         if (t != IDENT)
 919919                 error("bad ifdef");
 920920         slow = 0;
 921921         if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
 922922                 trulvl++;
 923923         else
 924924                 flslvl++;
 925925         chknl(0);
 926926 }
 927927 
 928928 static void
 929929 ifndefstmt(void)         
 930930 {
 931931         int t;
 932932 
 933933         slow = 1;
 934934         do
 935935                 t = yylex();
 936936         while (t == WSPACE);
 937937         if (t != IDENT)
 938938                 error("bad ifndef");
 939939         slow = 0;
 940940         if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
 941941                 trulvl++;
 942942         else
 943943                 flslvl++;
 944944         chknl(0);
 945945 }
 946946 
 947947 static void
 948948 endifstmt(void)         
 949949 {
 950950         if (flslvl) {
 951951                 flslvl--;
 952952                 if (flslvl == 0)
 953953                         prtline();
 954954         } else if (trulvl)
 955955                 trulvl--;
 956956         else
 957957                 error("If-less endif");
 958958         if (flslvl == 0)
 959959                 elflvl = 0;
 960960         elslvl = 0;
 961961         chknl(1);
 962962 }
 963963 
 964964 /*
 965965  * Note! Ugly!
 966966  * Walk over the string s and search for defined, and replace it with
 967967  * spaces and a 1 or 0.
 968968  */
 969969 static void
 970970 fixdefined(usch *s)
 971971 {
 972972         usch *bc, oc;
 973973 
 974974         for (; *s; s++) {
 975975                 if (*s != 'd')
 976976                         continue;
 977977                 if (memcmp(s, "defined", 7))
 978978                         continue;
 979979                 /* Ok, got defined, can scratch it now */
 980980                 memset(s, ' ', 7);
 981981                 s += 7;
 982982 #define WSARG(x) (x == ' ' || x == '\t')
 983983                 if (*s != '(' && !WSARG(*s))
 984984                         continue;
 985985                 while (WSARG(*s))
 986986                         s++;
 987987                 if (*s == '(')
 988988                         s++;
 989989                 while (WSARG(*s))
 990990                         s++;
 991991 #define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
 992992 #define NUMARG(x) (x >= '0' && x <= '9')
 993993                 if (!IDARG(*s))
 994994                         error("bad defined arg");
 995995                 bc = s;
 996996                 while (IDARG(*s) || NUMARG(*s))
 997997                         s++;
 998998                 oc = *s;
 999999                 *s = 0;
 10001000                 *bc = (lookup(bc, FIND) != 0) + '0';
 10011001                 memset(bc+1, ' ', s-bc-1);
 10021002                 *s = oc;
 10031003         }
 10041004 }
 10051005 
 10061006 /*
 10071007  * get the full line of identifiers after an #if, pushback a WARN and
 10081008  * the line and prepare for expmac() to expand.
 10091009  * This is done before switching state.  When expmac is finished,
 10101010  * pushback the expanded line, change state and call yyparse.
 10111011  */
 10121012 static void
 10131013 storepb(void)
 10141014 {
 10151015         usch *opb = stringbuf;
 10161016         int c;
 10171017 
 10181018         while ((c = input()) != '\n') {
 10191019                 if (c == '/') {
 10201020                          if ((c = input()) == '*') {
 10211021                                 /* ignore comments here whatsoever */
 10221022                                 usch *g = stringbuf;
 10231023                                 getcmnt();
 10241024                                 stringbuf = g;
 10251025                                 continue;
 10261026                         } else if (c == '/') {
 10271027                                 while ((c = input()) && c != '\n')
 10281028                                         ;
 10291029                                 break;
 10301030                         }
 10311031                         unput(c);
 10321032                         c = '/';
 10331033                 }
 10341034                 savch(c);
 10351035         }
 10361036         cunput('\n');
 10371037         savch(0);
 10381038         fixdefined(opb); /* XXX can fail if #line? */
 10391039         cunput(1); /* WARN XXX */
 10401040         unpstr(opb);
 10411041         stringbuf = opb;
 10421042         slow = 1;
 10431043         expmac(NULL);
 10441044         slow = 0;
 10451045         /* line now expanded */
 10461046         while (stringbuf > opb)
 10471047                 cunput(*--stringbuf);
 10481048 }
 10491049 
 10501050 static void
 10511051 ifstmt(void)
 10521052 {
 10531053         if (flslvl == 0) {
 10541054                 slow = 1;
 10551055                 if (yyparse())
 10561056                         ++trulvl;
 10571057                 else
 10581058                         ++flslvl;
 10591059                 slow = 0;
 10601060         } else
 10611061                 ++flslvl;
 10621062 }
 10631063 
 10641064 static void
 10651065 elifstmt(void)
 10661066 {
 10671067         if (flslvl == 0)
 10681068                 elflvl = trulvl;
 10691069         if (flslvl) {
 10701070                 if (elflvl > trulvl)
 10711071                         ;
 10721072                 else if (--flslvl!=0)
 10731073                         ++flslvl;
 10741074                 else {
 10751075                         slow = 1;
 10761076                         if (yyparse()) {
 10771077                                 ++trulvl;
 10781078                                 prtline();
 10791079                         } else
 10801080                                 ++flslvl;
 10811081                         slow = 0;
 10821082                 }
 10831083         } else if (trulvl) {
 10841084                 ++flslvl;
 10851085                 --trulvl;
 10861086         } else
 10871087                 error("If-less elif");
 10881088 }
 10891089 
 10901090 static usch *
 10911091 svinp(void)
 10921092 {
 10931093         int c;
 10941094         usch *cp = stringbuf;
 10951095 
 10961096         while ((c = input()) && c != '\n')
 10971097                 savch(c);
 10981098         savch('\n');
 10991099         savch(0);
 11001100         BEGIN 0;
 11011101         return cp;
 11021102 }
 11031103 
 11041104 static void
 11051105 cpperror(void)
 11061106 {
 11071107         usch *cp;
 11081108         int c;
 11091109 
 11101110         if (flslvl)
 11111111                 return;
 11121112         c = yylex();
 11131113         if (c != WSPACE && c != '\n')
 11141114                 error("bad error");
 11151115         cp = svinp();
 11161116         if (flslvl)
 11171117                 stringbuf = cp;
 11181118         else
 11191119                 error("%s", cp);
 11201120 }
 11211121 
 11221122 static void
 11231123 undefstmt(void)
 11241124 {
 11251125         struct symtab *np;
 11261126 
 11271127         slow = 1;
 11281128         if (yylex() != WSPACE || yylex() != IDENT)
 11291129                 error("bad undef");
 11301130         if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
 11311131                 np->value = 0;
 11321132         slow = 0;
 11331133         chknl(0);
 11341134 }
 11351135 
 11361136 static void
 11371137 pragmastmt(void)
 11381138 {
 11391139         int c;
 11401140 
 11411141         slow = 1;
 11421142         if (yylex() != WSPACE)
 11431143                 error("bad pragma");
 11441144         if (!flslvl)
 11451145                 putstr((usch *)"#pragma ");
 11461146         do {
 11471147                 c = input();
 11481148                 if (!flslvl)
 11491149                         putch(c);       /* Do arg expansion instead? */
 11501150         } while (c && c != '\n');
 11511151         if (c == '\n')
 11521152                 unch(c);
 11531153         prtline();
 11541154         slow = 0;
 11551155 }
 11561156 
 11571157 static void
 11581158 badop(const char *op)
 11591159 {
 11601160         error("invalid operator in preprocessor expression: %s", op);
 11611161 }
 11621162 
 11631163 int
 11641164 cinput()
 11651165 {
 11661166         return input();
 11671167 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-21 03:37 +0100