# 2.11BSD#431 - /usr/src/ucb/unifdef.c

##### Functions

    checkline         X
    doif              X
    error             X
    flushline         X
    getlin            X
    main              X
    pfile             X
    prname            X
    putlin            X
    skipcomment       X
    skipquote         X

##### Variables

    BSS               X
    complement        X
    errs              X
    exitstat          X
    filename          X
    ignore            X
    incomment         X
    inquote           X
    insym             X
    linenum           X
    lnblank           X
    nsyms             X
    progname          X
    reject            X
    stqcline          X
    sym               X
    text              X
    tline             X
    true              X

##### Macros

    BSS               X
    CEOF_ERR          X
    ELSE              X
    ELSE_ERR          X
    ENDIF             X
    ENDIF_ERR         X
    END_ERR           X
    FALSE             X
    IEOF_ERR          X
    KWSIZE            X
    LEOF              X
    MAXLINE           X
    MAXSYMS           X
    NO                X
    NO_ERR            X
    OTHER             X
    PLAIN             X
    Q1EOF_ERR         X
    Q2EOF_ERR         X
    QUOTE1            X
    QUOTE2            X
    TRUE              X
    YES               X
    endsym            X

       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: }

#### Defined functions

checkline defined in line 261; used 1 times

- in line 171

doif defined in line 157; used 3 times

- in line 153, 192, 198

error defined in line 533; used 8 times

- in line 193, 199-204(2), 221, 244-248(3)
- in /usr/src/ucb/rsh.c line 34

flushline defined in line 502; used 8 times

- in line 173, 187-190(2), 197, 212-216(2), 226-230(2)

getlin defined in line 430; used 1 times

- in line 274

main defined in line 37; never used
pfile defined in line 150; used 2 times

- in line 101, 112

prname defined in line 526; used 5 times

- in line 63, 81, 95, 105, 538

putlin defined in line 515; used 2 times

- in line 505-507(2)

skipcomment defined in line 357; used 5 times

- in line 34, 285, 301, 337, 343

skipquote defined in line 392; used 5 times

- in line 35, 339-347(4)

#### Defined variables

BSS defined in line 259; never used
complement defined in line 22; used 2 times

- in line 78, 504

errs defined in line 131; used 2 times

- in line 542-547(2)

exitstat defined in line 33; used 3 times

- in line 116, 189, 551

filename defined in line 19; used 5 times

- in line 99-100(2), 110, 542-547(2)

ignore defined in line 25; used 6 times

- in line 67, 183-186(2), 208-211(2), 225

incomment defined in line 29; used 8 times

- in line 235, 279, 302, 336, 361, 373-374(2), 385

inquote defined in line 32; used 10 times

- in line 237-239(2), 280-281(2), 338-340(2), 401, 407-408(2), 421

insym defined in line 27; used 6 times

- in line 180-184(2), 207(2), 223, 307

linenum defined in line 129; used 6 times

- in line 169, 204, 221, 273, 375, 409

lnblank defined in line 21; used 2 times

- in line 76, 506

nsyms defined in line 28; used 6 times

- in line 62-69(4), 86, 320

progname defined in line 18; used 3 times

- in line 46, 90, 528

reject defined in line 128; used 11 times

- in line 152-153(2), 178-183(3), 198, 208-210(2), 224, 334, 504

sccsid defined in line 2; never used
stqcline defined in line 130; used 4 times

- in line 244-248(2), 375, 409

sym defined in line 26; used 2 times

- in line 69, 308

text defined in line 20; used 3 times

- in line 74, 334, 366

tline defined in line 259; used 4 times

- in line 274-278(3), 505

true defined in line 24; used 2 times

- in line 68, 316

#### Defined macros

BSS defined in line 11; used 1 times

- in line 441

CEOF_ERR defined in line 142; used 1 times

- in line 236

ELSE defined in line 124; used 1 times

- in line 329

ELSE_ERR defined in line 136; used 1 times

- in line 204

ENDIF defined in line 125; used 1 times

- in line 331

ENDIF_ERR defined in line 138; used 1 times

- in line 221

END_ERR defined in line 134; used 2 times

- in line 535, 552

FALSE defined in line 122; used 1 times

- in line 316

IEOF_ERR defined in line 140; used 2 times

- in line 245, 552

KWSIZE defined in line 270; used 2 times

- in line 271, 289

LEOF defined in line 126; used 1 times

- in line 275

MAXLINE defined in line 258; used 1 times

- in line 259

MAXSYMS defined in line 23; used 5 times

- in line 24-27(4), 62

NO defined in line 15; used 12 times

- in line 56, 68, 153, 190, 212, 226, 274, 299, 385, 421, 440, 447

NO_ERR defined in line 132; used 8 times

- in line 192, 198, 227-231(2), 241-250(4)

OTHER defined in line 123; used 2 times

- in line 321, 327

PLAIN defined in line 120; used 2 times

- in line 277, 303

Q1EOF_ERR defined in line 144; used 1 times

- in line 238

Q2EOF_ERR defined in line 146; used 1 times

- in line 240

QUOTE1 defined in line 30; used 6 times

- in line 237, 280, 338-339(2), 345, 399

QUOTE2 defined in line 31; used 5 times

- in line 239, 281, 340-341(2), 347

TRUE defined in line 121; used 2 times

- in line 179, 316

YES defined in line 14; used 17 times

- in line 13, 52, 68, 74-78(3), 173, 187-198(4), 216, 230, 295, 374, 408, 490

endsym defined in line 256; used 2 times

- in line 287, 314

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1600 |