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

unix.superglobalmegacorp.com

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