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

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)ul.c       4.5 (Berkeley) 8/11/83";
        !             3: #endif
        !             4: 
        !             5: #include <stdio.h>
        !             6: 
        !             7: #define        IESC    '\033'
        !             8: #define        SO      '\016'
        !             9: #define        SI      '\017'
        !            10: #define        HFWD    '9'
        !            11: #define        HREV    '8'
        !            12: #define        FREV    '7'
        !            13: #define        MAXBUF  512
        !            14: 
        !            15: #define        NORMAL  000
        !            16: #define        ALTSET  001     /* Reverse */
        !            17: #define        SUPERSC 002     /* Dim */
        !            18: #define        SUBSC   004     /* Dim | Ul */
        !            19: #define        UNDERL  010     /* Ul */
        !            20: #define        BOLD    020     /* Bold */
        !            21: 
        !            22: int    must_use_uc, must_overstrike;
        !            23: char   *CURS_UP, *CURS_RIGHT, *CURS_LEFT,
        !            24:        *ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE,
        !            25:        *ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES;
        !            26: 
        !            27: struct CHAR    {
        !            28:        char    c_mode;
        !            29:        char    c_char;
        !            30: } ;
        !            31: 
        !            32: char   buf[BUFSIZ];
        !            33: 
        !            34: struct CHAR    obuf[MAXBUF];
        !            35: int    col, maxcol;
        !            36: int    mode;
        !            37: int    halfpos;
        !            38: int    upln;
        !            39: int    iflag;
        !            40: 
        !            41: main(argc, argv)
        !            42:        int argc;
        !            43:        char **argv;
        !            44: {
        !            45:        int c;
        !            46:        char *cp, *termtype;
        !            47:        FILE *f;
        !            48:        char termcap[1024];
        !            49:        char *getenv();
        !            50:        extern int optind;
        !            51:        extern char *optarg;
        !            52: 
        !            53:        termtype = getenv("TERM");
        !            54:        if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1)))
        !            55:                termtype = "lpr";
        !            56:        while ((c=getopt(argc, argv, "it:T:")) != EOF)
        !            57:                switch(c) {
        !            58: 
        !            59:                case 't':
        !            60:                case 'T': /* for nroff compatibility */
        !            61:                                termtype = optarg;
        !            62:                        break;
        !            63:                case 'i':
        !            64:                        iflag = 1;
        !            65:                        break;
        !            66: 
        !            67:                default:
        !            68:                        fprintf(stderr,
        !            69:                                "Usage: %s [ -i ] [ -tTerm ] file...\n",
        !            70:                                argv[0]);
        !            71:                        exit(1);
        !            72:                }
        !            73: 
        !            74:        switch(tgetent(termcap, termtype)) {
        !            75: 
        !            76:        case 1:
        !            77:                break;
        !            78: 
        !            79:        default:
        !            80:                fprintf(stderr,"trouble reading termcap");
        !            81:                /* fall through to ... */
        !            82: 
        !            83:        case 0:
        !            84:                /* No such terminal type - assume dumb */
        !            85:                strcpy(termcap, "dumb:os:col#80:cr=^M:sf=^J:am:");
        !            86:                break;
        !            87:        }
        !            88:        initcap();
        !            89:        if (    (tgetflag("os") && ENTER_BOLD==NULL ) ||
        !            90:                (tgetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
        !            91:                        must_overstrike = 1;
        !            92:        setbuf(stdout, buf);
        !            93:        initbuf();
        !            94:        if (optind == argc)
        !            95:                filter(stdin);
        !            96:        else for (; optind<argc; optind++) {
        !            97:                f = fopen(argv[optind],"r");
        !            98:                if (f == NULL) {
        !            99:                        perror(argv[optind]);
        !           100:                        exit(1);
        !           101:                } else
        !           102:                        filter(f);
        !           103:        }
        !           104:        exit(0);
        !           105: }
        !           106: 
        !           107: filter(f)
        !           108: FILE *f;
        !           109: {
        !           110:        register c;
        !           111: 
        !           112:        while((c = getc(f)) != EOF) switch(c) {
        !           113: 
        !           114:        case '\b':
        !           115:                if (col > 0)
        !           116:                        col--;
        !           117:                continue;
        !           118: 
        !           119:        case '\t':
        !           120:                col = (col+8) & ~07;
        !           121:                if (col > maxcol)
        !           122:                        maxcol = col;
        !           123:                continue;
        !           124: 
        !           125:        case '\r':
        !           126:                col = 0;
        !           127:                continue;
        !           128: 
        !           129:        case SO:
        !           130:                mode |= ALTSET;
        !           131:                continue;
        !           132: 
        !           133:        case SI:
        !           134:                mode &= ~ALTSET;
        !           135:                continue;
        !           136: 
        !           137:        case IESC:
        !           138:                switch (c = getc(f)) {
        !           139: 
        !           140:                case HREV:
        !           141:                        if (halfpos == 0) {
        !           142:                                mode |= SUPERSC;
        !           143:                                halfpos--;
        !           144:                        } else if (halfpos > 0) {
        !           145:                                mode &= ~SUBSC;
        !           146:                                halfpos--;
        !           147:                        } else {
        !           148:                                halfpos = 0;
        !           149:                                reverse();
        !           150:                        }
        !           151:                        continue;
        !           152: 
        !           153:                case HFWD:
        !           154:                        if (halfpos == 0) {
        !           155:                                mode |= SUBSC;
        !           156:                                halfpos++;
        !           157:                        } else if (halfpos < 0) {
        !           158:                                mode &= ~SUPERSC;
        !           159:                                halfpos++;
        !           160:                        } else {
        !           161:                                halfpos = 0;
        !           162:                                fwd();
        !           163:                        }
        !           164:                        continue;
        !           165: 
        !           166:                case FREV:
        !           167:                        reverse();
        !           168:                        continue;
        !           169: 
        !           170:                default:
        !           171:                        fprintf(stderr,
        !           172:                                "Unknown escape sequence in input: %o, %o\n",
        !           173:                                IESC, c);
        !           174:                        exit(1);
        !           175:                }
        !           176:                continue;
        !           177: 
        !           178:        case '_':
        !           179:                if (obuf[col].c_char)
        !           180:                        obuf[col].c_mode |= UNDERL | mode;
        !           181:                else
        !           182:                        obuf[col].c_char = '_';
        !           183:        case ' ':
        !           184:                col++;
        !           185:                if (col > maxcol)
        !           186:                        maxcol = col;
        !           187:                continue;
        !           188: 
        !           189:        case '\n':
        !           190:                flushln();
        !           191:                continue;
        !           192: 
        !           193:        default:
        !           194:                if (c < ' ')    /* non printing */
        !           195:                        continue;
        !           196:                if (obuf[col].c_char == '\0') {
        !           197:                        obuf[col].c_char = c;
        !           198:                        obuf[col].c_mode = mode;
        !           199:                } else if (obuf[col].c_char == '_') {
        !           200:                        obuf[col].c_char = c;
        !           201:                        obuf[col].c_mode |= UNDERL|mode;
        !           202:                } else if (obuf[col].c_char == c)
        !           203:                        obuf[col].c_mode |= BOLD|mode;
        !           204:                else {
        !           205:                        obuf[col].c_mode = c;
        !           206:                        obuf[col].c_mode = mode;
        !           207:                }
        !           208:                col++;
        !           209:                if (col > maxcol)
        !           210:                        maxcol = col;
        !           211:                continue;
        !           212:        }
        !           213:        if (maxcol)
        !           214:                flushln();
        !           215: }
        !           216: 
        !           217: flushln()
        !           218: {
        !           219:        register lastmode;
        !           220:        register i;
        !           221:        int hadmodes = 0;
        !           222: 
        !           223:        lastmode = NORMAL;
        !           224:        for (i=0; i<maxcol; i++) {
        !           225:                if (obuf[i].c_mode != lastmode) {
        !           226:                        hadmodes++;
        !           227:                        setmode(obuf[i].c_mode);
        !           228:                        lastmode = obuf[i].c_mode;
        !           229:                }
        !           230:                if (obuf[i].c_char == '\0') {
        !           231:                        if (upln) {
        !           232:                                puts(CURS_RIGHT);
        !           233:                        } else
        !           234:                                outc(' ');
        !           235:                } else
        !           236:                        outc(obuf[i].c_char);
        !           237:        }
        !           238:        if (lastmode != NORMAL) {
        !           239:                setmode(0);
        !           240:        }
        !           241:        if (must_overstrike && hadmodes)
        !           242:                overstrike();
        !           243:        putchar('\n');
        !           244:        if (iflag && hadmodes)
        !           245:                iattr();
        !           246:        fflush(stdout);
        !           247:        if (upln)
        !           248:                upln--;
        !           249:        initbuf();
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * For terminals that can overstrike, overstrike underlines and bolds.
        !           254:  * We don't do anything with halfline ups and downs, or Greek.
        !           255:  */
        !           256: overstrike()
        !           257: {
        !           258:        register int i;
        !           259:        char lbuf[256];
        !           260:        register char *cp = lbuf;
        !           261:        int hadbold=0;
        !           262: 
        !           263:        /* Set up overstrike buffer */
        !           264:        for (i=0; i<maxcol; i++)
        !           265:                switch (obuf[i].c_mode) {
        !           266:                case NORMAL:
        !           267:                default:
        !           268:                        *cp++ = ' ';
        !           269:                        break;
        !           270:                case UNDERL:
        !           271:                        *cp++ = '_';
        !           272:                        break;
        !           273:                case BOLD:
        !           274:                        *cp++ = obuf[i].c_char;
        !           275:                        hadbold=1;
        !           276:                        break;
        !           277:                }
        !           278:        putchar('\r');
        !           279:        for (*cp=' '; *cp==' '; cp--)
        !           280:                *cp = 0;
        !           281:        for (cp=lbuf; *cp; cp++)
        !           282:                putchar(*cp);
        !           283:        if (hadbold) {
        !           284:                putchar('\r');
        !           285:                for (cp=lbuf; *cp; cp++)
        !           286:                        putchar(*cp=='_' ? ' ' : *cp);
        !           287:                putchar('\r');
        !           288:                for (cp=lbuf; *cp; cp++)
        !           289:                        putchar(*cp=='_' ? ' ' : *cp);
        !           290:        }
        !           291: }
        !           292: 
        !           293: iattr()
        !           294: {
        !           295:        register int i;
        !           296:        char lbuf[256];
        !           297:        register char *cp = lbuf;
        !           298: 
        !           299:        for (i=0; i<maxcol; i++)
        !           300:                switch (obuf[i].c_mode) {
        !           301:                case NORMAL:    *cp++ = ' '; break;
        !           302:                case ALTSET:    *cp++ = 'g'; break;
        !           303:                case SUPERSC:   *cp++ = '^'; break;
        !           304:                case SUBSC:     *cp++ = 'v'; break;
        !           305:                case UNDERL:    *cp++ = '_'; break;
        !           306:                case BOLD:      *cp++ = '!'; break;
        !           307:                default:        *cp++ = 'X'; break;
        !           308:                }
        !           309:        for (*cp=' '; *cp==' '; cp--)
        !           310:                *cp = 0;
        !           311:        for (cp=lbuf; *cp; cp++)
        !           312:                putchar(*cp);
        !           313:        putchar('\n');
        !           314: }
        !           315: 
        !           316: initbuf()
        !           317: {
        !           318:        register i;
        !           319: 
        !           320:        for (i=0; i<MAXBUF; i++) {
        !           321:                obuf[i].c_char = '\0';
        !           322:                obuf[i].c_mode = NORMAL;
        !           323:        }
        !           324:        col = 0;
        !           325:        maxcol = 0;
        !           326:        mode &= ALTSET;
        !           327: }
        !           328: 
        !           329: fwd()
        !           330: {
        !           331:        register oldcol, oldmax;
        !           332: 
        !           333:        oldcol = col;
        !           334:        oldmax = maxcol;
        !           335:        flushln();
        !           336:        col = oldcol;
        !           337:        maxcol = oldmax;
        !           338: }
        !           339: 
        !           340: reverse()
        !           341: {
        !           342:        upln++;
        !           343:        fwd();
        !           344:        puts(CURS_UP);
        !           345:        puts(CURS_UP);
        !           346:        upln++;
        !           347: }
        !           348: 
        !           349: initcap()
        !           350: {
        !           351:        static char tcapbuf[512];
        !           352:        char *termtype;
        !           353:        char *bp = tcapbuf;
        !           354:        char *getenv(), *tgetstr();
        !           355: 
        !           356:        /* This nonsense attempts to work with both old and new termcap */
        !           357:        CURS_UP =               tgetstr("up", &bp);
        !           358:        CURS_RIGHT =            tgetstr("ri", &bp);
        !           359:        if (CURS_RIGHT == NULL)
        !           360:                CURS_RIGHT =    tgetstr("nd", &bp);
        !           361:        CURS_LEFT =             tgetstr("le", &bp);
        !           362:        if (CURS_LEFT == NULL)
        !           363:                CURS_LEFT =     tgetstr("bc", &bp);
        !           364:        if (CURS_LEFT == NULL && tgetflag("bs"))
        !           365:                CURS_LEFT =     "\b";
        !           366: 
        !           367:        ENTER_STANDOUT =        tgetstr("so", &bp);
        !           368:        EXIT_STANDOUT =         tgetstr("se", &bp);
        !           369:        ENTER_UNDERLINE =       tgetstr("us", &bp);
        !           370:        EXIT_UNDERLINE =        tgetstr("ue", &bp);
        !           371:        ENTER_DIM =             tgetstr("mh", &bp);
        !           372:        ENTER_BOLD =            tgetstr("md", &bp);
        !           373:        ENTER_REVERSE =         tgetstr("mr", &bp);
        !           374:        EXIT_ATTRIBUTES =       tgetstr("me", &bp);
        !           375: 
        !           376:        if (!ENTER_BOLD && ENTER_REVERSE)
        !           377:                ENTER_BOLD = ENTER_REVERSE;
        !           378:        if (!ENTER_BOLD && ENTER_STANDOUT)
        !           379:                ENTER_BOLD = ENTER_STANDOUT;
        !           380:        if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
        !           381:                ENTER_UNDERLINE = ENTER_STANDOUT;
        !           382:                EXIT_UNDERLINE = EXIT_STANDOUT;
        !           383:        }
        !           384:        if (!ENTER_DIM && ENTER_STANDOUT)
        !           385:                ENTER_DIM = ENTER_STANDOUT;
        !           386:        if (!ENTER_REVERSE && ENTER_STANDOUT)
        !           387:                ENTER_REVERSE = ENTER_STANDOUT;
        !           388:        if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
        !           389:                EXIT_ATTRIBUTES = EXIT_STANDOUT;
        !           390:        
        !           391:        /*
        !           392:         * Note that we use REVERSE for the alternate character set,
        !           393:         * not the as/ae capabilities.  This is because we are modelling
        !           394:         * the model 37 teletype (since that's what nroff outputs) and
        !           395:         * the typical as/ae is more of a graphics set, not the greek
        !           396:         * letters the 37 has.
        !           397:         */
        !           398: 
        !           399: #ifdef notdef
        !           400: printf("so %s se %s us %s ue %s me %s\n",
        !           401:        ENTER_STANDOUT, EXIT_STANDOUT, ENTER_UNDERLINE,
        !           402:        EXIT_UNDERLINE, EXIT_ATTRIBUTES);
        !           403: #endif
        !           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.