Annotation of 43BSDTahoe/ucb/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 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.