Annotation of 3BSD/cmd/deroff.c, revision 1.1

1.1     ! root        1: char *xxxvers = "\nDeroff Version 1.02    24 July 1978\n";
        !             2: 
        !             3: 
        !             4: #include <stdio.h>
        !             5: 
        !             6: /* Deroff command -- strip troff, eqn, and Tbl sequences from
        !             7: a file.  Has one flag argument, -w, to cause output one word per line
        !             8: rather than in the original format.
        !             9: Deroff follows .so and .nx commands, removes contents of macro
        !            10: definitions, equations (both .EQ ... .EN and $...$),
        !            11: Tbl command sequences, and Troff backslash constructions.
        !            12: 
        !            13: All input is through the C macro; the most recently read character is in c.
        !            14: */
        !            15: 
        !            16: #define C ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
        !            17: #define C1 ( (c=getc(infile)) == EOF ? eof() :  c)
        !            18: #define SKIP while(C != '\n') 
        !            19: 
        !            20: #define YES 1
        !            21: #define NO 0
        !            22: 
        !            23: #define NOCHAR -2
        !            24: #define SPECIAL 0
        !            25: #define APOS 1
        !            26: #define DIGIT 2
        !            27: #define LETTER 3
        !            28: 
        !            29: int wordflag = NO;
        !            30: int inmacro = NO;
        !            31: int intable = NO;
        !            32: 
        !            33: char chars[128];  /* SPECIAL, APOS, DIGIT, or LETTER */
        !            34: 
        !            35: char line[BUFSIZ];
        !            36: char *lp;
        !            37: 
        !            38: int c;
        !            39: int ldelim     = NOCHAR;
        !            40: int rdelim     = NOCHAR;
        !            41: 
        !            42: 
        !            43: int argc;
        !            44: char **argv;
        !            45: 
        !            46: char fname[50];
        !            47: FILE *files[15];
        !            48: FILE **filesp;
        !            49: FILE *infile;
        !            50: 
        !            51: char *calloc();
        !            52: 
        !            53: 
        !            54: 
        !            55: main(ac, av)
        !            56: int ac;
        !            57: char **av;
        !            58: {
        !            59: register int i;
        !            60: register char *p;
        !            61: static char onechar[2] = "X";
        !            62: FILE *opn();
        !            63: 
        !            64: argc = ac - 1;
        !            65: argv = av + 1;
        !            66: 
        !            67: while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0') 
        !            68:        {
        !            69:        for(p=argv[0]+1; *p; ++p) switch(*p)
        !            70:                {
        !            71:                case 'w':
        !            72:                        wordflag = YES;
        !            73:                        break;
        !            74:                default:
        !            75:                        onechar[0] = *p;
        !            76:                        fatal("Invalid flag %s\n", onechar);
        !            77:                }
        !            78:        --argc;
        !            79:        ++argv;
        !            80:        }
        !            81: 
        !            82: if(argc == 0)
        !            83:        infile = stdin;
        !            84: else   {
        !            85:        infile = opn(argv[0]);
        !            86:        --argc;
        !            87:        ++argv;
        !            88:        }
        !            89: 
        !            90: files[0] = infile;
        !            91: filesp = &files[0];
        !            92: 
        !            93: for(i='a'; i<='z' ; ++i)
        !            94:        chars[i] = LETTER;
        !            95: for(i='A'; i<='Z'; ++i)
        !            96:        chars[i] = LETTER;
        !            97: for(i='0'; i<='9'; ++i)
        !            98:        chars[i] = DIGIT;
        !            99: chars['\''] = APOS;
        !           100: chars['&'] = APOS;
        !           101: 
        !           102: work();
        !           103: }
        !           104: 
        !           105: 
        !           106: 
        !           107: skeqn()
        !           108: {
        !           109: while((c = getc(infile)) != rdelim)
        !           110:        if(c == EOF)
        !           111:                c = eof();
        !           112:        else if(c == '"')
        !           113:                while( (c = getc(infile)) != '"')
        !           114:                        if(c == EOF)
        !           115:                                c = eof();
        !           116:                        else if(c == '\\')
        !           117:                                if((c = getc(infile)) == EOF)
        !           118:                                        c = eof();
        !           119: return(C);
        !           120: }
        !           121: 
        !           122: 
        !           123: FILE *opn(p)
        !           124: register char *p;
        !           125: {
        !           126: FILE *fd;
        !           127: 
        !           128: if(p[0]=='-' && p[1]=='\0')
        !           129:        fd = stdin;
        !           130: else if( (fd = fopen(p, "r")) == NULL)
        !           131:        fatal("Cannot open file %s\n", p);
        !           132: 
        !           133: return(fd);
        !           134: }
        !           135: 
        !           136: 
        !           137: 
        !           138: eof()
        !           139: {
        !           140: if(infile != stdin)
        !           141:        fclose(infile);
        !           142: if(filesp > files)
        !           143:        infile = *--filesp;
        !           144: else if(argc > 0)
        !           145:        {
        !           146:        infile = opn(argv[0]);
        !           147:        --argc;
        !           148:        ++argv;
        !           149:        }
        !           150: else
        !           151:        exit(0);
        !           152: 
        !           153: return(C);
        !           154: }
        !           155: 
        !           156: 
        !           157: 
        !           158: getfname()
        !           159: {
        !           160: register char *p;
        !           161: struct chain { struct chain *nextp; char *datap; } *chainblock;
        !           162: register struct chain *q;
        !           163: static struct chain *namechain = NULL;
        !           164: char *copys();
        !           165: 
        !           166: while(C == ' ') ;
        !           167: 
        !           168: for(p = fname ; (*p=c)!= '\n' && c!=' ' && c!='\t' && c!='\\' ; ++p)
        !           169:        C;
        !           170: *p = '\0';
        !           171: while(c != '\n')
        !           172:        C;
        !           173: 
        !           174: /* see if this name has already been used */
        !           175: 
        !           176: for(q = namechain ; q; q = q->nextp)
        !           177:        if( ! strcmp(fname, q->datap))
        !           178:                {
        !           179:                fname[0] = '\0';
        !           180:                return;
        !           181:                }
        !           182: 
        !           183: q = (struct chain *) calloc(1, sizeof(*chainblock));
        !           184: q->nextp = namechain;
        !           185: q->datap = copys(fname);
        !           186: namechain = q;
        !           187: }
        !           188: 
        !           189: 
        !           190: 
        !           191: 
        !           192: fatal(s,p)
        !           193: char *s, *p;
        !           194: {
        !           195: fprintf(stderr, "Deroff: ");
        !           196: fprintf(stderr, s, p);
        !           197: exit(1);
        !           198: }
        !           199: 
        !           200: work()
        !           201: {
        !           202: 
        !           203: for( ;; )
        !           204:        {
        !           205:        if(C == '.'  ||  c == '\'')
        !           206:                comline();
        !           207:        else
        !           208:                regline(NO);
        !           209:        }
        !           210: }
        !           211: 
        !           212: 
        !           213: 
        !           214: 
        !           215: regline(macline)
        !           216: int macline;
        !           217: {
        !           218: line[0] = c;
        !           219: lp = line;
        !           220: for( ; ; )
        !           221:        {
        !           222:        if(c == '\\')
        !           223:                {
        !           224:                *lp = ' ';
        !           225:                backsl();
        !           226:                }
        !           227:        if(c == '\n') break;
        !           228:        if(intable && c=='T')
        !           229:                {
        !           230:                *++lp = C;
        !           231:                if(c=='{' || c=='}')
        !           232:                        {
        !           233:                        lp[-1] = ' ';
        !           234:                        *lp = C;
        !           235:                        }
        !           236:                }
        !           237:        else    *++lp = C;
        !           238:        }
        !           239: 
        !           240: *lp = '\0';
        !           241: 
        !           242: if(line[0] != '\0')
        !           243:        if(wordflag)
        !           244:                putwords(macline);
        !           245:        else if(macline)
        !           246:                putmac(line);
        !           247:        else
        !           248:                puts(line);
        !           249: }
        !           250: 
        !           251: 
        !           252: 
        !           253: 
        !           254: putmac(s)
        !           255: register char *s;
        !           256: {
        !           257: register char *t;
        !           258: 
        !           259: while(*s)
        !           260:        {
        !           261:        while(*s==' ' || *s=='\t')
        !           262:                putchar(*s++);
        !           263:        for(t = s ; *t!=' ' && *t!='\t' && *t!='\0' ; ++t)
        !           264:                ;
        !           265:        if(t>s+2 && chars[ s[0] ]==LETTER && chars[ s[1] ]==LETTER)
        !           266:                while(s < t)
        !           267:                        putchar(*s++);
        !           268:        else
        !           269:                s = t;
        !           270:        }
        !           271: putchar('\n');
        !           272: }
        !           273: 
        !           274: 
        !           275: 
        !           276: putwords(macline)      /* break into words for -w option */
        !           277: int macline;
        !           278: {
        !           279: register char *p, *p1;
        !           280: int i, nlet;
        !           281: 
        !           282: 
        !           283: for(p1 = line ; ;)
        !           284:        {
        !           285:        /* skip initial specials ampersands and apostrophes */
        !           286:        while( chars[*p1] < DIGIT)
        !           287:                if(*p1++ == '\0') return;
        !           288:        nlet = 0;
        !           289:        for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p)
        !           290:                if(i == LETTER) ++nlet;
        !           291: 
        !           292:        if( (!macline && nlet>1)   /* MDM definition of word */
        !           293:           || (macline && nlet>2 && chars[ p1[0] ]==LETTER && chars[ p1[1] ]==LETTER) )
        !           294:                {
        !           295:                /* delete trailing ampersands and apostrophes */
        !           296:                while(p[-1]=='\'' || p[-1]=='&')
        !           297:                         --p;
        !           298:                while(p1 < p) putchar(*p1++);
        !           299:                putchar('\n');
        !           300:                }
        !           301:        else
        !           302:                p1 = p;
        !           303:        }
        !           304: }
        !           305: 
        !           306: 
        !           307: 
        !           308: comline()
        !           309: {
        !           310: register int c1, c2;
        !           311: 
        !           312: while(C==' ' || c=='\t')
        !           313:        ;
        !           314: if( (c1=c) == '\n')
        !           315:        return;
        !           316: if(c1 == '.')
        !           317:        {
        !           318:        inmacro = NO;
        !           319:        SKIP;
        !           320:        return;
        !           321:        }
        !           322: if( (c2=C) == '\n')
        !           323:        return;
        !           324: 
        !           325: if(c1=='E' && c2=='Q' && filesp==files)
        !           326:        eqn();
        !           327: else if(c1=='T' && (c2=='S' || c2=='C' || c2=='&') && filesp==files)
        !           328:        tbl();
        !           329: else if(c1=='T' && c2=='E')
        !           330:        intable = NO;
        !           331: else if(!inmacro && c1=='d' && c2=='e')
        !           332:        macro();
        !           333: else if(!inmacro && c1=='i' && c2=='g')
        !           334:        macro();
        !           335: else if(!inmacro && c1=='a' && c2 == 'm')
        !           336:        macro();
        !           337: else if(c1=='s' && c2=='o')
        !           338:        {
        !           339:        getfname();
        !           340:        if( fname[0] )
        !           341:                infile = *++filesp = opn( fname );
        !           342:        }
        !           343: else if(c1=='n' && c2=='x')
        !           344:        {
        !           345:        getfname();
        !           346:        if(fname[0] == '\0') exit(0);
        !           347:        if(infile != stdin)
        !           348:                fclose(infile);
        !           349:        infile = *filesp = opn(fname);
        !           350:        }
        !           351: else if(c1=='h' && c2=='w')
        !           352:        { SKIP; }
        !           353: else
        !           354:        {
        !           355:        ++inmacro;
        !           356:        regline(YES);
        !           357:        --inmacro;
        !           358:        }
        !           359: }
        !           360: 
        !           361: 
        !           362: 
        !           363: macro()
        !           364: {
        !           365: /*
        !           366: do { SKIP; }
        !           367:        while(C!='.' || C!='.');        /* look for  .EN */
        !           368: SKIP;
        !           369: inmacro = YES;
        !           370: }
        !           371: 
        !           372: 
        !           373: 
        !           374: 
        !           375: tbl()
        !           376: {
        !           377: while(C != '.');
        !           378: SKIP;
        !           379: intable = YES;
        !           380: }
        !           381: 
        !           382: eqn()
        !           383: {
        !           384: register int c1, c2;
        !           385: 
        !           386: SKIP;
        !           387: 
        !           388: for( ;;)
        !           389:        {
        !           390:        if(C == '.'  || c == '\'')
        !           391:                {
        !           392:                while(C==' ' || c=='\t')
        !           393:                        ;
        !           394:                if(c=='E' && C=='N')
        !           395:                        {
        !           396:                        SKIP;
        !           397:                        return;
        !           398:                        }
        !           399:                }
        !           400:        else if(c == 'd')       /* look for delim */
        !           401:                {
        !           402:                if(C=='e' && C=='l')
        !           403:                    if( C=='i' && C=='m')
        !           404:                        {
        !           405:                        while(C1 == ' ');
        !           406:                        if((c1=c)=='\n' || (c2=C1)=='\n'
        !           407:                            || (c1=='o' && c2=='f' && C1=='f') )
        !           408:                                {
        !           409:                                ldelim = NOCHAR;
        !           410:                                rdelim = NOCHAR;
        !           411:                                }
        !           412:                        else    {
        !           413:                                ldelim = c1;
        !           414:                                rdelim = c2;
        !           415:                                }
        !           416:                        }
        !           417:                }
        !           418: 
        !           419:        if(c != '\n')  SKIP;
        !           420:        }
        !           421: }
        !           422: 
        !           423: 
        !           424: 
        !           425: backsl()       /* skip over a complete backslash construction */
        !           426: {
        !           427: int bdelim;
        !           428: 
        !           429: sw:  switch(C)
        !           430:        {
        !           431:        case '"':
        !           432:                SKIP;
        !           433:                return;
        !           434:        case 's':
        !           435:                if(C == '\\') backsl();
        !           436:                else    {
        !           437:                        while(C>='0' && c<='9') ;
        !           438:                        ungetc(c,infile);
        !           439:                        c = '0';
        !           440:                        }
        !           441:                --lp;
        !           442:                return;
        !           443: 
        !           444:        case 'f':
        !           445:        case 'n':
        !           446:        case '*':
        !           447:                if(C != '(')
        !           448:                        return;
        !           449: 
        !           450:        case '(':
        !           451:                if(C != '\n') C;
        !           452:                return;
        !           453: 
        !           454:        case '$':
        !           455:                C;      /* discard argument number */
        !           456:                return;
        !           457: 
        !           458:        case 'b':
        !           459:        case 'x':
        !           460:        case 'v':
        !           461:        case 'h':
        !           462:        case 'w':
        !           463:        case 'o':
        !           464:        case 'l':
        !           465:        case 'L':
        !           466:                if( (bdelim=C) == '\n')
        !           467:                        return;
        !           468:                while(C!='\n' && c!=bdelim)
        !           469:                        if(c == '\\') backsl();
        !           470:                return;
        !           471: 
        !           472:        case '\\':
        !           473:                if(inmacro)
        !           474:                        goto sw;
        !           475:        default:
        !           476:                return;
        !           477:        }
        !           478: }
        !           479: 
        !           480: 
        !           481: 
        !           482: 
        !           483: char *copys(s)
        !           484: register char *s;
        !           485: {
        !           486: register char *t, *t0;
        !           487: 
        !           488: if( (t0 = t = calloc( strlen(s)+1, sizeof(*t) ) ) == NULL)
        !           489:        fatal("Cannot allocate memory", (char *) NULL);
        !           490: 
        !           491: while( *t++ = *s++ )
        !           492:        ;
        !           493: return(t0);
        !           494: }

unix.superglobalmegacorp.com

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