|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)unifdef.c 4.4 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * unifdef - remove ifdef'ed lines ! 7: */ ! 8: ! 9: #include <stdio.h> ! 10: #include <ctype.h> ! 11: #define BSS ! 12: FILE *input; ! 13: #ifndef YES ! 14: #define YES 1 ! 15: #define NO 0 ! 16: #endif ! 17: ! 18: char *progname BSS; ! 19: char *filename BSS; ! 20: char text BSS; /* -t option in effect: this is a text file */ ! 21: char lnblank BSS; /* -l option in effect: blank deleted lines */ ! 22: char complement BSS; /* -c option in effect: complement the operation */ ! 23: #define MAXSYMS 100 ! 24: char true[MAXSYMS] BSS; ! 25: char ignore[MAXSYMS] BSS; ! 26: char *sym[MAXSYMS] BSS; ! 27: char insym[MAXSYMS] BSS; ! 28: char nsyms BSS; ! 29: char incomment BSS; ! 30: #define QUOTE1 0 ! 31: #define QUOTE2 1 ! 32: char inquote[2] BSS; ! 33: int exitstat BSS; ! 34: char *skipcomment (); ! 35: char *skipquote (); ! 36: ! 37: main (argc, argv) ! 38: int argc; ! 39: char **argv; ! 40: { ! 41: char **curarg; ! 42: register char *cp; ! 43: register char *cp1; ! 44: char ignorethis; ! 45: ! 46: progname = argv[0][0] ? argv[0] : "unifdef"; ! 47: ! 48: for (curarg = &argv[1]; --argc > 0; curarg++) { ! 49: if (*(cp1 = cp = *curarg) != '-') ! 50: break; ! 51: if (*++cp1 == 'i') { ! 52: ignorethis = YES; ! 53: cp1++; ! 54: } ! 55: else ! 56: ignorethis = NO; ! 57: if ( ( *cp1 == 'D' ! 58: || *cp1 == 'U' ! 59: ) ! 60: && cp1[1] != '\0' ! 61: ) { ! 62: if (nsyms >= MAXSYMS) { ! 63: prname (); ! 64: fprintf (stderr, "too many symbols.\n"); ! 65: exit (2); ! 66: } ! 67: ignore[nsyms] = ignorethis; ! 68: true[nsyms] = *cp1 == 'D' ? YES : NO; ! 69: sym[nsyms++] = &cp1[1]; ! 70: } ! 71: else if (ignorethis) ! 72: goto unrec; ! 73: else if (strcmp (&cp[1], "t") == 0) ! 74: text = YES; ! 75: else if (strcmp (&cp[1], "l") == 0) ! 76: lnblank = YES; ! 77: else if (strcmp (&cp[1], "c") == 0) ! 78: complement = YES; ! 79: else { ! 80: unrec: ! 81: prname (); ! 82: fprintf (stderr, "unrecognized option: %s\n", cp); ! 83: goto usage; ! 84: } ! 85: } ! 86: if (nsyms == 0) { ! 87: usage: ! 88: fprintf (stderr, "\ ! 89: Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-idsym] [-iusym]]... [file]\n\ ! 90: At least one arg from [-D -U -id -iu] is required\n", progname); ! 91: exit (2); ! 92: } ! 93: ! 94: if (argc > 1) { ! 95: prname (); ! 96: fprintf (stderr, "can only do one file.\n"); ! 97: } ! 98: else if (argc == 1) { ! 99: filename = *curarg; ! 100: if ((input = fopen (filename, "r")) != NULL) { ! 101: pfile(); ! 102: fclose (input); ! 103: } ! 104: else { ! 105: prname (); ! 106: perror(*curarg); ! 107: } ! 108: } ! 109: else { ! 110: filename = "[stdin]"; ! 111: input = stdin; ! 112: pfile(); ! 113: } ! 114: ! 115: fflush (stdout); ! 116: exit (exitstat); ! 117: } ! 118: ! 119: /* types of input lines: */ ! 120: #define PLAIN 0 /* ordinary line */ ! 121: #define TRUE 1 /* a true #ifdef of a symbol known to us */ ! 122: #define FALSE 2 /* a false #ifdef of a symbol known to us */ ! 123: #define OTHER 3 /* an #ifdef of a symbol not known to us */ ! 124: #define ELSE 4 /* #else */ ! 125: #define ENDIF 5 /* #endif */ ! 126: #define LEOF 6 /* end of file */ ! 127: ! 128: char reject BSS; /* 0 or 1: pass thru; 1 or 2: ignore comments */ ! 129: int linenum BSS; /* current line number */ ! 130: int stqcline BSS; /* start of current coment or quote */ ! 131: char *errs[] = { ! 132: #define NO_ERR 0 ! 133: "", ! 134: #define END_ERR 1 ! 135: "", ! 136: #define ELSE_ERR 2 ! 137: "Inappropriate else", ! 138: #define ENDIF_ERR 3 ! 139: "Inappropriate endif", ! 140: #define IEOF_ERR 4 ! 141: "Premature EOF in ifdef", ! 142: #define CEOF_ERR 5 ! 143: "Premature EOF in comment", ! 144: #define Q1EOF_ERR 6 ! 145: "Premature EOF in quoted character", ! 146: #define Q2EOF_ERR 7 ! 147: "Premature EOF in quoted string" ! 148: }; ! 149: ! 150: pfile () ! 151: { ! 152: reject = 0; ! 153: doif (-1, NO, reject, 0); ! 154: return; ! 155: } ! 156: ! 157: doif (thissym, inif, prevreject, depth) ! 158: register int thissym; /* index of the symbol who was last ifdef'ed */ ! 159: int inif; /* YES or NO we are inside an ifdef */ ! 160: int prevreject; /* previous value of reject */ ! 161: int depth; /* depth of ifdef's */ ! 162: { ! 163: register int lineval; ! 164: register int thisreject; ! 165: int doret; /* tmp return valud]e of doif */ ! 166: int cursym; /* index of the symbol returned by checkline */ ! 167: int stline; /* line number when called this time */ ! 168: ! 169: stline = linenum; ! 170: for (;;) { ! 171: switch (lineval = checkline (&cursym)) { ! 172: case PLAIN: ! 173: flushline (YES); ! 174: break; ! 175: ! 176: case TRUE: ! 177: case FALSE: ! 178: thisreject = reject; ! 179: if (lineval == TRUE) ! 180: insym[cursym] = 1; ! 181: else { ! 182: if (reject < 2) ! 183: reject = ignore[cursym] ? 1 : 2; ! 184: insym[cursym] = -1; ! 185: } ! 186: if (ignore[cursym]) ! 187: flushline (YES); ! 188: else { ! 189: exitstat = 1; ! 190: flushline (NO); ! 191: } ! 192: if ((doret = doif (cursym, YES, thisreject, depth + 1)) != NO_ERR) ! 193: return error (doret, stline, depth); ! 194: break; ! 195: ! 196: case OTHER: ! 197: flushline (YES); ! 198: if ((doret = doif (-1, YES, reject, depth + 1)) != NO_ERR) ! 199: return error (doret, stline, depth); ! 200: break; ! 201: ! 202: case ELSE: ! 203: if (inif != 1) ! 204: return error (ELSE_ERR, linenum, depth); ! 205: inif = 2; ! 206: if (thissym >= 0) { ! 207: if ((insym[thissym] = -insym[thissym]) < 0) ! 208: reject = ignore[thissym] ? 1 : 2; ! 209: else ! 210: reject = prevreject; ! 211: if (!ignore[thissym]) { ! 212: flushline (NO); ! 213: break; ! 214: } ! 215: } ! 216: flushline (YES); ! 217: break; ! 218: ! 219: case ENDIF: ! 220: if (inif == 0) ! 221: return error (ENDIF_ERR, linenum, depth); ! 222: if (thissym >= 0) { ! 223: insym[thissym] = 0; ! 224: reject = prevreject; ! 225: if (!ignore[thissym]) { ! 226: flushline (NO); ! 227: return NO_ERR; ! 228: } ! 229: } ! 230: flushline (YES); ! 231: return NO_ERR; ! 232: ! 233: case LEOF: { ! 234: int err; ! 235: err = incomment ! 236: ? CEOF_ERR ! 237: : inquote[QUOTE1] ! 238: ? Q1EOF_ERR ! 239: : inquote[QUOTE2] ! 240: ? Q2EOF_ERR ! 241: : NO_ERR; ! 242: if (inif) { ! 243: if (err != NO_ERR) ! 244: error (err, stqcline, depth); ! 245: return error (IEOF_ERR, stline, depth); ! 246: } ! 247: else if (err != NO_ERR) ! 248: return error (err, stqcline, depth); ! 249: else ! 250: return NO_ERR; ! 251: } ! 252: } ! 253: } ! 254: } ! 255: ! 256: #define endsym(c) (!isalpha (c) && !isdigit (c) && c != '_') ! 257: ! 258: #define MAXLINE 256 ! 259: char tline[MAXLINE] BSS; ! 260: ! 261: checkline (cursym) ! 262: int *cursym; ! 263: { ! 264: register char *cp; ! 265: register char *symp; ! 266: register char chr; ! 267: char *scp; ! 268: int retval; ! 269: int symind; ! 270: # define KWSIZE 8 ! 271: char keyword[KWSIZE]; ! 272: ! 273: linenum++; ! 274: if (getlin (tline, sizeof tline, input, NO) == EOF) ! 275: return LEOF; ! 276: ! 277: retval = PLAIN; ! 278: if ( *(cp = tline) != '#' ! 279: || incomment ! 280: || inquote[QUOTE1] ! 281: || inquote[QUOTE2] ! 282: ) ! 283: goto eol; ! 284: ! 285: cp = skipcomment (++cp); ! 286: symp = keyword; ! 287: while (!endsym (*cp)) { ! 288: *symp = *cp++; ! 289: if (++symp >= &keyword[KWSIZE]) ! 290: goto eol; ! 291: } ! 292: *symp = '\0'; ! 293: ! 294: if (strcmp (keyword, "ifdef") == 0) { ! 295: retval = YES; ! 296: goto ifdef; ! 297: } ! 298: else if (strcmp (keyword, "ifndef") == 0) { ! 299: retval = NO; ! 300: ifdef: ! 301: scp = cp = skipcomment (++cp); ! 302: if (incomment) { ! 303: retval = PLAIN; ! 304: goto eol; ! 305: } ! 306: for (symind = 0; ; ) { ! 307: if (insym[symind] == 0) { ! 308: for ( symp = sym[symind], cp = scp ! 309: ; *symp && *cp == *symp ! 310: ; cp++, symp++ ! 311: ) ! 312: {} ! 313: chr = *cp; ! 314: if (*symp == '\0' && endsym (chr)) { ! 315: *cursym = symind; ! 316: retval = (retval ^ true[symind]) ? FALSE : TRUE; ! 317: break; ! 318: } ! 319: } ! 320: if (++symind >= nsyms) { ! 321: retval = OTHER; ! 322: break; ! 323: } ! 324: } ! 325: } ! 326: else if (strcmp (keyword, "if") == 0) ! 327: retval = OTHER; ! 328: else if (strcmp (keyword, "else") == 0) ! 329: retval = ELSE; ! 330: else if (strcmp (keyword, "endif") == 0) ! 331: retval = ENDIF; ! 332: ! 333: eol: ! 334: if (!text && !reject) ! 335: for (; *cp; ) { ! 336: if (incomment) ! 337: cp = skipcomment (cp); ! 338: else if (inquote[QUOTE1]) ! 339: cp = skipquote (cp, QUOTE1); ! 340: else if (inquote[QUOTE2]) ! 341: cp = skipquote (cp, QUOTE2); ! 342: else if (*cp == '/' && cp[1] == '*') ! 343: cp = skipcomment (cp); ! 344: else if (*cp == '\'') ! 345: cp = skipquote (cp, QUOTE1); ! 346: else if (*cp == '"') ! 347: cp = skipquote (cp, QUOTE2); ! 348: else ! 349: cp++; ! 350: } ! 351: return retval; ! 352: } ! 353: ! 354: /* Skip over comments and stop at the next charaacter ! 355: /* position that is not whitespace. ! 356: /**/ ! 357: char * ! 358: skipcomment (cp) ! 359: register char *cp; ! 360: { ! 361: if (incomment) ! 362: goto inside; ! 363: for (;; cp++) { ! 364: while (*cp == ' ' || *cp == '\t') ! 365: cp++; ! 366: if (text) ! 367: return cp; ! 368: if ( cp[0] != '/' ! 369: || cp[1] != '*' ! 370: ) ! 371: return cp; ! 372: cp += 2; ! 373: if (!incomment) { ! 374: incomment = YES; ! 375: stqcline = linenum; ! 376: } ! 377: inside: ! 378: for (;;) { ! 379: for (; *cp != '*'; cp++) ! 380: if (*cp == '\0') ! 381: return cp; ! 382: if (*++cp == '/') ! 383: break; ! 384: } ! 385: incomment = NO; ! 386: } ! 387: } ! 388: ! 389: /* Skip over a quoted string or character and stop at the next charaacter ! 390: /* position that is not whitespace. ! 391: /**/ ! 392: char * ! 393: skipquote (cp, type) ! 394: register char *cp; ! 395: register int type; ! 396: { ! 397: register char qchar; ! 398: ! 399: qchar = type == QUOTE1 ? '\'' : '"'; ! 400: ! 401: if (inquote[type]) ! 402: goto inside; ! 403: for (;; cp++) { ! 404: if (*cp != qchar) ! 405: return cp; ! 406: cp++; ! 407: if (!inquote[type]) { ! 408: inquote[type] = YES; ! 409: stqcline = linenum; ! 410: } ! 411: inside: ! 412: for (; ; cp++) { ! 413: if (*cp == qchar) ! 414: break; ! 415: if ( *cp == '\0' ! 416: || *cp == '\\' ! 417: && *++cp == '\0' ! 418: ) ! 419: return cp; ! 420: } ! 421: inquote[type] = NO; ! 422: } ! 423: } ! 424: ! 425: /* ! 426: /* special getlin - treats form-feed as an end-of-line ! 427: /* and expands tabs if asked for ! 428: /* ! 429: /**/ ! 430: getlin (line, maxline, inp, expandtabs) ! 431: register char *line; ! 432: int maxline; ! 433: FILE *inp; ! 434: int expandtabs; ! 435: { ! 436: int tmp; ! 437: register int num; ! 438: register int chr; ! 439: #ifdef FFSPECIAL ! 440: static char havechar = NO; /* have leftover char from last time */ ! 441: static char svchar BSS; ! 442: #endif ! 443: ! 444: num = 0; ! 445: #ifdef FFSPECIAL ! 446: if (havechar) { ! 447: havechar = NO; ! 448: chr = svchar; ! 449: goto ent; ! 450: } ! 451: #endif ! 452: while (num + 8 < maxline) { /* leave room for tab */ ! 453: chr = getc (inp); ! 454: if (isprint (chr)) { ! 455: #ifdef FFSPECIAL ! 456: ent: ! 457: #endif ! 458: *line++ = chr; ! 459: num++; ! 460: } ! 461: else ! 462: switch (chr) { ! 463: case EOF: ! 464: return EOF; ! 465: ! 466: case '\t': ! 467: if (expandtabs) { ! 468: num += tmp = 8 - (num & 7); ! 469: do ! 470: *line++ = ' '; ! 471: while (--tmp); ! 472: break; ! 473: } ! 474: default: ! 475: *line++ = chr; ! 476: num++; ! 477: break; ! 478: ! 479: case '\n': ! 480: *line = '\n'; ! 481: num++; ! 482: goto end; ! 483: ! 484: #ifdef FFSPECIAL ! 485: case '\f': ! 486: if (++num == 1) ! 487: *line = '\f'; ! 488: else { ! 489: *line = '\n'; ! 490: havechar = YES; ! 491: svchar = chr; ! 492: } ! 493: goto end; ! 494: #endif ! 495: } ! 496: } ! 497: end: ! 498: *++line = '\0'; ! 499: return num; ! 500: } ! 501: ! 502: flushline (keep) ! 503: { ! 504: if ((keep && reject < 2) ^ complement) ! 505: putlin (tline, stdout); ! 506: else if (lnblank) ! 507: putlin ("\n", stdout); ! 508: return; ! 509: } ! 510: ! 511: /* ! 512: /* putlin - for tools ! 513: /* ! 514: /**/ ! 515: putlin (line, fio) ! 516: register char *line; ! 517: register FILE *fio; ! 518: { ! 519: register char chr; ! 520: ! 521: while (chr = *line++) ! 522: putc (chr, fio); ! 523: return; ! 524: } ! 525: ! 526: prname () ! 527: { ! 528: fprintf (stderr, "%s: ", progname); ! 529: return; ! 530: } ! 531: ! 532: ! 533: error (err, line, depth) ! 534: { ! 535: if (err == END_ERR) ! 536: return err; ! 537: ! 538: prname (); ! 539: ! 540: #ifndef TESTING ! 541: fprintf (stderr, "Error in %s line %d: %s.\n", ! 542: filename, line, errs[err]); ! 543: #endif ! 544: ! 545: #ifdef TESTING ! 546: fprintf (stderr, "Error in %s line %d: %s. ", ! 547: filename, line, errs[err]); ! 548: fprintf (stderr, "ifdef depth: %d\n", depth); ! 549: #endif ! 550: ! 551: exitstat = 2; ! 552: return depth > 1 ? IEOF_ERR : END_ERR; ! 553: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.