Annotation of 43BSDTahoe/ucb/ul.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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