Annotation of 42BSD/ucb/unifdef.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.