Annotation of 43BSD/ucb/ul.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)ul.c       5.1 (Berkeley) 5/31/85";
        !            15: #endif not lint
        !            16: 
        !            17: #include <stdio.h>
        !            18: 
        !            19: #define        IESC    '\033'
        !            20: #define        SO      '\016'
        !            21: #define        SI      '\017'
        !            22: #define        HFWD    '9'
        !            23: #define        HREV    '8'
        !            24: #define        FREV    '7'
        !            25: #define        MAXBUF  512
        !            26: 
        !            27: #define        NORMAL  000
        !            28: #define        ALTSET  001     /* Reverse */
        !            29: #define        SUPERSC 002     /* Dim */
        !            30: #define        SUBSC   004     /* Dim | Ul */
        !            31: #define        UNDERL  010     /* Ul */
        !            32: #define        BOLD    020     /* Bold */
        !            33: 
        !            34: int    must_use_uc, must_overstrike;
        !            35: char   *CURS_UP, *CURS_RIGHT, *CURS_LEFT,
        !            36:        *ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE,
        !            37:        *ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES;
        !            38: 
        !            39: struct CHAR    {
        !            40:        char    c_mode;
        !            41:        char    c_char;
        !            42: } ;
        !            43: 
        !            44: struct CHAR    obuf[MAXBUF];
        !            45: int    col, maxcol;
        !            46: int    mode;
        !            47: int    halfpos;
        !            48: int    upln;
        !            49: int    iflag;
        !            50: 
        !            51: main(argc, argv)
        !            52:        int argc;
        !            53:        char **argv;
        !            54: {
        !            55:        int c;
        !            56:        char *cp, *termtype;
        !            57:        FILE *f;
        !            58:        char termcap[1024];
        !            59:        char *getenv();
        !            60:        extern int optind;
        !            61:        extern char *optarg;
        !            62: 
        !            63:        termtype = getenv("TERM");
        !            64:        if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1)))
        !            65:                termtype = "lpr";
        !            66:        while ((c=getopt(argc, argv, "it:T:")) != EOF)
        !            67:                switch(c) {
        !            68: 
        !            69:                case 't':
        !            70:                case 'T': /* for nroff compatibility */
        !            71:                                termtype = optarg;
        !            72:                        break;
        !            73:                case 'i':
        !            74:                        iflag = 1;
        !            75:                        break;
        !            76: 
        !            77:                default:
        !            78:                        fprintf(stderr,
        !            79:                                "Usage: %s [ -i ] [ -tTerm ] file...\n",
        !            80:                                argv[0]);
        !            81:                        exit(1);
        !            82:                }
        !            83: 
        !            84:        switch(tgetent(termcap, termtype)) {
        !            85: 
        !            86:        case 1:
        !            87:                break;
        !            88: 
        !            89:        default:
        !            90:                fprintf(stderr,"trouble reading termcap");
        !            91:                /* fall through to ... */
        !            92: 
        !            93:        case 0:
        !            94:                /* No such terminal type - assume dumb */
        !            95:                strcpy(termcap, "dumb:os:col#80:cr=^M:sf=^J:am:");
        !            96:                break;
        !            97:        }
        !            98:        initcap();
        !            99:        if (    (tgetflag("os") && ENTER_BOLD==NULL ) ||
        !           100:                (tgetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
        !           101:                        must_overstrike = 1;
        !           102:        initbuf();
        !           103:        if (optind == argc)
        !           104:                filter(stdin);
        !           105:        else for (; optind<argc; optind++) {
        !           106:                f = fopen(argv[optind],"r");
        !           107:                if (f == NULL) {
        !           108:                        perror(argv[optind]);
        !           109:                        exit(1);
        !           110:                } else
        !           111:                        filter(f);
        !           112:        }
        !           113:        exit(0);
        !           114: }
        !           115: 
        !           116: filter(f)
        !           117: FILE *f;
        !           118: {
        !           119:        register c;
        !           120: 
        !           121:        while((c = getc(f)) != EOF) switch(c) {
        !           122: 
        !           123:        case '\b':
        !           124:                if (col > 0)
        !           125:                        col--;
        !           126:                continue;
        !           127: 
        !           128:        case '\t':
        !           129:                col = (col+8) & ~07;
        !           130:                if (col > maxcol)
        !           131:                        maxcol = col;
        !           132:                continue;
        !           133: 
        !           134:        case '\r':
        !           135:                col = 0;
        !           136:                continue;
        !           137: 
        !           138:        case SO:
        !           139:                mode |= ALTSET;
        !           140:                continue;
        !           141: 
        !           142:        case SI:
        !           143:                mode &= ~ALTSET;
        !           144:                continue;
        !           145: 
        !           146:        case IESC:
        !           147:                switch (c = getc(f)) {
        !           148: 
        !           149:                case HREV:
        !           150:                        if (halfpos == 0) {
        !           151:                                mode |= SUPERSC;
        !           152:                                halfpos--;
        !           153:                        } else if (halfpos > 0) {
        !           154:                                mode &= ~SUBSC;
        !           155:                                halfpos--;
        !           156:                        } else {
        !           157:                                halfpos = 0;
        !           158:                                reverse();
        !           159:                        }
        !           160:                        continue;
        !           161: 
        !           162:                case HFWD:
        !           163:                        if (halfpos == 0) {
        !           164:                                mode |= SUBSC;
        !           165:                                halfpos++;
        !           166:                        } else if (halfpos < 0) {
        !           167:                                mode &= ~SUPERSC;
        !           168:                                halfpos++;
        !           169:                        } else {
        !           170:                                halfpos = 0;
        !           171:                                fwd();
        !           172:                        }
        !           173:                        continue;
        !           174: 
        !           175:                case FREV:
        !           176:                        reverse();
        !           177:                        continue;
        !           178: 
        !           179:                default:
        !           180:                        fprintf(stderr,
        !           181:                                "Unknown escape sequence in input: %o, %o\n",
        !           182:                                IESC, c);
        !           183:                        exit(1);
        !           184:                }
        !           185:                continue;
        !           186: 
        !           187:        case '_':
        !           188:                if (obuf[col].c_char)
        !           189:                        obuf[col].c_mode |= UNDERL | mode;
        !           190:                else
        !           191:                        obuf[col].c_char = '_';
        !           192:        case ' ':
        !           193:                col++;
        !           194:                if (col > maxcol)
        !           195:                        maxcol = col;
        !           196:                continue;
        !           197: 
        !           198:        case '\n':
        !           199:                flushln();
        !           200:                continue;
        !           201: 
        !           202:        default:
        !           203:                if (c < ' ')    /* non printing */
        !           204:                        continue;
        !           205:                if (obuf[col].c_char == '\0') {
        !           206:                        obuf[col].c_char = c;
        !           207:                        obuf[col].c_mode = mode;
        !           208:                } else if (obuf[col].c_char == '_') {
        !           209:                        obuf[col].c_char = c;
        !           210:                        obuf[col].c_mode |= UNDERL|mode;
        !           211:                } else if (obuf[col].c_char == c)
        !           212:                        obuf[col].c_mode |= BOLD|mode;
        !           213:                else {
        !           214:                        obuf[col].c_mode = c;
        !           215:                        obuf[col].c_mode = mode;
        !           216:                }
        !           217:                col++;
        !           218:                if (col > maxcol)
        !           219:                        maxcol = col;
        !           220:                continue;
        !           221:        }
        !           222:        if (maxcol)
        !           223:                flushln();
        !           224: }
        !           225: 
        !           226: flushln()
        !           227: {
        !           228:        register lastmode;
        !           229:        register i;
        !           230:        int hadmodes = 0;
        !           231: 
        !           232:        lastmode = NORMAL;
        !           233:        for (i=0; i<maxcol; i++) {
        !           234:                if (obuf[i].c_mode != lastmode) {
        !           235:                        hadmodes++;
        !           236:                        setmode(obuf[i].c_mode);
        !           237:                        lastmode = obuf[i].c_mode;
        !           238:                }
        !           239:                if (obuf[i].c_char == '\0') {
        !           240:                        if (upln) {
        !           241:                                puts(CURS_RIGHT);
        !           242:                        } else
        !           243:                                outc(' ');
        !           244:                } else
        !           245:                        outc(obuf[i].c_char);
        !           246:        }
        !           247:        if (lastmode != NORMAL) {
        !           248:                setmode(0);
        !           249:        }
        !           250:        if (must_overstrike && hadmodes)
        !           251:                overstrike();
        !           252:        putchar('\n');
        !           253:        if (iflag && hadmodes)
        !           254:                iattr();
        !           255:        fflush(stdout);
        !           256:        if (upln)
        !           257:                upln--;
        !           258:        initbuf();
        !           259: }
        !           260: 
        !           261: /*
        !           262:  * For terminals that can overstrike, overstrike underlines and bolds.
        !           263:  * We don't do anything with halfline ups and downs, or Greek.
        !           264:  */
        !           265: overstrike()
        !           266: {
        !           267:        register int i;
        !           268:        char lbuf[256];
        !           269:        register char *cp = lbuf;
        !           270:        int hadbold=0;
        !           271: 
        !           272:        /* Set up overstrike buffer */
        !           273:        for (i=0; i<maxcol; i++)
        !           274:                switch (obuf[i].c_mode) {
        !           275:                case NORMAL:
        !           276:                default:
        !           277:                        *cp++ = ' ';
        !           278:                        break;
        !           279:                case UNDERL:
        !           280:                        *cp++ = '_';
        !           281:                        break;
        !           282:                case BOLD:
        !           283:                        *cp++ = obuf[i].c_char;
        !           284:                        hadbold=1;
        !           285:                        break;
        !           286:                }
        !           287:        putchar('\r');
        !           288:        for (*cp=' '; *cp==' '; cp--)
        !           289:                *cp = 0;
        !           290:        for (cp=lbuf; *cp; cp++)
        !           291:                putchar(*cp);
        !           292:        if (hadbold) {
        !           293:                putchar('\r');
        !           294:                for (cp=lbuf; *cp; cp++)
        !           295:                        putchar(*cp=='_' ? ' ' : *cp);
        !           296:                putchar('\r');
        !           297:                for (cp=lbuf; *cp; cp++)
        !           298:                        putchar(*cp=='_' ? ' ' : *cp);
        !           299:        }
        !           300: }
        !           301: 
        !           302: iattr()
        !           303: {
        !           304:        register int i;
        !           305:        char lbuf[256];
        !           306:        register char *cp = lbuf;
        !           307: 
        !           308:        for (i=0; i<maxcol; i++)
        !           309:                switch (obuf[i].c_mode) {
        !           310:                case NORMAL:    *cp++ = ' '; break;
        !           311:                case ALTSET:    *cp++ = 'g'; break;
        !           312:                case SUPERSC:   *cp++ = '^'; break;
        !           313:                case SUBSC:     *cp++ = 'v'; break;
        !           314:                case UNDERL:    *cp++ = '_'; break;
        !           315:                case BOLD:      *cp++ = '!'; break;
        !           316:                default:        *cp++ = 'X'; break;
        !           317:                }
        !           318:        for (*cp=' '; *cp==' '; cp--)
        !           319:                *cp = 0;
        !           320:        for (cp=lbuf; *cp; cp++)
        !           321:                putchar(*cp);
        !           322:        putchar('\n');
        !           323: }
        !           324: 
        !           325: initbuf()
        !           326: {
        !           327: 
        !           328:        bzero(obuf, sizeof (obuf));             /* depends on NORMAL == 0 */
        !           329:        col = 0;
        !           330:        maxcol = 0;
        !           331:        mode &= ALTSET;
        !           332: }
        !           333: 
        !           334: fwd()
        !           335: {
        !           336:        register oldcol, oldmax;
        !           337: 
        !           338:        oldcol = col;
        !           339:        oldmax = maxcol;
        !           340:        flushln();
        !           341:        col = oldcol;
        !           342:        maxcol = oldmax;
        !           343: }
        !           344: 
        !           345: reverse()
        !           346: {
        !           347:        upln++;
        !           348:        fwd();
        !           349:        puts(CURS_UP);
        !           350:        puts(CURS_UP);
        !           351:        upln++;
        !           352: }
        !           353: 
        !           354: initcap()
        !           355: {
        !           356:        static char tcapbuf[512];
        !           357:        char *termtype;
        !           358:        char *bp = tcapbuf;
        !           359:        char *getenv(), *tgetstr();
        !           360: 
        !           361:        /* This nonsense attempts to work with both old and new termcap */
        !           362:        CURS_UP =               tgetstr("up", &bp);
        !           363:        CURS_RIGHT =            tgetstr("ri", &bp);
        !           364:        if (CURS_RIGHT == NULL)
        !           365:                CURS_RIGHT =    tgetstr("nd", &bp);
        !           366:        CURS_LEFT =             tgetstr("le", &bp);
        !           367:        if (CURS_LEFT == NULL)
        !           368:                CURS_LEFT =     tgetstr("bc", &bp);
        !           369:        if (CURS_LEFT == NULL && tgetflag("bs"))
        !           370:                CURS_LEFT =     "\b";
        !           371: 
        !           372:        ENTER_STANDOUT =        tgetstr("so", &bp);
        !           373:        EXIT_STANDOUT =         tgetstr("se", &bp);
        !           374:        ENTER_UNDERLINE =       tgetstr("us", &bp);
        !           375:        EXIT_UNDERLINE =        tgetstr("ue", &bp);
        !           376:        ENTER_DIM =             tgetstr("mh", &bp);
        !           377:        ENTER_BOLD =            tgetstr("md", &bp);
        !           378:        ENTER_REVERSE =         tgetstr("mr", &bp);
        !           379:        EXIT_ATTRIBUTES =       tgetstr("me", &bp);
        !           380: 
        !           381:        if (!ENTER_BOLD && ENTER_REVERSE)
        !           382:                ENTER_BOLD = ENTER_REVERSE;
        !           383:        if (!ENTER_BOLD && ENTER_STANDOUT)
        !           384:                ENTER_BOLD = ENTER_STANDOUT;
        !           385:        if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
        !           386:                ENTER_UNDERLINE = ENTER_STANDOUT;
        !           387:                EXIT_UNDERLINE = EXIT_STANDOUT;
        !           388:        }
        !           389:        if (!ENTER_DIM && ENTER_STANDOUT)
        !           390:                ENTER_DIM = ENTER_STANDOUT;
        !           391:        if (!ENTER_REVERSE && ENTER_STANDOUT)
        !           392:                ENTER_REVERSE = ENTER_STANDOUT;
        !           393:        if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
        !           394:                EXIT_ATTRIBUTES = EXIT_STANDOUT;
        !           395:        
        !           396:        /*
        !           397:         * Note that we use REVERSE for the alternate character set,
        !           398:         * not the as/ae capabilities.  This is because we are modelling
        !           399:         * the model 37 teletype (since that's what nroff outputs) and
        !           400:         * the typical as/ae is more of a graphics set, not the greek
        !           401:         * letters the 37 has.
        !           402:         */
        !           403: 
        !           404:        UNDER_CHAR =            tgetstr("uc", &bp);
        !           405:        must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);
        !           406: }
        !           407: 
        !           408: outchar(c)
        !           409: char c;
        !           410: {
        !           411:        putchar(c&0177);
        !           412: }
        !           413: 
        !           414: puts(str)
        !           415: char *str;
        !           416: {
        !           417:        if (str)
        !           418:                tputs(str, 1, outchar);
        !           419: }
        !           420: 
        !           421: static curmode = 0;
        !           422: outc(c)
        !           423: char c;
        !           424: {
        !           425:        putchar(c);
        !           426:        if (must_use_uc &&  (curmode&UNDERL)) {
        !           427:                puts(CURS_LEFT);
        !           428:                puts(UNDER_CHAR);
        !           429:        }
        !           430: }
        !           431: 
        !           432: setmode(newmode)
        !           433: int newmode;
        !           434: {
        !           435:        if (!iflag)
        !           436:        {
        !           437:                if (curmode != NORMAL && newmode != NORMAL)
        !           438:                        setmode(NORMAL);
        !           439:                switch (newmode) {
        !           440:                case NORMAL:
        !           441:                        switch(curmode) {
        !           442:                        case NORMAL:
        !           443:                                break;
        !           444:                        case UNDERL:
        !           445:                                puts(EXIT_UNDERLINE);
        !           446:                                break;
        !           447:                        default:
        !           448:                                /* This includes standout */
        !           449:                                puts(EXIT_ATTRIBUTES);
        !           450:                                break;
        !           451:                        }
        !           452:                        break;
        !           453:                case ALTSET:
        !           454:                        puts(ENTER_REVERSE);
        !           455:                        break;
        !           456:                case SUPERSC:
        !           457:                        /*
        !           458:                         * This only works on a few terminals.
        !           459:                         * It should be fixed.
        !           460:                         */
        !           461:                        puts(ENTER_UNDERLINE);
        !           462:                        puts(ENTER_DIM);
        !           463:                        break;
        !           464:                case SUBSC:
        !           465:                        puts(ENTER_DIM);
        !           466:                        break;
        !           467:                case UNDERL:
        !           468:                        puts(ENTER_UNDERLINE);
        !           469:                        break;
        !           470:                case BOLD:
        !           471:                        puts(ENTER_BOLD);
        !           472:                        break;
        !           473:                default:
        !           474:                        /*
        !           475:                         * We should have some provision here for multiple modes
        !           476:                         * on at once.  This will have to come later.
        !           477:                         */
        !           478:                        puts(ENTER_STANDOUT);
        !           479:                        break;
        !           480:                }
        !           481:        }
        !           482:        curmode = newmode;
        !           483: }
        !           484: /*     @(#)getopt.c    3.2     */
        !           485: #define        ERR(s, c)       if(opterr){\
        !           486:        fputs(argv[0], stderr);\
        !           487:        fputs(s, stderr);\
        !           488:        fputc(c, stderr);\
        !           489:        fputc('\n', stderr);}
        !           490: 
        !           491: int    opterr = 1;
        !           492: int    optind = 1;
        !           493: char   *optarg;
        !           494: char   *index();
        !           495: 
        !           496: int
        !           497: getopt (argc, argv, opts)
        !           498:        char **argv, *opts;
        !           499: {
        !           500:        static int sp = 1;
        !           501:        char c;
        !           502:        char *cp;
        !           503: 
        !           504:        if (sp == 1)
        !           505:                if (optind >= argc ||
        !           506:                   argv[optind][0] != '-' || argv[optind][1] == '\0')
        !           507:                        return EOF;
        !           508:                else if (strcmp(argv[optind], "--") == NULL) {
        !           509:                        optind++;
        !           510:                        return EOF;
        !           511:                }
        !           512:                else if (strcmp(argv[optind], "-?") == NULL) {
        !           513:                        optind++;
        !           514:                        return '?';
        !           515:                }
        !           516:        c = argv[optind][sp];
        !           517:        if (c == ':' || (cp=index(opts, c)) == NULL) {
        !           518:                ERR (": illegal option -- ", c);
        !           519:                if (argv[optind][++sp] == '\0') {
        !           520:                        optind++;
        !           521:                        sp = 1;
        !           522:                }
        !           523:                return '?';
        !           524:        }
        !           525:        if (*++cp == ':') {
        !           526:                if (argv[optind][2] != '\0')
        !           527:                        optarg = &argv[optind++][sp+1];
        !           528:                else if (++optind >= argc) {
        !           529:                        ERR (": option requires an argument -- ", c);
        !           530:                        sp = 1;
        !           531:                        return '?';
        !           532:                } else
        !           533:                        optarg = argv[optind++];
        !           534:                sp = 1;
        !           535:        }
        !           536:        else if (argv[optind][++sp] == '\0') {
        !           537:                sp = 1;
        !           538:                optind++;
        !           539:        }
        !           540:        return c;
        !           541: }

unix.superglobalmegacorp.com

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