Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.15
 
1.16
 
MAIN:gmcgarry:20090414232246
 
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 
<> 84+#ifdef YYTEXT_POINTER
  85+static char buf[CPPBUF];
  86+char *yytext = buf;
  87+#else
8488 char yytext[CPPBUF];
<> 89+#endif
  90+
<_8591 static int owasnl, wasnl = 1;
 8692 
 8793 static void
 8894 unch(int c)
 8995 {
 9096                 
 9197         --ifiles->curptr;
 9298         if (ifiles->curptr < ifiles->bbuf)
 9399                 error("pushback buffer full");
 94100         *ifiles->curptr = c;
 95101 }
 96102 
 97103 
 98104 int
 99105 yylex()
 100106 {
 101107         int ch;
 102108         int yyp;
 103109         int os, mixed, haspmd;
 104110 
 105111 zagain:
 106112         yyp = 0;
 107113         yytext[yyp++] = ch = inch();
 108114         owasnl = wasnl;
 109115         wasnl = 0;
 110116         switch (ch) {
 111117         case -1:
 112118                 return 0;
 113119         case '\n':
 114120                 os = YYSTATE;
 115121 
 116122                 wasnl = 1;
 117123                 if (os != IFR)
 118124                         BEGIN 0;
 119125                 ifiles->lineno++;
 120126                 if (flslvl == 0) {
 121127                         if (ifiles->lineno == 1)
 122128                                 prtline();
 123129                         else
 124130                                 putch('\n');
 125131                 }
 126132                 if ((os != 0 || slow) && !contr)
 127133                         goto yyret;
 128134                 contr = 0;
 129135                 break;
 130136 
 131137         case '\r': /* Ignore CR's */
 132138                 yyp = 0;
 133139                 break;
 134140 
 135141 #define CHK(x,y) if (state != IFR) goto any; \
 136142         if ((ch = input()) != y) { unput(ch); ch = x; goto any; } \
 137143         yytext[yyp++] = ch
 138144 
 139145         case '+': CHK('+','+'); badop("++"); break;
 140146         case '-': CHK('-','-'); badop("--"); break;
 141147         case '=': CHK('=','='); ch = EQ; goto yyret;
 142148         case '!': CHK('!','='); ch = NE; goto yyret;
 143149         case '|': CHK('|','|'); ch = OROR; goto yyret;
 144150         case '&': CHK('&','&'); ch = ANDAND; goto yyret;
 145151         case '<':
 146152                 if (state != IFR) goto any;
 147153                 if ((ch = inch()) == '=') {
 148154                         yytext[yyp++] = ch; ch = LE; goto yyret;
 149155                 }
 150156                 if (ch == '<') { yytext[yyp++] = ch; ch = LS; goto yyret; }
 151157                 unch(ch);
 152158                 ch = '<';
 153159                 goto any;
 154160         case '>':
 155161                 if (state != IFR) goto any;
 156162                 if ((ch = inch()) == '=') {
 157163                         yytext[yyp++] = ch; ch = GE; goto yyret;
 158164                 }
 159165                 if (ch == '>') { yytext[yyp++] = ch; ch = RS; goto yyret; }
 160166                 unch(ch);
 161167                 ch = '>';
 162168                 goto any;
 163169 
 164170 
 165171         case '0': case '1': case '2': case '3': case '4': case '5':
 166172         case '6': case '7': case '8': case '9':
 167173                 /* readin a "pp-number" */
 168174                 mixed = haspmd = 0;
 169175 ppnum:          for (;;) {
 170176                         ch = input();
 171177                         if (ch == 'e' || ch == 'E' || ch == 'p' || ch == 'P') {
 172178                                 yytext[yyp++] = ch;
 173179                                 mixed = 1;
 174180                                 ch = input();
 175181                                 if (ch == '-' || ch == '+') {
 176182                                         yytext[yyp++] = ch;
 177183                                         haspmd = 1;
 178184                                 } else
 179185                                         unput(ch);
 180186                                 continue;
 181187                         }
 182188                         if (isdigit(ch) || isalpha(ch) ||
 183189                             ch == '_' || ch == '.') {
 184190                                 yytext[yyp++] = ch;
 185191                                 if (ch == '.')
 186192                                         haspmd = 1;
 187193                                 if (!isdigit(ch))
 188194                                         mixed = 1;
 189195                                 continue;
 190196                         }
 191197                         break;
 192198                 }
 193199                 unput(ch);
 194200                 yytext[yyp] = 0;
 195201 
 196202                 if (mixed == 1 && slow && (state == 0 || state == DEF))
 197203                         return IDENT;
 198204 
 199205                 if (mixed == 0) {
 200206                         if (slow && !YYSTATE)
 201207                                 return IDENT;
 202208                         scale = yytext[0] == '0' ? 8 : 10;
 203209                         goto num;
 204210                 } else if (yytext[0] == '0' &&
 205211                     (yytext[1] == 'x' || yytext[1] == 'X')) {
 206212                         scale = 16;
 207213 num:                    if (YYSTATE == IFR)
 208214                                 cvtdig(scale);
 209215                         PRTOUT(NUMBER);
 210216                 } else if (yytext[0] == '0' && isdigit(yytext[1])) {
 211217                         scale = 8; goto num;
 212218                 } else if (haspmd) {
 213219                         PRTOUT(FPOINT);
 214220                 } else {
 215221                         scale = 10; goto num;
 216222                 }
 217223                 goto zagain;
 218224 
 219225 
 220226         case '\'':
 221227 chlit:          if (tflag && !(YYSTATE || slow))
 222228                         goto any;
 223229                 for (;;) {
 224230                         if ((ch = input()) == '\\') {
 225231                                 yytext[yyp++] = ch;
 226232                                 yytext[yyp++] = input();
 227233                                 continue;
 228234                         } else if (ch == '\n') {
 229235                                 /* not a constant */
 230236                                 while (yyp > 1)
 231237                                         unput(yytext[--yyp]);
 232238                                 ch = '\'';
 233239                                 goto any;
 234240                         } else
 235241                                 yytext[yyp++] = ch;
 236242                         if (ch == '\'')
 237243                                 break;
 238244                 }
 239245                 yytext[yyp] = 0;
 240246 
 241247                 if (YYSTATE || slow) {
 242248                         yylval.node.op = NUMBER;
 243249                         yylval.node.nd_val = charcon((usch *)yytext);
 244250                         return (NUMBER);
 245251                 }
 246252                 if (!flslvl)
 247253                         putstr((usch *)yytext);
 248254                 goto zagain;
 249255 
 250256         case ' ':
 251257         case '\t':
 252258                 if (state == IFR)
 253259                         goto zagain;
 254260 
 255261                 while ((ch = input()) == ' ' || ch == '\t')
 256262                         yytext[yyp++] = ch;
 257263                 if (owasnl == 0) {
 258264 b1:                     unput(ch);
 259265                         yytext[yyp] = 0;
 260266                         PRTOUT(WSPACE);
 261267                 } else if (ch != '#') {
 262268                         goto b1;
 263269                 } else {
 264270                         extern int inmac;
 265271 
 266272 contr:                  while ((ch = input()) == ' ' || ch == '\t')
 267273                                 ;
 268274                         unch(ch);
 269275                         if (inmac)
 270276                                 error("preprocessor directive found "
 271277                                     "while expanding macro");
 272278                         contr = 1;
 273279                         BEGIN CONTR;
 274280 
 275281                 }
 276282                 goto zagain;
 277283 
 278284         case '/':
 279285                 if ((ch = input()) == '/') {
 280286                         do {
 281287                                 yytext[yyp++] = ch;
 282288                                 ch = input();
 283289                         } while (ch && ch != '\n');
 284290                         yytext[yyp] = 0;
 285291                         unch(ch);
 286292                         if (Cflag && !flslvl && !slow)
 287293                                 putstr((usch *)yytext);
 288294                         else if (!flslvl)
 289295                                 putch(' ');
 290296                         goto zagain;
 291297                 } else if (ch == '*') {
 292298                         int c, wrn;
 293299                         int prtcm = Cflag && !flslvl && !slow;
 294300                         extern int readmac;
 295301 
 296302                         if (Cflag && !flslvl && readmac)
 297303                                 return CMNT;
 298304 
 299305                         if (prtcm)
 300306                                 putstr((usch *)yytext);
 301307                         wrn = 0;
 302308                 more:   while ((c = input()) && c != '*') {
 303309                                 if (c == '\n')
 304310                                         putch(c), ifiles->lineno++;
 305311                                 else if (c == 1) /* WARN */
 306312                                         wrn = 1;
 307313                                 else if (prtcm)
 308314                                         putch(c);
 309315                         }
 310316                         if (c == 0)
 311317                                 return 0;
 312318                         if (prtcm)
 313319                                 putch(c);
 314320                         if ((c = input()) && c != '/') {
 315321                                 unput(c);
 316322                                 goto more;
 317323                         }
 318324                         if (prtcm)
 319325                                 putch(c);
 320326                         if (c == 0)
 321327                                 return 0;
 322328                         if (!tflag && !Cflag && !flslvl)
 323329                                 unput(' ');
 324330                         if (wrn)
 325331                                 unput(1);
 326332                         goto zagain;
 327333                 }
 328334                 unch(ch);
 329335                 ch = '/';
 330336                 goto any;
 331337 
 332338         case '#':
 333339                 if (state != DEF) {
 334340                         if (owasnl)
 335341                                 goto contr;
 336342                         goto any;
 337343                 }
 338344                 if ((ch = input()) == '#') {
 339345                         yytext[yyp++] = ch;
 340346                         ch = CONCAT;
 341347                 } else {
 342348                         unput(ch);
 343349                         ch = MKSTR;
 344350                 }
 345351                 goto yyret;
 346352                 
 347353         case '.':
 348354                 if (state != DEF) {
 349355                         ch = input();
 350356                         if (isdigit(ch)) {
 351357                                 yytext[yyp++] = ch;
 352358                                 mixed = haspmd = 1;
 353359                                 goto ppnum;
 354360                         } else {
 355361                                 unput(ch);
 356362                                 ch = '.';
 357363                         }
 358364                         goto any;
 359365                 }
 360366                 if ((ch = input()) != '.') {
 361367                         unput(ch);
 362368                         ch = '.';
 363369                         goto any;
 364370                 }
 365371                 if ((ch = input()) != '.') {
 366372                         unput(ch);
 367373                         unput('.');
 368374                         ch = '.';
 369375                         goto any;
 370376                 }
 371377                 yytext[yyp++] = ch;
 372378                 yytext[yyp++] = ch;
 373379                 ch = ELLIPS;
 374380                 goto yyret;
 375381 
 376382 
 377383         case '\"':
 378384         strng:
 379385                 for (;;) {
 380386                         if ((ch = input()) == '\\') {
 381387                                 yytext[yyp++] = ch;
 382388                                 yytext[yyp++] = input();
 383389                                 continue;
 384390                         } else
 385391                                 yytext[yyp++] = ch;
 386392                         if (ch == '\"')
 387393                                 break;
 388394                 }
 389395                 yytext[yyp] = 0;
 390396                 { PRTOUT(STRING); }
 391397                 break;
 392398 
 393399         case 'L':
 394400                 if ((ch = input()) == '\"') {
 395401                         yytext[yyp++] = ch;
 396402                         goto strng;
 397403                 } else if (ch == '\'') {
 398404                         yytext[yyp++] = ch;
 399405                         goto chlit;
 400406                 }
 401407                 unput(ch);
 402408                 /* FALLTHROUGH */
 403409 
 404410         /* Yetch, all identifiers */
 405411         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
 406412         case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
 407413         case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
 408414         case 's': case 't': case 'u': case 'v': case 'w': case 'x':
 409415         case 'y': case 'z':
 410416         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
 411417         case 'G': case 'H': case 'I': case 'J': case 'K':
 412418         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
 413419         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
 414420         case 'Y': case 'Z':
 415421         case '_': { /* {L}({L}|{D})* */
 416422                 struct symtab *nl;
 417423 
 418424                 /* Special hacks */
 419425                 for (;;) { /* get chars */
 420426                         ch = input();
 421427                         if (isalpha(ch) || isdigit(ch) || ch == '_') {
 422428                                 yytext[yyp++] = ch;
 423429                         } else {
 424430                                 unput(ch);
 425431                                 break;
 426432                         }
 427433                 }
 428434                 yytext[yyp] = 0; /* need already string */
 429435 
 430436                 switch (state) {
 431437                 case DEF:
 432438                         if (strcmp(yytext, "__VA_ARGS__") == 0)
 433439                                 return VA_ARGS;
 434440                         break;
 435441                 case CONTR:
 436442 #define CC(s)   if (strcmp(yytext, s) == 0)
 437443                         CC("ifndef") {
 438444                                 contr = 0; ifndefstmt();
 439445                                 goto zagain;
 440446                         } else CC("ifdef") {
 441447                                 contr = 0; ifdefstmt();
 442448                                 goto zagain;
 443449                         } else CC("if") {
 444450                                 contr = 0; storepb(); BEGIN IFR;
 445451                                 ifstmt(); BEGIN 0;
 446452                                 goto zagain;
 447453                         } else CC("include") {
 448454                                 contr = 0; BEGIN 0; include(); prtline();
 449455                                 goto zagain;
 450456                         } else CC("else") {
 451457                                 contr = 0; elsestmt();
 452458                                 goto zagain;
 453459                         } else CC("endif") {
 454460                                 contr = 0; endifstmt();
 455461                                 goto zagain;
 456462                         } else CC("error") {
 457463                                 contr = 0; if (slow) return IDENT;
 458464                                 cpperror(); BEGIN 0;
 459465                                 goto zagain;
 460466                         } else CC("define") {
 461467                                 contr = 0; BEGIN DEF; define(); BEGIN 0;
 462468                                 goto zagain;
 463469                         } else CC("undef") {
 464470                                 contr = 0; if (slow) return IDENT; undefstmt();
 465471                                 goto zagain;
 466472                         } else CC("line") {
 467473                                 contr = 0; storepb(); BEGIN 0; line();
 468474                                 goto zagain;
 469475                         } else CC("pragma") {
 470476                                 contr = 0; pragmastmt(); BEGIN 0;
 471477                                 goto zagain;
 472478                         } else CC("elif") {
 473479                                 contr = 0; storepb(); BEGIN IFR;
 474480                                 elifstmt(); BEGIN 0;
 475481                                 goto zagain;
 476482                         }
 477483                         break;
 478484                 case  IFR:
 479485                         CC("defined") {
 480486                                 int p, c;
 481487                                 gotdef = 1;
 482488                                 if ((p = c = yylex()) == '(')
 483489                                         c = yylex();
 484490                                 if (c != IDENT || (p != IDENT && p != '('))
 485491                                         error("syntax error");
 486492                                 if (p == '(' && yylex() != ')')
 487493                                         error("syntax error");
 488494                                 return NUMBER;
 489495                         } else {
 490496                                 yylval.node.op = NUMBER;
 491497                                 if (gotdef) {
 492498                                         yylval.node.nd_val
 493499                                             = lookup((usch *)yytext, FIND) != 0;
 494500                                         gotdef = 0;
 495501                                         return IDENT;
 496502                                 }
 497503                                 yylval.node.nd_val = 0;
 498504                                 return NUMBER;
 499505                         }
 500506                 }
 501507 
 502508                 /* end special hacks */
 503509 
 504510                 if (slow)
 505511                         return IDENT;
 506512                 if (YYSTATE == CONTR) {
 507513                         if (flslvl == 0) {
 508514                                 /*error("undefined control");*/
 509515                                 while (input() != '\n')
 510516                                         ;
 511517                                 unput('\n');
 512518                                 BEGIN 0;
 513519                                 goto xx;
 514520                         } else {
 515521                                 BEGIN 0; /* do nothing */
 516522                         }
 517523                 }
 518524                 if (flslvl) {
 519525                         ; /* do nothing */
 520526                 } else if (isdigit((int)yytext[0]) == 0 &&
 521527                     (nl = lookup((usch *)yytext, FIND)) != 0) {
 522528                         usch *op = stringbuf;
 523529                         putstr(gotident(nl));
 524530                         stringbuf = op;
 525531                 } else
 526532                         putstr((usch *)yytext);
 527533                 xx:
 528534                 goto zagain;
 529535         }
 530536 
 531537         default:
 532538         any:
 533539                 if (state == IFR)
 534540                         goto yyret;
 535541                 yytext[yyp] = 0;
 536542                 if (contr) {
 537543                         while (input() != '\n')
 538544                                 ;
 539545                         unput('\n');
 540546                         BEGIN 0;
 541547                         contr = 0;
 542548                         goto yy;
 543549                 }
 544550                 if (YYSTATE || slow)
 545551                         return yytext[0];
 546552                 if (yytext[0] == 6) { /* PRAGS */
 547553                         usch *obp = stringbuf;
 548554                         extern usch *prtprag(usch *);
 549555                         *stringbuf++ = yytext[0];
 550556                         do {
 551557                                 *stringbuf = input();
 552558                         } while (*stringbuf++ != 14);
 553559                         prtprag(obp);
 554560                         stringbuf = obp;
 555561                 } else {
 556562                         PRTOUT(yytext[0]);
 557563                 }
 558564                 yy:
 559565                 yyp = 0;
 560566                 break;
 561567 
 562568         } /* endcase */
 563569         goto zagain;
 564570 
 565571 yyret:
 566572         yytext[yyp] = 0;
 567573         return ch;
 568574 }
 569575 
 570576 usch *yyp, yybuf[CPPBUF];
 571577 
 572578 int yylex(void);
 573579 int yywrap(void);
 574580 
 575581 static int
 576582 inpch(void)
 577583 {
 578584         int len;
 579585 
 580586         if (ifiles->curptr < ifiles->maxread)
 581587                 return *ifiles->curptr++;
 582588 
 583589         if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
 584590                 error("read error on file %s", ifiles->orgfn);
 585591         if (len == 0)
 586592                 return -1;
 587593         ifiles->curptr = ifiles->buffer;
 588594         ifiles->maxread = ifiles->buffer + len;
 589595         return inpch();
 590596 }
 591597 
 592598 static int
 593599 inch(void)
 594600 {
 595601         int c;
 596602 
 597603 again:  switch (c = inpch()) {
 598604         case '\\': /* continued lines */
 599605 msdos:          if ((c = inpch()) == '\n') {
 600606                         ifiles->lineno++;
 601607                         putch('\n');
 602608                         goto again;
 603609                 } else if (c == '\r')
 604610                         goto msdos;
 605611                 unch(c);
 606612                 return '\\';
 607613         case '?': /* trigraphs */
 608614                 if ((c = inpch()) != '?') {
 609615                         unch(c);
 610616                         return '?';
 611617                 }
 612618                 switch (c = inpch()) {
 613619                 case '=': c = '#'; break;
 614620                 case '(': c = '['; break;
 615621                 case ')': c = ']'; break;
 616622                 case '<': c = '{'; break;
 617623                 case '>': c = '}'; break;
 618624                 case '/': c = '\\'; break;
 619625                 case '\'': c = '^'; break;
 620626                 case '!': c = '|'; break;
 621627                 case '-': c = '~'; break;
 622628                 default:
 623629                         unch(c);
 624630                         unch('?');
 625631                         return '?';
 626632                 }
 627633                 unch(c);
 628634                 goto again;
 629635         default:
 630636                 return c;
 631637         }
 632638 }
 633639 
 634640 /*
 635641  * Let the command-line args be faked defines at beginning of file.
 636642  */
 637643 static void
 638644 prinit(struct initar *it, struct includ *ic)
 639645 {
 640646         char *a, *pre, *post;
 641647 
 642648         if (it->next)
 643649                 prinit(it->next, ic);
 644650         pre = post = NULL; /* XXX gcc */
 645651         switch (it->type) {
 646652         case 'D':
 647653                 pre = "#define ";
 648654                 if ((a = strchr(it->str, '=')) != NULL) {
 649655                         *a = ' ';
 650656                         post = "\n";
 651657                 } else
 652658                         post = " 1\n";
 653659                 break;
 654660         case 'U':
 655661                 pre = "#undef ";
 656662                 post = "\n";
 657663                 break;
 658664         case 'i':
 659665                 pre = "#include \"";
 660666                 post = "\"\n";
 661667                 break;
 662668         default:
 663669                 error("prinit");
 664670         }
 665671         strlcat((char *)ic->buffer, pre, CPPBUF+1);
 666672         strlcat((char *)ic->buffer, it->str, CPPBUF+1);
 667673         if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
 668674                 error("line exceeds buffer size");
 669675 
 670676         ic->lineno--;
 671677         while (*ic->maxread)
 672678                 ic->maxread++;
 673679 }
 674680 
 675681 /*
 676682  * A new file included.
 677683  * If ifiles == NULL, this is the first file and already opened (stdin).
 678684  * Return 0 on success, -1 if file to be included is not found.
 679685  */
 680686 int
 681687 pushfile(usch *file)
 682688 {
 683689         extern struct initar *initar;
 684690         struct includ ibuf;
 685691         struct includ *ic;
 686692         int c, otrulvl;
 687693 
 688694         ic = &ibuf;
 689695         ic->next = ifiles;
 690696 
 691697         slow = 0;
 692698         if (file != NULL) {
 693699                 if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
 694700                         return -1;
 695701                 ic->orgfn = ic->fname = file;
 696702                 if (++inclevel > MAX_INCLEVEL)
 697703                         error("Limit for nested includes exceeded");
 698704         } else {
 699705                 ic->infil = 0;
 700706                 ic->orgfn = ic->fname = (usch *)"<stdin>";
 701707         }
 702708         ic->buffer = ic->bbuf+NAMEMAX;
 703709         ic->curptr = ic->buffer;
 704710         ifiles = ic;
 705711         ic->lineno = 1;
 706712         ic->maxread = ic->curptr;
 707713         prtline();
 708714         if (initar) {
 709715                 *ic->maxread = 0;
 710716                 prinit(initar, ic);
 711717                 if (dMflag)
 712718                         write(ofd, ic->buffer, strlen((char *)ic->buffer));
 713719                 initar = NULL;
 714720         }
 715721 
 716722         otrulvl = trulvl;
 717723 
 718724         if ((c = yylex()) != 0)
 719725                 error("yylex returned %d", c);
 720726 
 721727 wasnl = owasnl;
 722728         if (otrulvl != trulvl || flslvl)
 723729                 error("unterminated conditional");
 724730 
 725731         ifiles = ic->next;
 726732         close(ic->infil);
 727733         inclevel--;
 728734         return 0;
 729735 }
 730736 
 731737 /*
 732738  * Print current position to output file.
 733739  */
 734740 void
 735741 prtline()
 736742 {
 737743         usch *s, *os = stringbuf;
 738744 
 739745         if (Mflag) {
 740746                 if (dMflag)
 741747                         return; /* no output */
 742748                 if (ifiles->lineno == 1) {
 743749                         s = sheap("%s: %s\n", Mfile, ifiles->fname);
 744750                         write(ofd, s, strlen((char *)s));
 745751                 }
 746752         } else if (!Pflag)
 747753                 putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
 748754         stringbuf = os;
 749755 }
 750756 
 751757 void
 752758 cunput(int c)
 753759 {
 754760 #ifdef CPP_DEBUG
 755761         extern int dflag;
 756762         if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
 757763 #endif
 758764         unput(c);
 759765 }
 760766 
 761767 int yywrap(void) { return 1; }
 762768 
 763769 static int
 764770 dig2num(int c)
 765771 {
 766772         if (c >= 'a')
 767773                 c = c - 'a' + 10;
 768774         else if (c >= 'A')
 769775                 c = c - 'A' + 10;
 770776         else
 771777                 c = c - '0';
 772778         return c;
 773779 }
 774780 
 775781 /*
 776782  * Convert string numbers to unsigned long long and check overflow.
 777783  */
 778784 static void
 779785 cvtdig(int rad)
 780786 {
 781787         unsigned long long rv = 0;
 782788         unsigned long long rv2 = 0;
 783789         char *y = yytext;
 784790         int c;
 785791 
 786792         c = *y++;
 787793         if (rad == 16)
 788794                 y++;
 789795         while (isxdigit(c)) {
 790796                 rv = rv * rad + dig2num(c);
 791797                 /* check overflow */
 792798                 if (rv / rad < rv2)
 793799                         error("Constant \"%s\" is out of range", yytext);
 794800                 rv2 = rv;
 795801                 c = *y++;
 796802         }
 797803         y--;
 798804         while (*y == 'l' || *y == 'L')
 799805                 y++;
 800806         yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
 801807         yylval.node.nd_uval = rv;
 802808         if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
 803809                 yylval.node.op = UNUMBER;
 804810         if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
 805811                 /* too large for signed */
 806812                 error("Constant \"%s\" is out of range", yytext);
 807813 }
 808814 
 809815 static int
 810816 charcon(usch *p)
 811817 {
 812818         int val, c;
 813819 
 814820         p++; /* skip first ' */
 815821         val = 0;
 816822         if (*p++ == '\\') {
 817823                 switch (*p++) {
 818824                 case 'a': val = '\a'; break;
 819825                 case 'b': val = '\b'; break;
 820826                 case 'f': val = '\f'; break;
 821827                 case 'n': val = '\n'; break;
 822828                 case 'r': val = '\r'; break;
 823829                 case 't': val = '\t'; break;
 824830                 case 'v': val = '\v'; break;
 825831                 case '\"': val = '\"'; break;
 826832                 case '\'': val = '\''; break;
 827833                 case '\\': val = '\\'; break;
 828834                 case 'x':
 829835                         while (isxdigit(c = *p)) {
 830836                                 val = val * 16 + dig2num(c);
 831837                                 p++;
 832838                         }
 833839                         break;
 834840                 case '0': case '1': case '2': case '3': case '4':
 835841                 case '5': case '6': case '7':
 836842                         p--;
 837843                         while (isdigit(c = *p)) {
 838844                                 val = val * 8 + (c - '0');
 839845                                 p++;
 840846                         }
 841847                         break;
 842848                 default: val = p[-1];
 843849                 }
 844850 
 845851         } else
 846852                 val = p[-1];
 847853         return val;
 848854 }
 849855 
 850856 static void
 851857 chknl(int ignore)
 852858 {
 853859         int t;
 854860 
 855861         slow = 1;
 856862         while ((t = yylex()) == WSPACE)
 857863                 ;
 858864         if (t != '\n') {
 859865                 if (ignore) {
 860866                         warning("newline expected, got \"%s\"", yytext);
 861867                         /* ignore rest of line */
 862868                         while ((t = yylex()) && t != '\n')
 863869                                 ;
 864870                 }
 865871                 else
 866872                         error("newline expected, got \"%s\"", yytext);
 867873         }
 868874         slow = 0;
 869875 }
 870876 
 871877 static void
 872878 elsestmt(void)
 873879 {
 874880         if (flslvl) {
 875881                 if (elflvl > trulvl)
 876882                         ;
 877883                 else if (--flslvl!=0) {
 878884                         flslvl++;
 879885                 } else {
 880886                         trulvl++;
 881887                         prtline();
 882888                 }
 883889         } else if (trulvl) {
 884890                 flslvl++;
 885891                 trulvl--;
 886892         } else
 887893                 error("If-less else");
 888894         if (elslvl==trulvl+flslvl)
 889895                 error("Too many else");
 890896         elslvl=trulvl+flslvl;
 891897         chknl(1);
 892898 }
 893899 
 894900 static void
 895901 ifdefstmt(void)         
 896902 {
 897903         int t;
 898904 
 899905         if (flslvl) {
 900906                 /* just ignore the rest of the line */
 901907                 while (input() != '\n')
 902908                         ;
 903909                 unput('\n');
 904910                 yylex();
 905911                 flslvl++;
 906912                 return;
 907913         }
 908914         slow = 1;
 909915         do
 910916                 t = yylex();
 911917         while (t == WSPACE);
 912918         if (t != IDENT)
 913919                 error("bad ifdef");
 914920         slow = 0;
 915921         if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
 916922                 trulvl++;
 917923         else
 918924                 flslvl++;
 919925         chknl(0);
 920926 }
 921927 
 922928 static void
 923929 ifndefstmt(void)         
 924930 {
 925931         int t;
 926932 
 927933         slow = 1;
 928934         do
 929935                 t = yylex();
 930936         while (t == WSPACE);
 931937         if (t != IDENT)
 932938                 error("bad ifndef");
 933939         slow = 0;
 934940         if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
 935941                 trulvl++;
 936942         else
 937943                 flslvl++;
 938944         chknl(0);
 939945 }
 940946 
 941947 static void
 942948 endifstmt(void)         
 943949 {
 944950         if (flslvl) {
 945951                 flslvl--;
 946952                 if (flslvl == 0)
 947953                         prtline();
 948954         } else if (trulvl)
 949955                 trulvl--;
 950956         else
 951957                 error("If-less endif");
 952958         if (flslvl == 0)
 953959                 elflvl = 0;
 954960         elslvl = 0;
 955961         chknl(1);
 956962 }
 957963 
 958964 /*
 959965  * Note! Ugly!
 960966  * Walk over the string s and search for defined, and replace it with
 961967  * spaces and a 1 or 0.
 962968  */
 963969 static void
 964970 fixdefined(usch *s)
 965971 {
 966972         usch *bc, oc;
 967973 
 968974         for (; *s; s++) {
 969975                 if (*s != 'd')
 970976                         continue;
 971977                 if (memcmp(s, "defined", 7))
 972978                         continue;
 973979                 /* Ok, got defined, can scratch it now */
 974980                 memset(s, ' ', 7);
 975981                 s += 7;
 976982 #define WSARG(x) (x == ' ' || x == '\t')
 977983                 if (*s != '(' && !WSARG(*s))
 978984                         continue;
 979985                 while (WSARG(*s))
 980986                         s++;
 981987                 if (*s == '(')
 982988                         s++;
 983989                 while (WSARG(*s))
 984990                         s++;
 985991 #define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
 986992 #define NUMARG(x) (x >= '0' && x <= '9')
 987993                 if (!IDARG(*s))
 988994                         error("bad defined arg");
 989995                 bc = s;
 990996                 while (IDARG(*s) || NUMARG(*s))
 991997                         s++;
 992998                 oc = *s;
 993999                 *s = 0;
 9941000                 *bc = (lookup(bc, FIND) != 0) + '0';
 9951001                 memset(bc+1, ' ', s-bc-1);
 9961002                 *s = oc;
 9971003         }
 9981004 }
 9991005 
 10001006 /*
 10011007  * get the full line of identifiers after an #if, pushback a WARN and
 10021008  * the line and prepare for expmac() to expand.
 10031009  * This is done before switching state.  When expmac is finished,
 10041010  * pushback the expanded line, change state and call yyparse.
 10051011  */
 10061012 static void
 10071013 storepb(void)
 10081014 {
 10091015         usch *opb = stringbuf;
 10101016         int c;
 10111017 
 10121018         while ((c = input()) != '\n') {
 10131019                 if (c == '/') {
 10141020                          if ((c = input()) == '*') {
 10151021                                 /* ignore comments here whatsoever */
 10161022                                 usch *g = stringbuf;
 10171023                                 getcmnt();
 10181024                                 stringbuf = g;
 10191025                                 continue;
 10201026                         } else if (c == '/') {
 10211027                                 while ((c = input()) && c != '\n')
 10221028                                         ;
 10231029                                 break;
 10241030                         }
 10251031                         unput(c);
 10261032                         c = '/';
 10271033                 }
 10281034                 savch(c);
 10291035         }
 10301036         cunput('\n');
 10311037         savch(0);
 10321038         fixdefined(opb); /* XXX can fail if #line? */
 10331039         cunput(1); /* WARN XXX */
 10341040         unpstr(opb);
 10351041         stringbuf = opb;
 10361042         slow = 1;
 10371043         expmac(NULL);
 10381044         slow = 0;
 10391045         /* line now expanded */
 10401046         while (stringbuf > opb)
 10411047                 cunput(*--stringbuf);
 10421048 }
 10431049 
 10441050 static void
 10451051 ifstmt(void)
 10461052 {
 10471053         if (flslvl == 0) {
 10481054                 slow = 1;
 10491055                 if (yyparse())
 10501056                         ++trulvl;
 10511057                 else
 10521058                         ++flslvl;
 10531059                 slow = 0;
 10541060         } else
 10551061                 ++flslvl;
 10561062 }
 10571063 
 10581064 static void
 10591065 elifstmt(void)
 10601066 {
 10611067         if (flslvl == 0)
 10621068                 elflvl = trulvl;
 10631069         if (flslvl) {
 10641070                 if (elflvl > trulvl)
 10651071                         ;
 10661072                 else if (--flslvl!=0)
 10671073                         ++flslvl;
 10681074                 else {
 10691075                         slow = 1;
 10701076                         if (yyparse()) {
 10711077                                 ++trulvl;
 10721078                                 prtline();
 10731079                         } else
 10741080                                 ++flslvl;
 10751081                         slow = 0;
 10761082                 }
 10771083         } else if (trulvl) {
 10781084                 ++flslvl;
 10791085                 --trulvl;
 10801086         } else
 10811087                 error("If-less elif");
 10821088 }
 10831089 
 10841090 static usch *
 10851091 svinp(void)
 10861092 {
 10871093         int c;
 10881094         usch *cp = stringbuf;
 10891095 
 10901096         while ((c = input()) && c != '\n')
 10911097                 savch(c);
 10921098         savch('\n');
 10931099         savch(0);
 10941100         BEGIN 0;
 10951101         return cp;
 10961102 }
 10971103 
 10981104 static void
 10991105 cpperror(void)
 11001106 {
 11011107         usch *cp;
 11021108         int c;
 11031109 
 11041110         if (flslvl)
 11051111                 return;
 11061112         c = yylex();
 11071113         if (c != WSPACE && c != '\n')
 11081114                 error("bad error");
 11091115         cp = svinp();
 11101116         if (flslvl)
 11111117                 stringbuf = cp;
 11121118         else
 11131119                 error("%s", cp);
 11141120 }
 11151121 
 11161122 static void
 11171123 undefstmt(void)
 11181124 {
 11191125         struct symtab *np;
 11201126 
 11211127         slow = 1;
 11221128         if (yylex() != WSPACE || yylex() != IDENT)
 11231129                 error("bad undef");
 11241130         if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
 11251131                 np->value = 0;
 11261132         slow = 0;
 11271133         chknl(0);
 11281134 }
 11291135 
 11301136 static void
 11311137 pragmastmt(void)
 11321138 {
 11331139         int c;
 11341140 
 11351141         slow = 1;
 11361142         if (yylex() != WSPACE)
 11371143                 error("bad pragma");
 11381144         if (!flslvl)
 11391145                 putstr((usch *)"#pragma ");
 11401146         do {
 11411147                 c = input();
 11421148                 if (!flslvl)
 11431149                         putch(c);       /* Do arg expansion instead? */
 11441150         } while (c && c != '\n');
 11451151         if (c == '\n')
 11461152                 unch(c);
 11471153         prtline();
 11481154         slow = 0;
 11491155 }
 11501156 
 11511157 static void
 11521158 badop(const char *op)
 11531159 {
 11541160         error("invalid operator in preprocessor expression: %s", op);
 11551161 }
 11561162 
 11571163 int
 11581164 cinput()
 11591165 {
 11601166         return input();
 11611167 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-01 00:01 +0200