Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.14
 
1.15
 
MAIN:ragge:20090312201943
 
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 char yytext[CPPBUF];
<> 85+static int owasnl, wasnl = 1;
8586 
 8687 static void
 8788 unch(int c)
 8889 {
<>89 -        *--ifiles->curptr = c;
  90+                
  91+        --ifiles->curptr;
  92+        if (ifiles->curptr < ifiles->bbuf)
  93+                error("pushback buffer full");
  94+        *ifiles->curptr = c;
9095 }
 9196 
 9297 
 9398 int
 9499 yylex()
 95100 {
<>96 -        static int owasnl, wasnl = 1;
97101         int ch;
 98102         int yyp;
 99103         int os, mixed, haspmd;
 100104 
 101105 zagain:
 102106         yyp = 0;
 103107         yytext[yyp++] = ch = inch();
 104108         owasnl = wasnl;
 105109         wasnl = 0;
 106110         switch (ch) {
 107111         case -1:
 108112                 return 0;
 109113         case '\n':
 110114                 os = YYSTATE;
 111115 
 112116                 wasnl = 1;
 113117                 if (os != IFR)
 114118                         BEGIN 0;
 115119                 ifiles->lineno++;
 116120                 if (flslvl == 0) {
 117121                         if (ifiles->lineno == 1)
 118122                                 prtline();
 119123                         else
 120124                                 putch('\n');
 121125                 }
 122126                 if ((os != 0 || slow) && !contr)
 123127                         goto yyret;
 124128                 contr = 0;
 125129                 break;
 126130 
 127131         case '\r': /* Ignore CR's */
 128132                 yyp = 0;
 129133                 break;
 130134 
 131135 #define CHK(x,y) if (state != IFR) goto any; \
 132136         if ((ch = input()) != y) { unput(ch); ch = x; goto any; } \
 133137         yytext[yyp++] = ch
 134138 
 135139         case '+': CHK('+','+'); badop("++"); break;
 136140         case '-': CHK('-','-'); badop("--"); break;
 137141         case '=': CHK('=','='); ch = EQ; goto yyret;
 138142         case '!': CHK('!','='); ch = NE; goto yyret;
 139143         case '|': CHK('|','|'); ch = OROR; goto yyret;
 140144         case '&': CHK('&','&'); ch = ANDAND; goto yyret;
 141145         case '<':
 142146                 if (state != IFR) goto any;
 143147                 if ((ch = inch()) == '=') {
 144148                         yytext[yyp++] = ch; ch = LE; goto yyret;
 145149                 }
 146150                 if (ch == '<') { yytext[yyp++] = ch; ch = LS; goto yyret; }
 147151                 unch(ch);
 148152                 ch = '<';
 149153                 goto any;
 150154         case '>':
 151155                 if (state != IFR) goto any;
 152156                 if ((ch = inch()) == '=') {
 153157                         yytext[yyp++] = ch; ch = GE; goto yyret;
 154158                 }
 155159                 if (ch == '>') { yytext[yyp++] = ch; ch = RS; goto yyret; }
 156160                 unch(ch);
 157161                 ch = '>';
 158162                 goto any;
 159163 
 160164 
 161165         case '0': case '1': case '2': case '3': case '4': case '5':
 162166         case '6': case '7': case '8': case '9':
 163167                 /* readin a "pp-number" */
 164168                 mixed = haspmd = 0;
 165169 ppnum:          for (;;) {
 166170                         ch = input();
 167171                         if (ch == 'e' || ch == 'E' || ch == 'p' || ch == 'P') {
 168172                                 yytext[yyp++] = ch;
 169173                                 mixed = 1;
 170174                                 ch = input();
 171175                                 if (ch == '-' || ch == '+') {
 172176                                         yytext[yyp++] = ch;
 173177                                         haspmd = 1;
 174178                                 } else
 175179                                         unput(ch);
 176180                                 continue;
 177181                         }
 178182                         if (isdigit(ch) || isalpha(ch) ||
 179183                             ch == '_' || ch == '.') {
 180184                                 yytext[yyp++] = ch;
 181185                                 if (ch == '.')
 182186                                         haspmd = 1;
 183187                                 if (!isdigit(ch))
 184188                                         mixed = 1;
 185189                                 continue;
 186190                         }
 187191                         break;
 188192                 }
 189193                 unput(ch);
 190194                 yytext[yyp] = 0;
 191195 
<> 196+                if (mixed == 1 && slow && (state == 0 || state == DEF))
  197+                        return IDENT;
  198+
192199                 if (mixed == 0) {
 193200                         if (slow && !YYSTATE)
 194201                                 return IDENT;
 195202                         scale = yytext[0] == '0' ? 8 : 10;
 196203                         goto num;
 197204                 } else if (yytext[0] == '0' &&
 198205                     (yytext[1] == 'x' || yytext[1] == 'X')) {
 199206                         scale = 16;
 200207 num:                    if (YYSTATE == IFR)
 201208                                 cvtdig(scale);
 202209                         PRTOUT(NUMBER);
 203210                 } else if (yytext[0] == '0' && isdigit(yytext[1])) {
 204211                         scale = 8; goto num;
 205212                 } else if (haspmd) {
 206213                         PRTOUT(FPOINT);
 207214                 } else {
 208215                         scale = 10; goto num;
 209216                 }
 210217                 goto zagain;
 211218 
 212219 
 213220         case '\'':
 214221 chlit:          if (tflag && !(YYSTATE || slow))
 215222                         goto any;
 216223                 for (;;) {
 217224                         if ((ch = input()) == '\\') {
 218225                                 yytext[yyp++] = ch;
 219226                                 yytext[yyp++] = input();
 220227                                 continue;
 221228                         } else if (ch == '\n') {
 222229                                 /* not a constant */
 223230                                 while (yyp > 1)
 224231                                         unput(yytext[--yyp]);
 225232                                 ch = '\'';
 226233                                 goto any;
 227234                         } else
 228235                                 yytext[yyp++] = ch;
 229236                         if (ch == '\'')
 230237                                 break;
 231238                 }
 232239                 yytext[yyp] = 0;
 233240 
 234241                 if (YYSTATE || slow) {
 235242                         yylval.node.op = NUMBER;
 236243                         yylval.node.nd_val = charcon((usch *)yytext);
 237244                         return (NUMBER);
 238245                 }
 239246                 if (!flslvl)
 240247                         putstr((usch *)yytext);
 241248                 goto zagain;
 242249 
 243250         case ' ':
 244251         case '\t':
 245252                 if (state == IFR)
 246253                         goto zagain;
 247254 
 248255                 while ((ch = input()) == ' ' || ch == '\t')
 249256                         yytext[yyp++] = ch;
 250257                 if (owasnl == 0) {
 251258 b1:                     unput(ch);
 252259                         yytext[yyp] = 0;
 253260                         PRTOUT(WSPACE);
 254261                 } else if (ch != '#') {
 255262                         goto b1;
 256263                 } else {
 257264                         extern int inmac;
 258265 
 259266 contr:                  while ((ch = input()) == ' ' || ch == '\t')
 260267                                 ;
 261268                         unch(ch);
 262269                         if (inmac)
 263270                                 error("preprocessor directive found "
 264271                                     "while expanding macro");
 265272                         contr = 1;
 266273                         BEGIN CONTR;
 267274 
 268275                 }
 269276                 goto zagain;
 270277 
 271278         case '/':
 272279                 if ((ch = input()) == '/') {
 273280                         do {
 274281                                 yytext[yyp++] = ch;
 275282                                 ch = input();
 276283                         } while (ch && ch != '\n');
 277284                         yytext[yyp] = 0;
 278285                         unch(ch);
 279286                         if (Cflag && !flslvl && !slow)
 280287                                 putstr((usch *)yytext);
 281288                         else if (!flslvl)
 282289                                 putch(' ');
 283290                         goto zagain;
 284291                 } else if (ch == '*') {
 285292                         int c, wrn;
 286293                         int prtcm = Cflag && !flslvl && !slow;
 287294                         extern int readmac;
 288295 
 289296                         if (Cflag && !flslvl && readmac)
 290297                                 return CMNT;
 291298 
 292299                         if (prtcm)
 293300                                 putstr((usch *)yytext);
 294301                         wrn = 0;
 295302                 more:   while ((c = input()) && c != '*') {
 296303                                 if (c == '\n')
 297304                                         putch(c), ifiles->lineno++;
 298305                                 else if (c == 1) /* WARN */
 299306                                         wrn = 1;
 300307                                 else if (prtcm)
 301308                                         putch(c);
 302309                         }
 303310                         if (c == 0)
 304311                                 return 0;
 305312                         if (prtcm)
 306313                                 putch(c);
 307314                         if ((c = input()) && c != '/') {
 308315                                 unput(c);
 309316                                 goto more;
 310317                         }
 311318                         if (prtcm)
 312319                                 putch(c);
 313320                         if (c == 0)
 314321                                 return 0;
 315322                         if (!tflag && !Cflag && !flslvl)
 316323                                 unput(' ');
 317324                         if (wrn)
 318325                                 unput(1);
 319326                         goto zagain;
 320327                 }
 321328                 unch(ch);
 322329                 ch = '/';
 323330                 goto any;
 324331 
 325332         case '#':
 326333                 if (state != DEF) {
 327334                         if (owasnl)
 328335                                 goto contr;
 329336                         goto any;
 330337                 }
 331338                 if ((ch = input()) == '#') {
 332339                         yytext[yyp++] = ch;
 333340                         ch = CONCAT;
 334341                 } else {
 335342                         unput(ch);
 336343                         ch = MKSTR;
 337344                 }
 338345                 goto yyret;
 339346                 
 340347         case '.':
 341348                 if (state != DEF) {
 342349                         ch = input();
 343350                         if (isdigit(ch)) {
 344351                                 yytext[yyp++] = ch;
 345352                                 mixed = haspmd = 1;
 346353                                 goto ppnum;
 347354                         } else {
 348355                                 unput(ch);
 349356                                 ch = '.';
 350357                         }
 351358                         goto any;
 352359                 }
 353360                 if ((ch = input()) != '.') {
 354361                         unput(ch);
 355362                         ch = '.';
 356363                         goto any;
 357364                 }
 358365                 if ((ch = input()) != '.') {
 359366                         unput(ch);
 360367                         unput('.');
 361368                         ch = '.';
 362369                         goto any;
 363370                 }
 364371                 yytext[yyp++] = ch;
 365372                 yytext[yyp++] = ch;
 366373                 ch = ELLIPS;
 367374                 goto yyret;
 368375 
 369376 
 370377         case '\"':
 371378         strng:
 372379                 for (;;) {
 373380                         if ((ch = input()) == '\\') {
 374381                                 yytext[yyp++] = ch;
 375382                                 yytext[yyp++] = input();
 376383                                 continue;
 377384                         } else
 378385                                 yytext[yyp++] = ch;
 379386                         if (ch == '\"')
 380387                                 break;
 381388                 }
 382389                 yytext[yyp] = 0;
 383390                 { PRTOUT(STRING); }
 384391                 break;
 385392 
 386393         case 'L':
 387394                 if ((ch = input()) == '\"') {
 388395                         yytext[yyp++] = ch;
 389396                         goto strng;
 390397                 } else if (ch == '\'') {
 391398                         yytext[yyp++] = ch;
 392399                         goto chlit;
 393400                 }
 394401                 unput(ch);
 395402                 /* FALLTHROUGH */
 396403 
 397404         /* Yetch, all identifiers */
 398405         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 399406         case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
 400407         case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
 401408         case 's': case 't': case 'u': case 'v': case 'w': case 'x':
 402409         case 'y': case 'z':
 403410         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
 404411         case 'G': case 'H': case 'I': case 'J': case 'K':
 405412         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
 406413         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
 407414         case 'Y': case 'Z':
 408415         case '_': { /* {L}({L}|{D})* */
 409416                 struct symtab *nl;
 410417 
 411418                 /* Special hacks */
 412419                 for (;;) { /* get chars */
 413420                         ch = input();
 414421                         if (isalpha(ch) || isdigit(ch) || ch == '_') {
 415422                                 yytext[yyp++] = ch;
 416423                         } else {
 417424                                 unput(ch);
 418425                                 break;
 419426                         }
 420427                 }
 421428                 yytext[yyp] = 0; /* need already string */
 422429 
 423430                 switch (state) {
 424431                 case DEF:
 425432                         if (strcmp(yytext, "__VA_ARGS__") == 0)
 426433                                 return VA_ARGS;
 427434                         break;
 428435                 case CONTR:
 429436 #define CC(s)   if (strcmp(yytext, s) == 0)
 430437                         CC("ifndef") {
 431438                                 contr = 0; ifndefstmt();
 432439                                 goto zagain;
 433440                         } else CC("ifdef") {
 434441                                 contr = 0; ifdefstmt();
 435442                                 goto zagain;
 436443                         } else CC("if") {
 437444                                 contr = 0; storepb(); BEGIN IFR;
 438445                                 ifstmt(); BEGIN 0;
 439446                                 goto zagain;
 440447                         } else CC("include") {
 441448                                 contr = 0; BEGIN 0; include(); prtline();
 442449                                 goto zagain;
 443450                         } else CC("else") {
 444451                                 contr = 0; elsestmt();
 445452                                 goto zagain;
 446453                         } else CC("endif") {
 447454                                 contr = 0; endifstmt();
 448455                                 goto zagain;
 449456                         } else CC("error") {
 450457                                 contr = 0; if (slow) return IDENT;
 451458                                 cpperror(); BEGIN 0;
 452459                                 goto zagain;
 453460                         } else CC("define") {
 454461                                 contr = 0; BEGIN DEF; define(); BEGIN 0;
 455462                                 goto zagain;
 456463                         } else CC("undef") {
 457464                                 contr = 0; if (slow) return IDENT; undefstmt();
 458465                                 goto zagain;
 459466                         } else CC("line") {
 460467                                 contr = 0; storepb(); BEGIN 0; line();
 461468                                 goto zagain;
 462469                         } else CC("pragma") {
 463470                                 contr = 0; pragmastmt(); BEGIN 0;
 464471                                 goto zagain;
 465472                         } else CC("elif") {
 466473                                 contr = 0; storepb(); BEGIN IFR;
 467474                                 elifstmt(); BEGIN 0;
 468475                                 goto zagain;
 469476                         }
 470477                         break;
 471478                 case  IFR:
 472479                         CC("defined") {
 473480                                 int p, c;
 474481                                 gotdef = 1;
 475482                                 if ((p = c = yylex()) == '(')
 476483                                         c = yylex();
 477484                                 if (c != IDENT || (p != IDENT && p != '('))
 478485                                         error("syntax error");
 479486                                 if (p == '(' && yylex() != ')')
 480487                                         error("syntax error");
 481488                                 return NUMBER;
 482489                         } else {
 483490                                 yylval.node.op = NUMBER;
 484491                                 if (gotdef) {
 485492                                         yylval.node.nd_val
 486493                                             = lookup((usch *)yytext, FIND) != 0;
 487494                                         gotdef = 0;
 488495                                         return IDENT;
 489496                                 }
 490497                                 yylval.node.nd_val = 0;
 491498                                 return NUMBER;
 492499                         }
 493500                 }
 494501 
 495502                 /* end special hacks */
 496503 
 497504                 if (slow)
 498505                         return IDENT;
 499506                 if (YYSTATE == CONTR) {
 500507                         if (flslvl == 0) {
 501508                                 /*error("undefined control");*/
 502509                                 while (input() != '\n')
 503510                                         ;
 504511                                 unput('\n');
 505512                                 BEGIN 0;
 506513                                 goto xx;
 507514                         } else {
 508515                                 BEGIN 0; /* do nothing */
 509516                         }
 510517                 }
 511518                 if (flslvl) {
 512519                         ; /* do nothing */
 513520                 } else if (isdigit((int)yytext[0]) == 0 &&
 514521                     (nl = lookup((usch *)yytext, FIND)) != 0) {
 515522                         usch *op = stringbuf;
 516523                         putstr(gotident(nl));
 517524                         stringbuf = op;
 518525                 } else
 519526                         putstr((usch *)yytext);
 520527                 xx:
 521528                 goto zagain;
 522529         }
 523530 
 524531         default:
 525532         any:
 526533                 if (state == IFR)
 527534                         goto yyret;
 528535                 yytext[yyp] = 0;
 529536                 if (contr) {
 530537                         while (input() != '\n')
 531538                                 ;
 532539                         unput('\n');
 533540                         BEGIN 0;
 534541                         contr = 0;
 535542                         goto yy;
 536543                 }
 537544                 if (YYSTATE || slow)
 538545                         return yytext[0];
 539546                 if (yytext[0] == 6) { /* PRAGS */
 540547                         usch *obp = stringbuf;
 541548                         extern usch *prtprag(usch *);
 542549                         *stringbuf++ = yytext[0];
 543550                         do {
 544551                                 *stringbuf = input();
 545552                         } while (*stringbuf++ != 14);
 546553                         prtprag(obp);
 547554                         stringbuf = obp;
 548555                 } else {
 549556                         PRTOUT(yytext[0]);
 550557                 }
 551558                 yy:
 552559                 yyp = 0;
 553560                 break;
 554561 
 555562         } /* endcase */
 556563         goto zagain;
 557564 
 558565 yyret:
 559566         yytext[yyp] = 0;
 560567         return ch;
 561568 }
 562569 
 563570 usch *yyp, yybuf[CPPBUF];
 564571 
 565572 int yylex(void);
 566573 int yywrap(void);
 567574 
 568575 static int
 569576 inpch(void)
 570577 {
 571578         int len;
 572579 
 573580         if (ifiles->curptr < ifiles->maxread)
 574581                 return *ifiles->curptr++;
 575582 
 576583         if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
 577584                 error("read error on file %s", ifiles->orgfn);
 578585         if (len == 0)
 579586                 return -1;
 580587         ifiles->curptr = ifiles->buffer;
 581588         ifiles->maxread = ifiles->buffer + len;
 582589         return inpch();
 583590 }
 584591 
 585592 static int
 586593 inch(void)
 587594 {
 588595         int c;
 589596 
 590597 again:  switch (c = inpch()) {
 591598         case '\\': /* continued lines */
 592599 msdos:          if ((c = inpch()) == '\n') {
 593600                         ifiles->lineno++;
 594601                         putch('\n');
 595602                         goto again;
 596603                 } else if (c == '\r')
 597604                         goto msdos;
 598605                 unch(c);
 599606                 return '\\';
 600607         case '?': /* trigraphs */
 601608                 if ((c = inpch()) != '?') {
 602609                         unch(c);
 603610                         return '?';
 604611                 }
 605612                 switch (c = inpch()) {
 606613                 case '=': c = '#'; break;
 607614                 case '(': c = '['; break;
 608615                 case ')': c = ']'; break;
 609616                 case '<': c = '{'; break;
 610617                 case '>': c = '}'; break;
 611618                 case '/': c = '\\'; break;
 612619                 case '\'': c = '^'; break;
 613620                 case '!': c = '|'; break;
 614621                 case '-': c = '~'; break;
 615622                 default:
 616623                         unch(c);
 617624                         unch('?');
 618625                         return '?';
 619626                 }
 620627                 unch(c);
 621628                 goto again;
 622629         default:
 623630                 return c;
 624631         }
 625632 }
 626633 
 627634 /*
 628635  * Let the command-line args be faked defines at beginning of file.
 629636  */
 630637 static void
 631638 prinit(struct initar *it, struct includ *ic)
 632639 {
 633640         char *a, *pre, *post;
 634641 
 635642         if (it->next)
 636643                 prinit(it->next, ic);
 637644         pre = post = NULL; /* XXX gcc */
 638645         switch (it->type) {
 639646         case 'D':
 640647                 pre = "#define ";
 641648                 if ((a = strchr(it->str, '=')) != NULL) {
 642649                         *a = ' ';
 643650                         post = "\n";
 644651                 } else
 645652                         post = " 1\n";
 646653                 break;
 647654         case 'U':
 648655                 pre = "#undef ";
 649656                 post = "\n";
 650657                 break;
 651658         case 'i':
 652659                 pre = "#include \"";
 653660                 post = "\"\n";
 654661                 break;
 655662         default:
 656663                 error("prinit");
 657664         }
 658665         strlcat((char *)ic->buffer, pre, CPPBUF+1);
 659666         strlcat((char *)ic->buffer, it->str, CPPBUF+1);
 660667         if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
 661668                 error("line exceeds buffer size");
 662669 
 663670         ic->lineno--;
 664671         while (*ic->maxread)
 665672                 ic->maxread++;
 666673 }
 667674 
 668675 /*
 669676  * A new file included.
 670677  * If ifiles == NULL, this is the first file and already opened (stdin).
 671678  * Return 0 on success, -1 if file to be included is not found.
 672679  */
 673680 int
 674681 pushfile(usch *file)
 675682 {
 676683         extern struct initar *initar;
 677684         struct includ ibuf;
 678685         struct includ *ic;
 679686         int c, otrulvl;
 680687 
 681688         ic = &ibuf;
 682689         ic->next = ifiles;
 683690 
 684691         slow = 0;
 685692         if (file != NULL) {
 686693                 if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
 687694                         return -1;
 688695                 ic->orgfn = ic->fname = file;
 689696                 if (++inclevel > MAX_INCLEVEL)
 690697                         error("Limit for nested includes exceeded");
 691698         } else {
 692699                 ic->infil = 0;
 693700                 ic->orgfn = ic->fname = (usch *)"<stdin>";
 694701         }
 695702         ic->buffer = ic->bbuf+NAMEMAX;
 696703         ic->curptr = ic->buffer;
 697704         ifiles = ic;
 698705         ic->lineno = 1;
 699706         ic->maxread = ic->curptr;
 700707         prtline();
 701708         if (initar) {
 702709                 *ic->maxread = 0;
 703710                 prinit(initar, ic);
 704711                 if (dMflag)
 705712                         write(ofd, ic->buffer, strlen((char *)ic->buffer));
 706713                 initar = NULL;
 707714         }
 708715 
 709716         otrulvl = trulvl;
 710717 
 711718         if ((c = yylex()) != 0)
 712719                 error("yylex returned %d", c);
 713720 
<> 721+wasnl = owasnl;
714722         if (otrulvl != trulvl || flslvl)
 715723                 error("unterminated conditional");
 716724 
 717725         ifiles = ic->next;
 718726         close(ic->infil);
 719727         inclevel--;
 720728         return 0;
 721729 }
 722730 
 723731 /*
 724732  * Print current position to output file.
 725733  */
 726734 void
 727735 prtline()
 728736 {
 729737         usch *s, *os = stringbuf;
 730738 
 731739         if (Mflag) {
 732740                 if (dMflag)
 733741                         return; /* no output */
 734742                 if (ifiles->lineno == 1) {
 735743                         s = sheap("%s: %s\n", Mfile, ifiles->fname);
 736744                         write(ofd, s, strlen((char *)s));
 737745                 }
 738746         } else if (!Pflag)
 739747                 putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
 740748         stringbuf = os;
 741749 }
 742750 
 743751 void
 744752 cunput(int c)
 745753 {
 746754 #ifdef CPP_DEBUG
 747755         extern int dflag;
 748756         if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
 749757 #endif
 750758         unput(c);
 751759 }
 752760 
 753761 int yywrap(void) { return 1; }
 754762 
 755763 static int
 756764 dig2num(int c)
 757765 {
 758766         if (c >= 'a')
 759767                 c = c - 'a' + 10;
 760768         else if (c >= 'A')
 761769                 c = c - 'A' + 10;
 762770         else
 763771                 c = c - '0';
 764772         return c;
 765773 }
 766774 
 767775 /*
 768776  * Convert string numbers to unsigned long long and check overflow.
 769777  */
 770778 static void
 771779 cvtdig(int rad)
 772780 {
 773781         unsigned long long rv = 0;
 774782         unsigned long long rv2 = 0;
 775783         char *y = yytext;
 776784         int c;
 777785 
 778786         c = *y++;
 779787         if (rad == 16)
 780788                 y++;
 781789         while (isxdigit(c)) {
 782790                 rv = rv * rad + dig2num(c);
 783791                 /* check overflow */
 784792                 if (rv / rad < rv2)
 785793                         error("Constant \"%s\" is out of range", yytext);
 786794                 rv2 = rv;
 787795                 c = *y++;
 788796         }
 789797         y--;
 790798         while (*y == 'l' || *y == 'L')
 791799                 y++;
 792800         yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
 793801         yylval.node.nd_uval = rv;
 794802         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
 795803                 yylval.node.op = UNUMBER;
 796804         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
 797805                 /* too large for signed */
 798806                 error("Constant \"%s\" is out of range", yytext);
 799807 }
 800808 
 801809 static int
 802810 charcon(usch *p)
 803811 {
 804812         int val, c;
 805813 
 806814         p++; /* skip first ' */
 807815         val = 0;
 808816         if (*p++ == '\\') {
 809817                 switch (*p++) {
 810818                 case 'a': val = '\a'; break;
 811819                 case 'b': val = '\b'; break;
 812820                 case 'f': val = '\f'; break;
 813821                 case 'n': val = '\n'; break;
 814822                 case 'r': val = '\r'; break;
 815823                 case 't': val = '\t'; break;
 816824                 case 'v': val = '\v'; break;
 817825                 case '\"': val = '\"'; break;
 818826                 case '\'': val = '\''; break;
 819827                 case '\\': val = '\\'; break;
 820828                 case 'x':
 821829                         while (isxdigit(c = *p)) {
 822830                                 val = val * 16 + dig2num(c);
 823831                                 p++;
 824832                         }
 825833                         break;
 826834                 case '0': case '1': case '2': case '3': case '4':
 827835                 case '5': case '6': case '7':
 828836                         p--;
 829837                         while (isdigit(c = *p)) {
 830838                                 val = val * 8 + (c - '0');
 831839                                 p++;
 832840                         }
 833841                         break;
 834842                 default: val = p[-1];
 835843                 }
 836844 
 837845         } else
 838846                 val = p[-1];
 839847         return val;
 840848 }
 841849 
 842850 static void
 843851 chknl(int ignore)
 844852 {
 845853         int t;
 846854 
 847855         slow = 1;
 848856         while ((t = yylex()) == WSPACE)
 849857                 ;
 850858         if (t != '\n') {
 851859                 if (ignore) {
 852860                         warning("newline expected, got \"%s\"", yytext);
 853861                         /* ignore rest of line */
 854862                         while ((t = yylex()) && t != '\n')
 855863                                 ;
 856864                 }
 857865                 else
 858866                         error("newline expected, got \"%s\"", yytext);
 859867         }
 860868         slow = 0;
 861869 }
 862870 
 863871 static void
 864872 elsestmt(void)
 865873 {
 866874         if (flslvl) {
 867875                 if (elflvl > trulvl)
 868876                         ;
 869877                 else if (--flslvl!=0) {
 870878                         flslvl++;
 871879                 } else {
 872880                         trulvl++;
 873881                         prtline();
 874882                 }
 875883         } else if (trulvl) {
 876884                 flslvl++;
 877885                 trulvl--;
 878886         } else
 879887                 error("If-less else");
 880888         if (elslvl==trulvl+flslvl)
 881889                 error("Too many else");
 882890         elslvl=trulvl+flslvl;
 883891         chknl(1);
 884892 }
 885893 
 886894 static void
 887895 ifdefstmt(void)         
 888896 {
 889897         int t;
 890898 
 891899         if (flslvl) {
 892900                 /* just ignore the rest of the line */
 893901                 while (input() != '\n')
 894902                         ;
 895903                 unput('\n');
 896904                 yylex();
 897905                 flslvl++;
 898906                 return;
 899907         }
 900908         slow = 1;
 901909         do
 902910                 t = yylex();
 903911         while (t == WSPACE);
 904912         if (t != IDENT)
 905913                 error("bad ifdef");
 906914         slow = 0;
 907915         if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
 908916                 trulvl++;
 909917         else
 910918                 flslvl++;
 911919         chknl(0);
 912920 }
 913921 
 914922 static void
 915923 ifndefstmt(void)         
 916924 {
 917925         int t;
 918926 
 919927         slow = 1;
 920928         do
 921929                 t = yylex();
 922930         while (t == WSPACE);
 923931         if (t != IDENT)
 924932                 error("bad ifndef");
 925933         slow = 0;
 926934         if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
 927935                 trulvl++;
 928936         else
 929937                 flslvl++;
 930938         chknl(0);
 931939 }
 932940 
 933941 static void
 934942 endifstmt(void)         
 935943 {
 936944         if (flslvl) {
 937945                 flslvl--;
 938946                 if (flslvl == 0)
 939947                         prtline();
 940948         } else if (trulvl)
 941949                 trulvl--;
 942950         else
 943951                 error("If-less endif");
 944952         if (flslvl == 0)
 945953                 elflvl = 0;
 946954         elslvl = 0;
 947955         chknl(1);
 948956 }
 949957 
 950958 /*
 951959  * Note! Ugly!
 952960  * Walk over the string s and search for defined, and replace it with
 953961  * spaces and a 1 or 0.
 954962  */
 955963 static void
 956964 fixdefined(usch *s)
 957965 {
 958966         usch *bc, oc;
 959967 
 960968         for (; *s; s++) {
 961969                 if (*s != 'd')
 962970                         continue;
 963971                 if (memcmp(s, "defined", 7))
 964972                         continue;
 965973                 /* Ok, got defined, can scratch it now */
 966974                 memset(s, ' ', 7);
 967975                 s += 7;
 968976 #define WSARG(x) (x == ' ' || x == '\t')
 969977                 if (*s != '(' && !WSARG(*s))
 970978                         continue;
 971979                 while (WSARG(*s))
 972980                         s++;
 973981                 if (*s == '(')
 974982                         s++;
 975983                 while (WSARG(*s))
 976984                         s++;
 977985 #define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
 978986 #define NUMARG(x) (x >= '0' && x <= '9')
 979987                 if (!IDARG(*s))
 980988                         error("bad defined arg");
 981989                 bc = s;
 982990                 while (IDARG(*s) || NUMARG(*s))
 983991                         s++;
 984992                 oc = *s;
 985993                 *s = 0;
 986994                 *bc = (lookup(bc, FIND) != 0) + '0';
 987995                 memset(bc+1, ' ', s-bc-1);
 988996                 *s = oc;
 989997         }
 990998 }
 991999 
 9921000 /*
 9931001  * get the full line of identifiers after an #if, pushback a WARN and
 9941002  * the line and prepare for expmac() to expand.
 9951003  * This is done before switching state.  When expmac is finished,
 9961004  * pushback the expanded line, change state and call yyparse.
 9971005  */
 9981006 static void
 9991007 storepb(void)
 10001008 {
 10011009         usch *opb = stringbuf;
 10021010         int c;
 10031011 
 10041012         while ((c = input()) != '\n') {
 10051013                 if (c == '/') {
 10061014                          if ((c = input()) == '*') {
 10071015                                 /* ignore comments here whatsoever */
 10081016                                 usch *g = stringbuf;
 10091017                                 getcmnt();
 10101018                                 stringbuf = g;
 10111019                                 continue;
 10121020                         } else if (c == '/') {
 10131021                                 while ((c = input()) && c != '\n')
 10141022                                         ;
 10151023                                 break;
 10161024                         }
 10171025                         unput(c);
 10181026                         c = '/';
 10191027                 }
 10201028                 savch(c);
 10211029         }
 10221030         cunput('\n');
 10231031         savch(0);
 10241032         fixdefined(opb); /* XXX can fail if #line? */
 10251033         cunput(1); /* WARN XXX */
 10261034         unpstr(opb);
 10271035         stringbuf = opb;
 10281036         slow = 1;
 10291037         expmac(NULL);
 10301038         slow = 0;
 10311039         /* line now expanded */
 10321040         while (stringbuf > opb)
 10331041                 cunput(*--stringbuf);
 10341042 }
 10351043 
 10361044 static void
 10371045 ifstmt(void)
 10381046 {
 10391047         if (flslvl == 0) {
 10401048                 slow = 1;
 10411049                 if (yyparse())
 10421050                         ++trulvl;
 10431051                 else
 10441052                         ++flslvl;
 10451053                 slow = 0;
 10461054         } else
 10471055                 ++flslvl;
 10481056 }
 10491057 
 10501058 static void
 10511059 elifstmt(void)
 10521060 {
 10531061         if (flslvl == 0)
 10541062                 elflvl = trulvl;
 10551063         if (flslvl) {
 10561064                 if (elflvl > trulvl)
 10571065                         ;
 10581066                 else if (--flslvl!=0)
 10591067                         ++flslvl;
 10601068                 else {
 10611069                         slow = 1;
 10621070                         if (yyparse()) {
 10631071                                 ++trulvl;
 10641072                                 prtline();
 10651073                         } else
 10661074                                 ++flslvl;
 10671075                         slow = 0;
 10681076                 }
 10691077         } else if (trulvl) {
 10701078                 ++flslvl;
 10711079                 --trulvl;
 10721080         } else
 10731081                 error("If-less elif");
 10741082 }
 10751083 
 10761084 static usch *
 10771085 svinp(void)
 10781086 {
 10791087         int c;
 10801088         usch *cp = stringbuf;
 10811089 
 10821090         while ((c = input()) && c != '\n')
 10831091                 savch(c);
 10841092         savch('\n');
 10851093         savch(0);
 10861094         BEGIN 0;
 10871095         return cp;
 10881096 }
 10891097 
 10901098 static void
 10911099 cpperror(void)
 10921100 {
 10931101         usch *cp;
 10941102         int c;
 10951103 
 10961104         if (flslvl)
 10971105                 return;
 10981106         c = yylex();
 10991107         if (c != WSPACE && c != '\n')
 11001108                 error("bad error");
 11011109         cp = svinp();
 11021110         if (flslvl)
 11031111                 stringbuf = cp;
 11041112         else
 11051113                 error("%s", cp);
 11061114 }
 11071115 
 11081116 static void
 11091117 undefstmt(void)
 11101118 {
 11111119         struct symtab *np;
 11121120 
 11131121         slow = 1;
 11141122         if (yylex() != WSPACE || yylex() != IDENT)
 11151123                 error("bad undef");
 11161124         if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
 11171125                 np->value = 0;
 11181126         slow = 0;
 11191127         chknl(0);
 11201128 }
 11211129 
 11221130 static void
 11231131 pragmastmt(void)
 11241132 {
 11251133         int c;
 11261134 
 11271135         slow = 1;
 11281136         if (yylex() != WSPACE)
 11291137                 error("bad pragma");
 11301138         if (!flslvl)
 11311139                 putstr((usch *)"#pragma ");
 11321140         do {
 11331141                 c = input();
 11341142                 if (!flslvl)
 11351143                         putch(c);       /* Do arg expansion instead? */
 11361144         } while (c && c != '\n');
<>1137 -        ifiles->lineno++;
  1145+        if (c == '\n')
  1146+                unch(c);
<_11381147         prtline();
 11391148         slow = 0;
 11401149 }
 11411150 
 11421151 static void
 11431152 badop(const char *op)
 11441153 {
 11451154         error("invalid operator in preprocessor expression: %s", op);
 11461155 }
 11471156 
 11481157 int
 11491158 cinput()
 11501159 {
 11511160         return input();
 11521161 }
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-18 18:23 +0100