Annotation of 42BSD/usr.bin/deroff.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)deroff.c   4.4     (Berkeley)      83/04/29";
        !             3: #endif not lint
        !             4: 
        !             5: #include <stdio.h>
        !             6: 
        !             7: /*
        !             8:  *     Deroff command -- strip troff, eqn, and Tbl sequences from
        !             9:  *     a file.  Has two flags argument, -w, to cause output one word per line
        !            10:  *     rather than in the original format.
        !            11:  *     -mm (or -ms) causes the corresponding macro's to be interpreted
        !            12:  *     so that just sentences are output
        !            13:  *     -ml  also gets rid of lists.
        !            14:  *     Deroff follows .so and .nx commands, removes contents of macro
        !            15:  *     definitions, equations (both .EQ ... .EN and $...$),
        !            16:  *     Tbl command sequences, and Troff backslash constructions.
        !            17:  *
        !            18:  *     All input is through the Cget macro;
        !            19:  *     the most recently read character is in c.
        !            20:  *
        !            21:  *     Modified by Robert Henry to process -me and -man macros.
        !            22:  */
        !            23: 
        !            24: #define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
        !            25: #define C1get ( (c=getc(infile)) == EOF ? eof() :  c)
        !            26: 
        !            27: #ifdef DEBUG
        !            28: #  define C    _C()
        !            29: #  define C1   _C1()
        !            30: #else not DEBUG
        !            31: #  define C    Cget
        !            32: #  define C1   C1get
        !            33: #endif not DEBUG
        !            34: 
        !            35: #define SKIP while(C != '\n') 
        !            36: #define SKIP_TO_COM SKIP; SKIP; pc=c; while(C != '.' || pc != '\n' || C > 'Z')pc=c
        !            37: 
        !            38: #define        YES 1
        !            39: #define        NO 0
        !            40: #define        MS 0    /* -ms */
        !            41: #define        MM 1    /* -mm */
        !            42: #define        ME 2    /* -me */
        !            43: #define        MA 3    /* -man */
        !            44: 
        !            45: #ifdef DEBUG
        !            46: char *mactab[] = {"-ms", "-mm", "-me", "-ma"};
        !            47: #endif DEBUG
        !            48: 
        !            49: #define        ONE 1
        !            50: #define        TWO 2
        !            51: 
        !            52: #define NOCHAR -2
        !            53: #define SPECIAL 0
        !            54: #define APOS 1
        !            55: #define PUNCT 2
        !            56: #define DIGIT 3
        !            57: #define LETTER 4
        !            58: 
        !            59: int    wordflag;
        !            60: int    msflag;         /* processing a source written using a mac package */
        !            61: int    mac;            /* which package */
        !            62: int    disp;
        !            63: int    parag;
        !            64: int    inmacro;
        !            65: int    intable;
        !            66: int    keepblock;      /* keep blocks of text; normally false when msflag */
        !            67: 
        !            68: char chars[128];  /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
        !            69: 
        !            70: char line[512];
        !            71: char *lp;
        !            72: 
        !            73: int c;
        !            74: int pc;
        !            75: int ldelim;
        !            76: int rdelim;
        !            77: 
        !            78: 
        !            79: int argc;
        !            80: char **argv;
        !            81: 
        !            82: char fname[50];
        !            83: FILE *files[15];
        !            84: FILE **filesp;
        !            85: FILE *infile;
        !            86: FILE   *opn();
        !            87: /*
        !            88:  *     Flags for matching conditions other than
        !            89:  *     the macro name
        !            90:  */
        !            91: #define        NONE            0
        !            92: #define        FNEST           1               /* no nested files */
        !            93: #define        NOMAC           2               /* no macro */
        !            94: #define        MAC             3               /* macro */
        !            95: #define        PARAG           4               /* in a paragraph */
        !            96: #define        MSF             5               /* msflag is on */
        !            97: #define        NBLK            6               /* set if no blocks to be kept */
        !            98: 
        !            99: /*
        !           100:  *     Return codes from macro minions, determine where to jump,
        !           101:  *     how to repeat/reprocess text
        !           102:  */
        !           103: #define        COMX            1               /* goto comx */
        !           104: #define        COM             2               /* goto com */
        !           105: 
        !           106: main(ac, av)
        !           107: int ac;
        !           108: char **av;
        !           109: {
        !           110:        register int i;
        !           111:        int     errflg = 0;
        !           112:        register        optchar;
        !           113:        FILE *opn();
        !           114:        int     kflag = NO;
        !           115:        char    *p;
        !           116: 
        !           117:        wordflag = NO;
        !           118:        msflag = NO;
        !           119:        mac = ME;
        !           120:        disp = NO;
        !           121:        parag = NO;
        !           122:        inmacro = NO;
        !           123:        intable = NO;
        !           124:        ldelim  = NOCHAR;
        !           125:        rdelim  = NOCHAR;
        !           126:        keepblock = YES;
        !           127: 
        !           128:        for(argc = ac - 1, argv = av + 1;
        !           129:            (   (argc > 0)
        !           130:             && (argv[0][0] == '-')
        !           131:             && (argv[0][1] != '\0') );
        !           132:            --argc, ++argv
        !           133:        ){
        !           134:                for(p = argv[0]+1; *p; ++p) {
        !           135:                        switch(*p) {
        !           136:                        case 'p':
        !           137:                                parag=YES;
        !           138:                                break;
        !           139:                        case 'k':
        !           140:                                kflag = YES;
        !           141:                                break;
        !           142:                        case 'w':
        !           143:                                wordflag = YES;
        !           144:                                kflag = YES;
        !           145:                                break;
        !           146:                        case 'm':
        !           147:                                msflag = YES;
        !           148:                                keepblock = NO;
        !           149:                                switch(p[1]){
        !           150:                                case 'm':       mac = MM; p++; break;
        !           151:                                case 's':       mac = MS; p++; break;
        !           152:                                case 'e':       mac = ME; p++; break;
        !           153:                                case 'a':       mac = MA; p++; break;
        !           154:                                case 'l':       disp = YES; p++; break;
        !           155:                                default:        errflg++; break;
        !           156:                                }
        !           157:                                break;
        !           158:                        default:
        !           159:                                errflg++;
        !           160:                        }
        !           161:                }
        !           162:        }
        !           163: 
        !           164:        if (kflag)
        !           165:                keepblock = YES;
        !           166:        if (errflg)
        !           167:                fatal("usage: deroff [ -w ] [ -k] [ -m (a e m s l) ] [ file ] ... \n",
        !           168:                        (char *) NULL);
        !           169: 
        !           170: #ifdef DEBUG
        !           171:        printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n",
        !           172:                msflag, mactab[mac], keepblock, disp);
        !           173: #endif DEBUG
        !           174:        if (argc == 0){
        !           175:                infile = stdin;
        !           176:        } else {
        !           177:                infile = opn(argv[0]);
        !           178:                --argc;
        !           179:                ++argv;
        !           180:        }
        !           181: 
        !           182: 
        !           183:        files[0] = infile;
        !           184:        filesp = &files[0];
        !           185: 
        !           186:        for(i='a'; i<='z' ; ++i)
        !           187:                chars[i] = LETTER;
        !           188:        for(i='A'; i<='Z'; ++i)
        !           189:                chars[i] = LETTER;
        !           190:        for(i='0'; i<='9'; ++i)
        !           191:                chars[i] = DIGIT;
        !           192:        chars['\''] = APOS;
        !           193:        chars['&'] = APOS;
        !           194:        chars['.'] = PUNCT;
        !           195:        chars[','] = PUNCT;
        !           196:        chars[';'] = PUNCT;
        !           197:        chars['?'] = PUNCT;
        !           198:        chars[':'] = PUNCT;
        !           199:        work();
        !           200: }
        !           201: char *calloc();
        !           202: 
        !           203: skeqn()
        !           204: {
        !           205:        while((c = getc(infile)) != rdelim)
        !           206:                if(c == EOF)
        !           207:                        c = eof();
        !           208:                else if(c == '"')
        !           209:                        while( (c = getc(infile)) != '"')
        !           210:                                if(c == EOF)
        !           211:                                        c = eof();
        !           212:                                else if(c == '\\')
        !           213:                                        if((c = getc(infile)) == EOF)
        !           214:                                                c = eof();
        !           215:        if(msflag)return(c='x');
        !           216:        return(c = ' ');
        !           217: }
        !           218: 
        !           219: FILE *opn(p)
        !           220: register char *p;
        !           221: {
        !           222:        FILE *fd;
        !           223: 
        !           224:        if( (fd = fopen(p, "r")) == NULL) {
        !           225:                fprintf(stderr, "Deroff: ");
        !           226:                perror(p);
        !           227:                exit(1);
        !           228:        }
        !           229: 
        !           230:        return(fd);
        !           231: }
        !           232: 
        !           233: eof()
        !           234: {
        !           235:        if(infile != stdin)
        !           236:                fclose(infile);
        !           237:        if(filesp > files)
        !           238:                infile = *--filesp;
        !           239:        else if (argc > 0) {
        !           240:                infile = opn(argv[0]);
        !           241:                --argc;
        !           242:                ++argv;
        !           243:        } else
        !           244:                exit(0);
        !           245:        return(C);
        !           246: }
        !           247: 
        !           248: getfname()
        !           249: {
        !           250:        register char *p;
        !           251:        struct chain { 
        !           252:                struct chain *nextp; 
        !           253:                char *datap; 
        !           254:        } *chainblock;
        !           255:        register struct chain *q;
        !           256:        static struct chain *namechain  = NULL;
        !           257:        char *copys();
        !           258: 
        !           259:        while(C == ' ') ;
        !           260: 
        !           261:        for(p = fname ; (*p=c)!= '\n' && c!=' ' && c!='\t' && c!='\\' ; ++p)
        !           262:                C;
        !           263:        *p = '\0';
        !           264:        while(c != '\n')
        !           265:                C;
        !           266: 
        !           267:        /* see if this name has already been used */
        !           268: 
        !           269:        for(q = namechain ; q; q = q->nextp)
        !           270:                if( ! strcmp(fname, q->datap))
        !           271:                {
        !           272:                        fname[0] = '\0';
        !           273:                        return;
        !           274:                }
        !           275: 
        !           276:        q = (struct chain *) calloc(1, sizeof(*chainblock));
        !           277:        q->nextp = namechain;
        !           278:        q->datap = copys(fname);
        !           279:        namechain = q;
        !           280: }
        !           281: 
        !           282: fatal(s,p)
        !           283: char *s, *p;
        !           284: {
        !           285:        fprintf(stderr, "Deroff: ");
        !           286:        fprintf(stderr, s, p);
        !           287:        exit(1);
        !           288: }
        !           289: 
        !           290: /*ARGSUSED*/
        !           291: textline(str, const)
        !           292:        char    *str;
        !           293:        int     const;
        !           294: {
        !           295:        if (wordflag) {
        !           296:                msputwords(0);
        !           297:                return;
        !           298:        }
        !           299:        puts(str);
        !           300: }
        !           301: 
        !           302: work()
        !           303: {
        !           304:        for( ;; )
        !           305:        {
        !           306:                C;
        !           307: #ifdef FULLDEBUG
        !           308:                printf("Starting work with `%c'\n", c);
        !           309: #endif FULLDEBUG
        !           310:                if(c == '.'  ||  c == '\'')
        !           311:                        comline();
        !           312:                else
        !           313:                        regline(textline, TWO);
        !           314:        }
        !           315: }
        !           316: 
        !           317: regline(pfunc, const)
        !           318:        int     (*pfunc)();
        !           319:        int     const;
        !           320: {
        !           321:        line[0] = c;
        !           322:        lp = line;
        !           323:        for( ; ; )
        !           324:        {
        !           325:                if(c == '\\') {
        !           326:                        *lp = ' ';
        !           327:                        backsl();
        !           328:                }
        !           329:                if(c == '\n')
        !           330:                        break;
        !           331:                if(intable && c=='T') {
        !           332:                        *++lp = C;
        !           333:                        if(c=='{' || c=='}') {
        !           334:                                lp[-1] = ' ';
        !           335:                                *lp = C;
        !           336:                        }
        !           337:                } else {
        !           338:                        *++lp = C;
        !           339:                }
        !           340:        }
        !           341: 
        !           342:        *lp = '\0';
        !           343: 
        !           344:        if(line[0] != '\0')
        !           345:                (*pfunc)(line, const);
        !           346: }
        !           347: 
        !           348: macro()
        !           349: {
        !           350:        if(msflag){
        !           351:                do { 
        !           352:                        SKIP; 
        !           353:                }               while(C!='.' || C!='.' || C=='.');      /* look for  .. */
        !           354:                if(c != '\n')SKIP;
        !           355:                return;
        !           356:        }
        !           357:        SKIP;
        !           358:        inmacro = YES;
        !           359: }
        !           360: 
        !           361: tbl()
        !           362: {
        !           363:        while(C != '.');
        !           364:        SKIP;
        !           365:        intable = YES;
        !           366: }
        !           367: stbl()
        !           368: {
        !           369:        while(C != '.');
        !           370:        SKIP_TO_COM;
        !           371:        if(c != 'T' || C != 'E'){
        !           372:                SKIP;
        !           373:                pc=c;
        !           374:                while(C != '.' || pc != '\n' || C != 'T' || C != 'E')pc=c;
        !           375:        }
        !           376: }
        !           377: 
        !           378: eqn()
        !           379: {
        !           380:        register int c1, c2;
        !           381:        register int dflg;
        !           382:        char last;
        !           383: 
        !           384:        last=0;
        !           385:        dflg = 1;
        !           386:        SKIP;
        !           387: 
        !           388:        for( ;;)
        !           389:        {
        !           390:                if(C1 == '.'  || c == '\'')
        !           391:                {
        !           392:                        while(C1==' ' || c=='\t')
        !           393:                                ;
        !           394:                        if(c=='E' && C1=='N')
        !           395:                        {
        !           396:                                SKIP;
        !           397:                                if(msflag && dflg){
        !           398:                                        putchar('x');
        !           399:                                        putchar(' ');
        !           400:                                        if(last){
        !           401:                                                putchar(last); 
        !           402:                                                putchar('\n'); 
        !           403:                                        }
        !           404:                                }
        !           405:                                return;
        !           406:                        }
        !           407:                }
        !           408:                else if(c == 'd')       /* look for delim */
        !           409:                {
        !           410:                        if(C1=='e' && C1=='l')
        !           411:                                if( C1=='i' && C1=='m')
        !           412:                                {
        !           413:                                        while(C1 == ' ');
        !           414:                                        if((c1=c)=='\n' || (c2=C1)=='\n'
        !           415:                                            || (c1=='o' && c2=='f' && C1=='f') )
        !           416:                                        {
        !           417:                                                ldelim = NOCHAR;
        !           418:                                                rdelim = NOCHAR;
        !           419:                                        }
        !           420:                                        else    {
        !           421:                                                ldelim = c1;
        !           422:                                                rdelim = c2;
        !           423:                                        }
        !           424:                                }
        !           425:                        dflg = 0;
        !           426:                }
        !           427: 
        !           428:                if(c != '\n') while(C1 != '\n'){ 
        !           429:                        if(chars[c] == PUNCT)last = c;
        !           430:                        else if(c != ' ')last = 0;
        !           431:                }
        !           432:        }
        !           433: }
        !           434: 
        !           435: backsl()       /* skip over a complete backslash construction */
        !           436: {
        !           437:        int bdelim;
        !           438: 
        !           439: sw:  
        !           440:        switch(C)
        !           441:        {
        !           442:        case '"':
        !           443:                SKIP;
        !           444:                return;
        !           445:        case 's':
        !           446:                if(C == '\\') backsl();
        !           447:                else    {
        !           448:                        while(C>='0' && c<='9') ;
        !           449:                        ungetc(c,infile);
        !           450:                        c = '0';
        !           451:                }
        !           452:                --lp;
        !           453:                return;
        !           454: 
        !           455:        case 'f':
        !           456:        case 'n':
        !           457:        case '*':
        !           458:                if(C != '(')
        !           459:                        return;
        !           460: 
        !           461:        case '(':
        !           462:                if(msflag){
        !           463:                        if(C == 'e'){
        !           464:                                if(C == 'm'){
        !           465:                                        *lp = '-';
        !           466:                                        return;
        !           467:                                }
        !           468:                        }
        !           469:                        else if(c != '\n')C;
        !           470:                        return;
        !           471:                }
        !           472:                if(C != '\n') C;
        !           473:                return;
        !           474: 
        !           475:        case '$':
        !           476:                C;      /* discard argument number */
        !           477:                return;
        !           478: 
        !           479:        case 'b':
        !           480:        case 'x':
        !           481:        case 'v':
        !           482:        case 'h':
        !           483:        case 'w':
        !           484:        case 'o':
        !           485:        case 'l':
        !           486:        case 'L':
        !           487:                if( (bdelim=C) == '\n')
        !           488:                        return;
        !           489:                while(C!='\n' && c!=bdelim)
        !           490:                        if(c == '\\') backsl();
        !           491:                return;
        !           492: 
        !           493:        case '\\':
        !           494:                if(inmacro)
        !           495:                        goto sw;
        !           496:        default:
        !           497:                return;
        !           498:        }
        !           499: }
        !           500: 
        !           501: char *copys(s)
        !           502: register char *s;
        !           503: {
        !           504:        register char *t, *t0;
        !           505: 
        !           506:        if( (t0 = t = calloc( (unsigned)(strlen(s)+1), sizeof(*t) ) ) == NULL)
        !           507:                fatal("Cannot allocate memory", (char *) NULL);
        !           508: 
        !           509:        while( *t++ = *s++ )
        !           510:                ;
        !           511:        return(t0);
        !           512: }
        !           513: 
        !           514: sce()
        !           515: {
        !           516:        register char *ap;
        !           517:        register int n, i;
        !           518:        char a[10];
        !           519:        for(ap=a;C != '\n';ap++){
        !           520:                *ap = c;
        !           521:                if(ap == &a[9]){
        !           522:                        SKIP;
        !           523:                        ap=a;
        !           524:                        break;
        !           525:                }
        !           526:        }
        !           527:        if(ap != a)n = atoi(a);
        !           528:        else n = 1;
        !           529:        for(i=0;i<n;){
        !           530:                if(C == '.'){
        !           531:                        if(C == 'c'){
        !           532:                                if(C == 'e'){
        !           533:                                        while(C == ' ');
        !           534:                                        if(c == '0'){
        !           535:                                                SKIP;
        !           536:                                                break;
        !           537:                                        }
        !           538:                                        else SKIP;
        !           539:                                }
        !           540:                                else SKIP;
        !           541:                        }
        !           542:                        else if(c == 'P' || C == 'P'){
        !           543:                                if(c != '\n')SKIP;
        !           544:                                break;
        !           545:                        }
        !           546:                        else if(c != '\n')SKIP;
        !           547:                }
        !           548:                else {
        !           549:                        SKIP;
        !           550:                        i++;
        !           551:                }
        !           552:        }
        !           553: }
        !           554: 
        !           555: refer(c1)
        !           556: {
        !           557:        register int c2;
        !           558:        if(c1 != '\n')
        !           559:                SKIP;
        !           560:        while(1){
        !           561:                if(C != '.')
        !           562:                        SKIP;
        !           563:                else {
        !           564:                        if(C != ']')
        !           565:                                SKIP;
        !           566:                        else {
        !           567:                                while(C != '\n')
        !           568:                                        c2=c;
        !           569:                                if(chars[c2] == PUNCT)putchar(c2);
        !           570:                                return;
        !           571:                        }
        !           572:                }
        !           573:        }
        !           574: }
        !           575: 
        !           576: inpic()
        !           577: {
        !           578:        register int c1;
        !           579:        register char *p1;
        !           580:        SKIP;
        !           581:        p1 = line;
        !           582:        c = '\n';
        !           583:        while(1){
        !           584:                c1 = c;
        !           585:                if(C == '.' && c1 == '\n'){
        !           586:                        if(C != 'P'){
        !           587:                                if(c == '\n')continue;
        !           588:                                else { SKIP; c='\n'; continue;}
        !           589:                        }
        !           590:                        if(C != 'E'){
        !           591:                                if(c == '\n')continue;
        !           592:                                else { SKIP; c='\n';continue; }
        !           593:                        }
        !           594:                        SKIP;
        !           595:                        return;
        !           596:                }
        !           597:                else if(c == '\"'){
        !           598:                        while(C != '\"'){
        !           599:                                if(c == '\\'){
        !           600:                                        if(C == '\"')continue;
        !           601:                                        ungetc(c,infile);
        !           602:                                        backsl();
        !           603:                                }
        !           604:                                else *p1++ = c;
        !           605:                        }
        !           606:                        *p1++ = ' ';
        !           607:                }
        !           608:                else if(c == '\n' && p1 != line){
        !           609:                        *p1 = '\0';
        !           610:                        if(wordflag)msputwords(NO);
        !           611:                        else {
        !           612:                                puts(line);
        !           613:                                putchar('\n');
        !           614:                        }
        !           615:                        p1 = line;
        !           616:                }
        !           617:        }
        !           618: }
        !           619: 
        !           620: #ifdef DEBUG
        !           621: _C1()
        !           622: {
        !           623:        return(C1get);
        !           624: }
        !           625: _C()
        !           626: {
        !           627:        return(Cget);
        !           628: }
        !           629: #endif DEBUG
        !           630: 
        !           631: /*
        !           632:  *     Macro processing
        !           633:  *
        !           634:  *     Macro table definitions
        !           635:  */
        !           636: #define        reg     register
        !           637: typedef        int pacmac;             /* compressed macro name */
        !           638: int    argconcat = 0;          /* concat arguments together (-me only) */
        !           639: 
        !           640: #define        tomac(c1, c2)           ((((c1) & 0xFF) << 8) | ((c2) & 0xFF))
        !           641: #define        frommac(src, c1, c2)    (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF))
        !           642: 
        !           643: struct mactab{
        !           644:        int     condition;
        !           645:        pacmac  macname;
        !           646:        int     (*func)();
        !           647: };
        !           648: struct mactab  troffmactab[];
        !           649: struct mactab  ppmactab[];
        !           650: struct mactab  msmactab[];
        !           651: struct mactab  mmmactab[];
        !           652: struct mactab  memactab[];
        !           653: struct mactab  manmactab[];
        !           654: /*
        !           655:  *     macro table initialization
        !           656:  */
        !           657: #define        M(cond, c1, c2, func) {cond, tomac(c1, c2), func}
        !           658: 
        !           659: /*
        !           660:  *     Put out a macro line, using ms and mm conventions.
        !           661:  */
        !           662: msputmac(s, const)
        !           663:        register char *s;
        !           664:        int     const;
        !           665: {
        !           666:        register char *t;
        !           667:        register found;
        !           668:        int last;
        !           669:        found = 0;
        !           670: 
        !           671:        if (wordflag) {
        !           672:                msputwords(YES);
        !           673:                return;
        !           674:        }
        !           675:        while(*s)
        !           676:        {
        !           677:                while(*s==' ' || *s=='\t')
        !           678:                        putchar(*s++);
        !           679:                for(t = s ; *t!=' ' && *t!='\t' && *t!='\0' ; ++t)
        !           680:                        ;
        !           681:                if(*s == '\"')s++;
        !           682:                if(t>s+const && chars[ s[0] ]==LETTER && chars[ s[1] ]==LETTER){
        !           683:                        while(s < t)
        !           684:                                if(*s == '\"')s++;
        !           685:                                else
        !           686:                                        putchar(*s++);
        !           687:                        last = *(t-1);
        !           688:                        found++;
        !           689:                }
        !           690:                else if(found && chars[ s[0] ] == PUNCT && s[1] == '\0')
        !           691:                        putchar(*s++);
        !           692:                else{
        !           693:                        last = *(t-1);
        !           694:                        s = t;
        !           695:                }
        !           696:        }
        !           697:        putchar('\n');
        !           698:        if(msflag && chars[last] == PUNCT){
        !           699:                putchar(last);
        !           700:                putchar('\n');
        !           701:        }
        !           702: }
        !           703: /*
        !           704:  *     put out words (for the -w option) with ms and mm conventions
        !           705:  */
        !           706: msputwords(macline)    
        !           707:        int macline;    /* is this is a macro line */
        !           708: {
        !           709:        register char *p, *p1;
        !           710:        int i, nlet;
        !           711: 
        !           712:        for(p1 = line ; ;) {
        !           713:                /*
        !           714:                 *      skip initial specials ampersands and apostrophes
        !           715:                 */
        !           716:                while( chars[*p1] < DIGIT)
        !           717:                        if(*p1++ == '\0') return;
        !           718:                nlet = 0;
        !           719:                for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p)
        !           720:                        if(i == LETTER) ++nlet;
        !           721: 
        !           722:                if (   (macline && nlet > 1)
        !           723:                    || (!macline && nlet > 2 
        !           724:                                 && chars[p1[0]] == LETTER
        !           725:                                 && chars[p1[1]] == LETTER) )
        !           726:                {
        !           727:                        /*
        !           728:                         *      delete trailing ampersands and apostrophes
        !           729:                         */
        !           730:                        while(  (p[-1]=='\'')
        !           731:                             || (p[-1]=='&')
        !           732:                             || (chars[p[-1]] == PUNCT) ){
        !           733:                                --p;
        !           734:                        }
        !           735:                        while(p1 < p)
        !           736:                                putchar(*p1++);
        !           737:                        putchar('\n');
        !           738:                } else {
        !           739:                        p1 = p;
        !           740:                }
        !           741:        }
        !           742: }
        !           743: /*
        !           744:  *     put out a macro using the me conventions
        !           745:  */
        !           746: #define SKIPBLANK(cp)  while(*cp == ' ' || *cp == '\t') { cp++; }
        !           747: #define SKIPNONBLANK(cp) while(*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }
        !           748: 
        !           749: meputmac(cp, const)
        !           750:        reg     char    *cp;
        !           751:                int     const;
        !           752: {
        !           753:        reg     char    *np;
        !           754:                int     found;
        !           755:                int     argno;
        !           756:                int     last;
        !           757:                int     inquote;
        !           758: 
        !           759:        if (wordflag) {
        !           760:                meputwords(YES);
        !           761:                return;
        !           762:        }
        !           763:        for (argno = 0; *cp; argno++){
        !           764:                SKIPBLANK(cp);
        !           765:                inquote = (*cp == '"');
        !           766:                if (inquote)
        !           767:                        cp++;
        !           768:                for (np = cp; *np; np++){
        !           769:                        switch(*np){
        !           770:                        case '\n':
        !           771:                        case '\0':      break;
        !           772:                        case '\t':
        !           773:                        case ' ':       if (inquote) {
        !           774:                                                continue;
        !           775:                                        } else {
        !           776:                                                goto endarg;
        !           777:                                        }
        !           778:                        case '"':       if(inquote && np[1] == '"'){
        !           779:                                                strcpy(np, np + 1);
        !           780:                                                np++;
        !           781:                                                continue;
        !           782:                                        } else {
        !           783:                                                *np = ' ';      /* bye bye " */
        !           784:                                                goto endarg;
        !           785:                                        }
        !           786:                        default:        continue;
        !           787:                        }
        !           788:                }
        !           789:                endarg: ;
        !           790:                /*
        !           791:                 *      cp points at the first char in the arg
        !           792:                 *      np points one beyond the last char in the arg
        !           793:                 */
        !           794:                if ((argconcat == 0) || (argconcat != argno)) {
        !           795:                        putchar(' ');
        !           796:                }
        !           797: #ifdef FULLDEBUG
        !           798:                {
        !           799:                        char    *p;
        !           800:                        printf("[%d,%d: ", argno, np - cp);
        !           801:                        for (p = cp; p < np; p++) {
        !           802:                                putchar(*p);
        !           803:                        }
        !           804:                        printf("]");
        !           805:                }
        !           806: #endif FULLDEBUG
        !           807:                /*
        !           808:                 *      Determine if the argument merits being printed
        !           809:                 *
        !           810:                 *      const is the cut off point below which something
        !           811:                 *      is not a word.
        !           812:                 */
        !           813:                if (   ( (np - cp) > const)
        !           814:                    && (    inquote
        !           815:                         || (chars[cp[0]] == LETTER)) ){
        !           816:                        for (cp = cp; cp < np; cp++){
        !           817:                                putchar(*cp);
        !           818:                        }
        !           819:                        last = np[-1];
        !           820:                        found++;
        !           821:                } else
        !           822:                if(found && (np - cp == 1) && chars[*cp] == PUNCT){
        !           823:                        putchar(*cp);
        !           824:                } else {
        !           825:                        last = np[-1];
        !           826:                }
        !           827:                cp = np;
        !           828:        }
        !           829:        if(msflag && chars[last] == PUNCT)
        !           830:                putchar(last);
        !           831:        putchar('\n');
        !           832: }
        !           833: /*
        !           834:  *     put out words (for the -w option) with ms and mm conventions
        !           835:  */
        !           836: meputwords(macline)
        !           837:        int     macline;
        !           838: {
        !           839:        msputwords(macline);
        !           840: }
        !           841: /*
        !           842:  *
        !           843:  *     Skip over a nested set of macros
        !           844:  *
        !           845:  *     Possible arguments to noblock are:
        !           846:  *
        !           847:  *     fi      end of unfilled text
        !           848:  *     PE      pic ending
        !           849:  *     DE      display ending
        !           850:  *
        !           851:  *     for ms and mm only:
        !           852:  *             KE      keep ending
        !           853:  *
        !           854:  *             NE      undocumented match to NS (for mm?)
        !           855:  *             LE      mm only: matches RL or *L (for lists)
        !           856:  *
        !           857:  *     for me:
        !           858:  *             ([lqbzcdf]
        !           859:  */
        !           860: 
        !           861: noblock(a1, a2)
        !           862:        char a1, a2;
        !           863: {
        !           864:        register int c1,c2;
        !           865:        register int eqnf;
        !           866:        int lct;
        !           867:        lct = 0;
        !           868:        eqnf = 1;
        !           869:        SKIP;
        !           870:        while(1){
        !           871:                while(C != '.')
        !           872:                        if(c == '\n')
        !           873:                                continue;
        !           874:                        else
        !           875:                                SKIP;
        !           876:                if((c1=C) == '\n')
        !           877:                        continue;
        !           878:                if((c2=C) == '\n')
        !           879:                        continue;
        !           880:                if(c1==a1 && c2 == a2){
        !           881:                        SKIP;
        !           882:                        if(lct != 0){
        !           883:                                lct--;
        !           884:                                continue;
        !           885:                        }
        !           886:                        if(eqnf)
        !           887:                                putchar('.');
        !           888:                        putchar('\n');
        !           889:                        return;
        !           890:                } else if(a1 == 'L' && c2 == 'L'){
        !           891:                        lct++;
        !           892:                        SKIP;
        !           893:                }
        !           894:                /*
        !           895:                 *      equations (EQ) nested within a display
        !           896:                 */
        !           897:                else if(c1 == 'E' && c2 == 'Q'){
        !           898:                        if (   (mac == ME && a1 == ')')
        !           899:                            || (mac != ME && a1 == 'D') ) {
        !           900:                                eqn(); 
        !           901:                                eqnf=0;
        !           902:                        }
        !           903:                }
        !           904:                /*
        !           905:                 *      turning on filling is done by the paragraphing
        !           906:                 *      macros
        !           907:                 */
        !           908:                else if(a1 == 'f') {    /* .fi */
        !           909:                        if  (  (mac == ME && (c2 == 'h' || c2 == 'p'))
        !           910:                             ||(mac != ME && (c1 == 'P' || c2 == 'P')) ) {
        !           911:                                SKIP;
        !           912:                                return;
        !           913:                        }
        !           914:                } else {
        !           915:                        SKIP;
        !           916:                }
        !           917:        }
        !           918: }
        !           919: 
        !           920: EQ()
        !           921: {
        !           922:        eqn();
        !           923:        return(0);
        !           924: }
        !           925: domacro()
        !           926: {
        !           927:        macro();
        !           928:        return(0);
        !           929: }
        !           930: PS()
        !           931: {
        !           932:        if (!msflag) {
        !           933:                inpic();
        !           934:        } else {
        !           935:                noblock('P', 'E');
        !           936:        }
        !           937:        return(0);
        !           938: }
        !           939: 
        !           940: skip()
        !           941: {
        !           942:        SKIP;
        !           943:        return(0);
        !           944: }
        !           945: 
        !           946: intbl()
        !           947: {
        !           948:        if(msflag){ 
        !           949:                stbl(); 
        !           950:        }
        !           951:        else tbl(); 
        !           952:        return(0);
        !           953: }
        !           954: 
        !           955: outtbl(){ intable = NO; }
        !           956: 
        !           957: so()
        !           958: {
        !           959:        getfname();
        !           960:        if( fname[0] )
        !           961:                infile = *++filesp = opn( fname );
        !           962:        return(0);
        !           963: }
        !           964: nx()
        !           965: {
        !           966:        getfname();
        !           967:        if(fname[0] == '\0') exit(0);
        !           968:        if(infile != stdin)
        !           969:                fclose(infile);
        !           970:        infile = *filesp = opn(fname);
        !           971:        return(0);
        !           972: }
        !           973: skiptocom(){ SKIP_TO_COM; return(COMX); }
        !           974: 
        !           975: PP(c12)
        !           976:        pacmac  c12;
        !           977: {
        !           978:        int     c1, c2;
        !           979:        
        !           980:        frommac(c12, c1, c2);
        !           981:        printf(".%c%c",c1,c2);
        !           982:        while(C != '\n')putchar(c);
        !           983:        putchar('\n');
        !           984:        return(0);
        !           985: }
        !           986: AU()
        !           987: {
        !           988:        if(mac==MM) {
        !           989:                return(0);
        !           990:        } else {
        !           991:                SKIP_TO_COM;
        !           992:                return(COMX);
        !           993:        }
        !           994: }
        !           995: 
        !           996: SH(c12)
        !           997:        pacmac  c12;
        !           998: {
        !           999:        int     c1, c2;
        !          1000:        
        !          1001:        frommac(c12, c1, c2);
        !          1002: 
        !          1003:        if(parag){
        !          1004:                printf(".%c%c",c1,c2);
        !          1005:                while(C != '\n')putchar(c);
        !          1006:                putchar(c);
        !          1007:                putchar('!');
        !          1008:                while(1){
        !          1009:                        while(C != '\n')putchar(c);
        !          1010:                        putchar('\n');
        !          1011:                        if(C == '.')
        !          1012:                                return(COM);
        !          1013:                        putchar('!');
        !          1014:                        putchar(c);
        !          1015:                }
        !          1016:                /*NOTREACHED*/
        !          1017:        } else {
        !          1018:                SKIP_TO_COM;
        !          1019:                return(COMX);
        !          1020:        }
        !          1021: }
        !          1022: 
        !          1023: UX()
        !          1024: {
        !          1025:        if(wordflag)
        !          1026:                printf("UNIX\n");
        !          1027:        else
        !          1028:                printf("UNIX ");
        !          1029:        return(0);
        !          1030: }
        !          1031: 
        !          1032: MMHU(c12)
        !          1033:        pacmac  c12;
        !          1034: {
        !          1035:        int     c1, c2;
        !          1036:        
        !          1037:        frommac(c12, c1, c2);
        !          1038:        if(parag){
        !          1039:                printf(".%c%c",c1,c2);
        !          1040:                while(C != '\n')putchar(c);
        !          1041:                putchar('\n');
        !          1042:        } else {
        !          1043:                SKIP;
        !          1044:        }
        !          1045:        return(0);
        !          1046: }
        !          1047: 
        !          1048: mesnblock(c12)
        !          1049:        pacmac  c12;
        !          1050: {
        !          1051:        int     c1, c2;
        !          1052:        
        !          1053:        frommac(c12, c1, c2);
        !          1054:        noblock(')',c2);
        !          1055:        return(0);
        !          1056: }
        !          1057: mssnblock(c12)
        !          1058:        pacmac  c12;
        !          1059: {
        !          1060:        int     c1, c2;
        !          1061:        
        !          1062:        frommac(c12, c1, c2);
        !          1063:        noblock(c1,'E');
        !          1064:        return(0);
        !          1065: }      
        !          1066: nf()
        !          1067: {
        !          1068:        noblock('f','i');
        !          1069:        return(0);
        !          1070: }
        !          1071: 
        !          1072: ce()
        !          1073: {
        !          1074:        sce();
        !          1075:        return(0);
        !          1076: }
        !          1077: 
        !          1078: meip(c12)
        !          1079:        pacmac  c12;
        !          1080: {
        !          1081:        if(parag)
        !          1082:                mepp(c12);
        !          1083:        else if (wordflag)      /* save the tag */
        !          1084:                regline(meputmac, ONE);
        !          1085:        else {
        !          1086:                SKIP;
        !          1087:        }
        !          1088:        return(0);
        !          1089: }
        !          1090: /*
        !          1091:  *     only called for -me .pp or .sh, when parag is on
        !          1092:  */
        !          1093: mepp(c12)
        !          1094:        pacmac  c12;
        !          1095: {
        !          1096:        PP(c12);                /* eats the line */
        !          1097:        return(0);
        !          1098: }
        !          1099: /* 
        !          1100:  *     Start of a section heading; output the section name if doing words
        !          1101:  */
        !          1102: mesh(c12)
        !          1103:        pacmac  c12;
        !          1104: {
        !          1105:        if (parag)
        !          1106:                mepp(c12);
        !          1107:        else if (wordflag)
        !          1108:                defcomline(c12);
        !          1109:        else {
        !          1110:                SKIP;
        !          1111:        }
        !          1112:        return(0);
        !          1113: }
        !          1114: /*
        !          1115:  *     process a font setting
        !          1116:  */
        !          1117: mefont(c12)
        !          1118:        pacmac  c12;
        !          1119: {
        !          1120:        argconcat = 1;
        !          1121:        defcomline(c12);
        !          1122:        argconcat = 0;
        !          1123:        return(0);
        !          1124: }
        !          1125: manfont(c12)
        !          1126:        pacmac  c12;
        !          1127: {
        !          1128:        return(mefont(c12));
        !          1129: }
        !          1130: manpp(c12)
        !          1131:        pacmac  c12;
        !          1132: {
        !          1133:        return(mepp(c12));
        !          1134: }
        !          1135: 
        !          1136: defcomline(c12)
        !          1137:        pacmac  c12;
        !          1138: {
        !          1139:        int     c1, c2;
        !          1140:        
        !          1141:        frommac(c12, c1, c2);
        !          1142:        if(msflag && mac==MM && c2=='L'){
        !          1143:                if(disp || c1 == 'R') {
        !          1144:                        noblock('L','E');
        !          1145:                } else {
        !          1146:                        SKIP;
        !          1147:                        putchar('.');
        !          1148:                }
        !          1149:        }
        !          1150:        else if(c1=='.' && c2=='.'){
        !          1151:                if(msflag){
        !          1152:                        SKIP;
        !          1153:                        return;
        !          1154:                }
        !          1155:                while(C == '.')
        !          1156:                        /*VOID*/;
        !          1157:        }
        !          1158:        ++inmacro;
        !          1159:        /*
        !          1160:         *      Process the arguments to the macro
        !          1161:         */
        !          1162:        switch(mac){
        !          1163:        default:
        !          1164:        case MM:
        !          1165:        case MS:
        !          1166:                if(c1 <= 'Z' && msflag)
        !          1167:                        regline(msputmac, ONE);
        !          1168:                else
        !          1169:                        regline(msputmac, TWO);
        !          1170:                break;
        !          1171:        case ME:
        !          1172:                regline(meputmac, ONE);
        !          1173:                break;
        !          1174:        }
        !          1175:        --inmacro;
        !          1176: }
        !          1177: 
        !          1178: comline()
        !          1179: {
        !          1180:        reg     int     c1;
        !          1181:        reg     int     c2;
        !          1182:                pacmac  c12;
        !          1183:        reg     int     mid;
        !          1184:                int     lb, ub;
        !          1185:                int     hit;
        !          1186:        static  int     tabsize = 0;
        !          1187:        static  struct  mactab  *mactab = (struct mactab *)0;
        !          1188:        reg     struct  mactab  *mp;
        !          1189: 
        !          1190:        if (mactab == 0){
        !          1191:                 buildtab(&mactab, &tabsize);
        !          1192:        }
        !          1193: com:
        !          1194:        while(C==' ' || c=='\t')
        !          1195:                ;
        !          1196: comx:
        !          1197:        if( (c1=c) == '\n')
        !          1198:                return;
        !          1199:        c2 = C;
        !          1200:        if(c1=='.' && c2 !='.')
        !          1201:                inmacro = NO;
        !          1202:        if(msflag && c1 == '['){
        !          1203:                refer(c2);
        !          1204:                return;
        !          1205:        }
        !          1206:        if(parag && mac==MM && c1 == 'P' && c2 == '\n'){
        !          1207:                printf(".P\n");
        !          1208:                return;
        !          1209:        }
        !          1210:        if(c2 == '\n')
        !          1211:                return;
        !          1212:        /*
        !          1213:         *      Single letter macro
        !          1214:         */
        !          1215:        if (mac == ME && (c2 == ' ' || c2 == '\t') )
        !          1216:                c2 = ' ';
        !          1217:        c12 = tomac(c1, c2);
        !          1218:        /*
        !          1219:         *      binary search through the table of macros
        !          1220:         */
        !          1221:        lb = 0;
        !          1222:        ub = tabsize - 1;
        !          1223:        while(lb <= ub){
        !          1224:                mid = (ub + lb) / 2;
        !          1225:                mp = &mactab[mid];
        !          1226:                if (mp->macname < c12)
        !          1227:                        lb = mid + 1;
        !          1228:                else if (mp->macname > c12)
        !          1229:                        ub = mid - 1;
        !          1230:                else {
        !          1231:                        hit = 1;
        !          1232: #ifdef FULLDEBUG
        !          1233:                        printf("preliminary hit macro %c%c ", c1, c2);
        !          1234: #endif FULLDEBUG
        !          1235:                        switch(mp->condition){
        !          1236:                        case NONE:      hit = YES;                      break;
        !          1237:                        case FNEST:     hit = (filesp == files);        break;
        !          1238:                        case NOMAC:     hit = !inmacro;                 break;
        !          1239:                        case MAC:       hit = inmacro;                  break;
        !          1240:                        case PARAG:     hit = parag;                    break;
        !          1241:                        case NBLK:      hit = !keepblock;               break;
        !          1242:                        default:        hit = 0;
        !          1243:                        }
        !          1244:                        if (hit) {
        !          1245: #ifdef FULLDEBUG
        !          1246:                                printf("MATCH\n");
        !          1247: #endif FULLDEBUG
        !          1248:                                switch( (*(mp->func))(c12) ) {
        !          1249:                                default:        return;
        !          1250:                                case COMX:      goto comx;
        !          1251:                                case COM:       goto com;
        !          1252:                                }
        !          1253:                        }
        !          1254: #ifdef FULLDEBUG
        !          1255:                        printf("FAIL\n");
        !          1256: #endif FULLDEBUG
        !          1257:                        break;
        !          1258:                }
        !          1259:        }
        !          1260:        defcomline(c12);
        !          1261: }
        !          1262: 
        !          1263: int macsort(p1, p2)
        !          1264:        struct  mactab  *p1, *p2;
        !          1265: {
        !          1266:        return(p1->macname - p2->macname);
        !          1267: }
        !          1268: 
        !          1269: int sizetab(mp)
        !          1270:        reg     struct  mactab  *mp;
        !          1271: {
        !          1272:        reg     int     i;
        !          1273:        i = 0;
        !          1274:        if (mp){
        !          1275:                for (; mp->macname; mp++, i++)
        !          1276:                        /*VOID*/ ;
        !          1277:        }
        !          1278:        return(i);
        !          1279: }
        !          1280: 
        !          1281: struct mactab *macfill(dst, src)
        !          1282:        reg     struct  mactab  *dst;
        !          1283:        reg     struct  mactab  *src;
        !          1284: {
        !          1285:        if (src) {
        !          1286:                while(src->macname){
        !          1287:                        *dst++ = *src++;
        !          1288:                }
        !          1289:        }
        !          1290:        return(dst);
        !          1291: }
        !          1292: 
        !          1293: buildtab(r_back, r_size)
        !          1294:        struct  mactab  **r_back;
        !          1295:        int     *r_size;
        !          1296: {
        !          1297:        int     size;
        !          1298: 
        !          1299:        struct  mactab  *p, *p1, *p2;
        !          1300:        struct  mactab  *back;
        !          1301: 
        !          1302:        size = sizetab(troffmactab);
        !          1303:        size += sizetab(ppmactab);
        !          1304:        p1 = p2 = (struct mactab *)0;
        !          1305:        if (msflag){
        !          1306:                switch(mac){
        !          1307:                case ME:        p1 = memactab; break;
        !          1308:                case MM:        p1 = msmactab;
        !          1309:                                p2 = mmmactab; break;
        !          1310: 
        !          1311:                case MS:        p1 = msmactab; break;
        !          1312:                case MA:        p1 = manmactab; break;
        !          1313:                default:        break;
        !          1314:                }
        !          1315:        }
        !          1316:        size += sizetab(p1);
        !          1317:        size += sizetab(p2);
        !          1318:        back = (struct mactab *)calloc(size+2, sizeof(struct mactab));
        !          1319: 
        !          1320:        p = macfill(back, troffmactab);
        !          1321:        p = macfill(p, ppmactab);
        !          1322:        p = macfill(p, p1);
        !          1323:        p = macfill(p, p2);
        !          1324: 
        !          1325:        qsort(back, size, sizeof(struct mactab), macsort);
        !          1326:        *r_size = size;
        !          1327:        *r_back = back;
        !          1328: }
        !          1329: 
        !          1330: /*
        !          1331:  *     troff commands
        !          1332:  */
        !          1333: struct mactab  troffmactab[] = {
        !          1334:        M(NONE,         '\\','"',       skip),  /* comment */
        !          1335:        M(NOMAC,        'd','e',        domacro),       /* define */
        !          1336:        M(NOMAC,        'i','g',        domacro),       /* ignore till .. */
        !          1337:        M(NOMAC,        'a','m',        domacro),       /* append macro */
        !          1338:        M(NBLK,         'n','f',        nf),    /* filled */
        !          1339:        M(NBLK,         'c','e',        ce),    /* centered */
        !          1340: 
        !          1341:        M(NONE,         's','o',        so),    /* source a file */
        !          1342:        M(NONE,         'n','x',        nx),    /* go to next file */
        !          1343: 
        !          1344:        M(NONE,         't','m',        skip),  /* print string on tty */
        !          1345:        M(NONE,         'h','w',        skip),  /* exception hyphen words */
        !          1346:        M(NONE,         0,0,            0)
        !          1347: };
        !          1348: /*
        !          1349:  *     Preprocessor output
        !          1350:  */
        !          1351: struct mactab  ppmactab[] = {
        !          1352:        M(FNEST,        'E','Q',        EQ),    /* equation starting */
        !          1353:        M(FNEST,        'T','S',        intbl), /* table starting */
        !          1354:        M(FNEST,        'T','C',        intbl), /* alternative table? */
        !          1355:        M(FNEST,        'T','&',        intbl), /* table reformatting */
        !          1356:        M(NONE,         'T','E',        outtbl),/* table ending */
        !          1357:        M(NONE,         'P','S',        PS),    /* picture starting */
        !          1358:        M(NONE,         0,0,            0)
        !          1359: };
        !          1360: /*
        !          1361:  *     Particular to ms and mm
        !          1362:  */
        !          1363: struct mactab  msmactab[] = {
        !          1364:        M(NONE,         'T','L',        skiptocom),     /* title follows */
        !          1365:        M(NONE,         'F','S',        skiptocom),     /* start footnote */
        !          1366:        M(NONE,         'O','K',        skiptocom),     /* Other kws */
        !          1367: 
        !          1368:        M(NONE,         'N','R',        skip),  /* undocumented */
        !          1369:        M(NONE,         'N','D',        skip),  /* use supplied date */
        !          1370: 
        !          1371:        M(PARAG,        'P','P',        PP),    /* begin parag */
        !          1372:        M(PARAG,        'I','P',        PP),    /* begin indent parag, tag x */
        !          1373:        M(PARAG,        'L','P',        PP),    /* left blocked parag */
        !          1374: 
        !          1375:        M(NONE,         'A','U',        AU),    /* author */
        !          1376:        M(NONE,         'A','I',        AU),    /* authors institution */
        !          1377: 
        !          1378:        M(NONE,         'S','H',        SH),    /* section heading */
        !          1379:        M(NONE,         'S','N',        SH),    /* undocumented */
        !          1380:        M(NONE,         'U','X',        UX),    /* unix */
        !          1381: 
        !          1382:        M(NBLK,         'D','S',        mssnblock),     /* start display text */
        !          1383:        M(NBLK,         'K','S',        mssnblock),     /* start keep */
        !          1384:        M(NBLK,         'K','F',        mssnblock),     /* start float keep */
        !          1385:        M(NONE,         0,0,            0)
        !          1386: };
        !          1387: 
        !          1388: struct mactab  mmmactab[] = {
        !          1389:        M(NONE,         'H',' ',        MMHU),  /* -mm ? */
        !          1390:        M(NONE,         'H','U',        MMHU),  /* -mm ? */
        !          1391:        M(PARAG,        'P',' ',        PP),    /* paragraph for -mm */
        !          1392:        M(NBLK,         'N','S',        mssnblock),     /* undocumented */
        !          1393:        M(NONE,         0,0,            0)
        !          1394: };
        !          1395: 
        !          1396: struct mactab  memactab[] = {
        !          1397:        M(PARAG,        'p','p',        mepp),
        !          1398:        M(PARAG,        'l','p',        mepp),
        !          1399:        M(PARAG,        'n','p',        mepp),
        !          1400:        M(NONE,         'i','p',        meip),
        !          1401: 
        !          1402:        M(NONE,         's','h',        mesh),
        !          1403:        M(NONE,         'u','h',        mesh),
        !          1404: 
        !          1405:        M(NBLK,         '(','l',        mesnblock),
        !          1406:        M(NBLK,         '(','q',        mesnblock),
        !          1407:        M(NBLK,         '(','b',        mesnblock),
        !          1408:        M(NBLK,         '(','z',        mesnblock),
        !          1409:        M(NBLK,         '(','c',        mesnblock),
        !          1410: 
        !          1411:        M(NBLK,         '(','d',        mesnblock),
        !          1412:        M(NBLK,         '(','f',        mesnblock),
        !          1413:        M(NBLK,         '(','x',        mesnblock),
        !          1414: 
        !          1415:        M(NONE,         'r',' ',        mefont),
        !          1416:        M(NONE,         'i',' ',        mefont),
        !          1417:        M(NONE,         'b',' ',        mefont),
        !          1418:        M(NONE,         'u',' ',        mefont),
        !          1419:        M(NONE,         'q',' ',        mefont),
        !          1420:        M(NONE,         'r','b',        mefont),
        !          1421:        M(NONE,         'b','i',        mefont),
        !          1422:        M(NONE,         'b','x',        mefont),
        !          1423:        M(NONE,         0,0,            0)
        !          1424: };
        !          1425: 
        !          1426: 
        !          1427: struct mactab  manmactab[] = {
        !          1428:        M(PARAG,        'B','I',        manfont),
        !          1429:        M(PARAG,        'B','R',        manfont),
        !          1430:        M(PARAG,        'I','B',        manfont),
        !          1431:        M(PARAG,        'I','R',        manfont),
        !          1432:        M(PARAG,        'R','B',        manfont),
        !          1433:        M(PARAG,        'R','I',        manfont),
        !          1434: 
        !          1435:        M(PARAG,        'P','P',        manpp),
        !          1436:        M(PARAG,        'L','P',        manpp),
        !          1437:        M(PARAG,        'H','P',        manpp),
        !          1438:        M(NONE,         0,0,            0)
        !          1439: };

unix.superglobalmegacorp.com

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