Annotation of researchv10no/cmd/hp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     hp [-e] [-m]
        !             3:  *     convert nroff TTY37 output to right form for HP2640x terminals.
        !             4:  *     -e indicates enhanced terminal with underline, etc.
        !             5:  *     -m requests minimization of output by removing multiple newlines
        !             6:  */
        !             7: 
        !             8: char hpvers[] = "@(#)hp.c      1.6";
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <signal.h>
        !            12: #include <sys/types.h>
        !            13: #include <sys/stat.h>
        !            14: #include <sgtty.h>
        !            15: #define        ESC     033     /* escape */
        !            16: #define        HFWD    '9'
        !            17: #define        HREV    '8'
        !            18: #define        FREV    '7'
        !            19: #define        SO      016     /* shift out - enter greek */
        !            20: #define        SI      017     /* shift in */
        !            21: #define LF     '\n'
        !            22: #define CR     015
        !            23: #define        NFLAG   0200    /* hi-bit flag for non-showing chars */
        !            24: #define        NMASK   0177
        !            25: #define AMP    046     /* & */
        !            26: #define DEE    0144    /* d */
        !            27: #define        BFSIZ   4096    /* size of output buffer */
        !            28:                        /* (bigger because of tbl weirds */
        !            29:                        /* and nroff idiosyncracies      */
        !            30: 
        !            31: /*     puty adds control char to output, marked by hi-bit */
        !            32: #define puty(c)        putx(c|NFLAG)
        !            33: #define flg(x) ((char)(x|NFLAG))   /* set hi-bit of x */
        !            34: int    nlcnt,          /* accumulated newline count */
        !            35:        frevcnt,        /* accumulated reverse line-feeds */
        !            36:        halfpos,        /* half-line position: -1 = above, +1 = below */
        !            37:        restrict = 1,   /* 0==> full terminal, 1==> no display enhancements */
        !            38:        minimiz;        /* 0==> normal, 1==> remove extra newlines */
        !            39: char   *ttydev;
        !            40: int    svstmode;       /* for mesg restore */
        !            41: int    restore();
        !            42: char   *ttyname();
        !            43: int    svsgflgs;
        !            44: struct sgttyb  sgb;
        !            45: int    retcode = 2;    /* return code */
        !            46: char   peekbuf[2];
        !            47: char   *peekstr = peekbuf;     /* lookahead ptr */
        !            48: 
        !            49: char   outbf[BFSIZ];   /* output assembly buffer */
        !            50: char   *bfnext = outbf,        /* addr of next empty byte */
        !            51:        *bflast =  &outbf[BFSIZ-1];     /* addr of last usable byte */
        !            52: 
        !            53: /*     normal display enhancement strings */
        !            54: char   *enunder =      "\033&dD",      /* underline */
        !            55:        *ennorml =      "\033&d@",      /* normal output */
        !            56:        *ensuper =      "\033&dH",      /* superscript (half) */
        !            57:        *ensubsc =      "\033&dL",      /* subscript (half, underlined */
        !            58:        *enrestr =      "\033&dB";      /* restricted (inverse only) */
        !            59: 
        !            60: int    restore();
        !            61: main(argc, argv)
        !            62: char **argv;
        !            63: {
        !            64:        register c;
        !            65:        scanarg(argc,argv);
        !            66:        if (((int)signal(SIGINT, SIG_IGN) & 01) == 0)
        !            67:                signal(SIGINT, restore);
        !            68:        if (gtty(1, &sgb) == 0)
        !            69:                fixtty();
        !            70:        setbuf(stdin, calloc(BUFSIZ,1));
        !            71:        while((c = getchal()) != EOF) {
        !            72:                if (nlcnt && c != LF) flushnl();
        !            73:                if (frevcnt && c != ESC) flushrv();
        !            74:                if (c == LF) {
        !            75:                        if (++nlcnt == 1) flushln();
        !            76:                        continue;
        !            77:                }
        !            78:                if (c == ESC)
        !            79:                        escape();
        !            80:                else if (c == SO)
        !            81:                        special();
        !            82:                else if (c == '\b')
        !            83:                        backsp();
        !            84:                else if (c == '_') {            /* C nroff */
        !            85:                        if ((c = getchal()) == '\b') {
        !            86:                                undersc();
        !            87:                        } else {
        !            88:                                putx('_');
        !            89:                                peekbuf[0] = c;
        !            90:                                peekstr = peekbuf;
        !            91:                        }
        !            92:                }
        !            93:                else
        !            94:                        putx(c);
        !            95:        }
        !            96:        flusher();
        !            97:        retcode = 0;
        !            98:        restore();
        !            99: }
        !           100: 
        !           101: getchal()
        !           102: {
        !           103:        if (*peekstr)
        !           104:                return(*peekstr++);
        !           105:        return(getchar());
        !           106: }
        !           107: 
        !           108: /*     scanarg: scan arguments and set flags; ignore unknown args */
        !           109: scanarg(argc,argv)
        !           110:        int argc; char **argv;
        !           111: {
        !           112:        register char *p;
        !           113:        while ( --argc > 0) {
        !           114:                p = *++argv;
        !           115:                if (*p == '-') {
        !           116:                        ++p;
        !           117:                        if (*p == 'e') restrict = 0;
        !           118:                        else if (*p == 'm') minimiz = 1;
        !           119:                }
        !           120:        }
        !           121:        if (restrict)
        !           122:                enunder = ensuper = ensubsc = enrestr;
        !           123: }
        !           124: 
        !           125: /*     fixtty: get tty status and save; remove delay and CR-LF mapping */
        !           126: fixtty()
        !           127: {
        !           128:        struct stat sb;
        !           129: 
        !           130:        svsgflgs = sgb.sg_flags;
        !           131:        sgb.sg_flags &= ~(ALLDELAY|CRMOD);
        !           132:        stty(1, &sgb);  /* stty nl nl0 cr0 tab0 ff0 */
        !           133:        fstat(1, &sb);
        !           134:        svstmode = sb.st_mode;
        !           135:        ttydev = ttyname(1);
        !           136:        if (ttydev && *ttydev)
        !           137:                chmod(ttydev, 0600);    /* mesg n */
        !           138: }
        !           139: 
        !           140: /*     flusher: flush accumulated newlines, reverse line feeds, buffer */
        !           141: flusher()
        !           142: {
        !           143:        flushln();
        !           144:        if (nlcnt) flushnl();
        !           145:        if (frevcnt) flushrv();
        !           146:        fflush(stdout);
        !           147: }
        !           148: 
        !           149: /*     flushrv: flush accumulated reverse line feeds */
        !           150: flushrv()
        !           151: {
        !           152:        while (frevcnt--) 
        !           153:                putstr("\033T");
        !           154:        putstr(ennorml);
        !           155:        frevcnt = 0;
        !           156: }
        !           157: 
        !           158: /*     flushnl: flush accumulated newlines (count in nlcnt) */
        !           159: flushnl()
        !           160: {
        !           161:        if (minimiz != 0 && nlcnt > 2) nlcnt = 2;
        !           162:        putchar(CR);
        !           163:        while (nlcnt--)
        !           164:                putchar(LF);
        !           165:        nlcnt = 0;
        !           166: }
        !           167: 
        !           168: putstr(p)
        !           169: char *p;
        !           170: {
        !           171:        register char *pp;
        !           172:        pp = p; 
        !           173:        while (*pp) puty(*pp++);
        !           174: }
        !           175: 
        !           176: restore(){
        !           177:        if (isatty(1)) {
        !           178:                sgb.sg_flags = svsgflgs;
        !           179:                stty(1, &sgb);
        !           180:                if (ttydev && *ttydev)
        !           181:                        chmod(ttydev, svstmode);
        !           182:        }
        !           183:        exit(retcode);
        !           184: }
        !           185: 
        !           186: char   tab[] = {
        !           187:        'A','A',        /* alpha */
        !           188:        'B','B',        /* beta */
        !           189:        'D','W',        /* delta */
        !           190:        'W','V',        /* DELTA */
        !           191:        'S','E',        /* epsilon */
        !           192:        'N','H',        /* eta */
        !           193:        '\\','Q',       /* gamma */
        !           194:        'G','+',        /* GAMMA */
        !           195:        'o','<',        /* infinity - not in M37 */
        !           196:        '^','\'',       /* integral */
        !           197:        'L','G',        /* lambda */
        !           198:        'E',';',        /* LAMBDA */
        !           199:        'M','M',        /* mu */
        !           200:        '[','$',        /* nabla (del) */
        !           201:        '_','\\',       /* not */
        !           202:        '@','N',        /* nu */
        !           203:        'C','L',        /* omega */
        !           204:        'Z',':',        /* OMEGA */
        !           205:        ']','F',        /* partial */
        !           206:        'U','D',        /* phi */
        !           207:        'F','.',        /* PHI */
        !           208:        'V','C',        /* psi */
        !           209:        'H',',',        /* PSI */
        !           210:        'J','P',        /* pi */
        !           211:        'P','*',        /* PI */
        !           212:        'K','O',        /* rho */
        !           213:        'Y','S',        /* sigma */
        !           214:        'R','?',        /* SIGMA */
        !           215:        'I','T',        /* tau */
        !           216:        'T','R',        /* theta */
        !           217:        'O','J',        /* THETA */
        !           218:        'X','U',        /* xi */
        !           219:        'Q','Z',        /* zeta */
        !           220:        'v','Y',
        !           221:        0
        !           222: };
        !           223: 
        !           224: char spec1[] = {LF,SO,0};
        !           225: special(){
        !           226:        register int c;
        !           227:        register char *p;
        !           228:        puty(SO);
        !           229:        while ((c = getchal()) != EOF) {
        !           230:                if (c == SI) {
        !           231:                        puty(c);
        !           232:                        return;
        !           233:                }
        !           234:                if (c == LF) {
        !           235:                        peekstr = spec1;
        !           236:                        return;
        !           237:                }
        !           238:                for (p = tab; *p != 0; p += 2)
        !           239:                        if (c == *p) {
        !           240:                                c = *++p;
        !           241:                                break;
        !           242:                        }
        !           243:                putx(c);
        !           244:        }
        !           245: }
        !           246: 
        !           247: /*     escape: handle escape sequences */
        !           248: escape()
        !           249: {
        !           250:        register int c;
        !           251:        c = getchal();
        !           252:        if (frevcnt && c != FREV) flushrv();
        !           253:        switch (c) {
        !           254:        case FREV:
        !           255:                frevcnt++;
        !           256:                break;
        !           257:        case HREV:
        !           258:                if (halfpos == 0) {
        !           259:                        putstr(ensuper);
        !           260:                        halfpos--;
        !           261:                }
        !           262:                else if (halfpos > 0) {
        !           263:                        putstr(ennorml);
        !           264:                        halfpos--;
        !           265:                }
        !           266:                else {
        !           267:                        putstr("\033T"); /* roll back 1 */
        !           268:                        putstr(ennorml);
        !           269:                        halfpos = 0;
        !           270:                }
        !           271:                break;
        !           272:        case HFWD:
        !           273:                if (halfpos == 0) {
        !           274:                        putstr(ensubsc);
        !           275:                        halfpos++;
        !           276:                }
        !           277:                else if (halfpos < 0) {
        !           278:                        putstr(ennorml);
        !           279:                        halfpos++;
        !           280:                }
        !           281:                else {
        !           282:                        putstr("\033S");        /* roll up 1, i.e., LF w/o CR */
        !           283:                        putstr(ennorml);
        !           284:                        halfpos = 0;
        !           285:                }
        !           286:                break;
        !           287:        case '&':
        !           288:                putstr("\033&");
        !           289:                puty(c = getchal());
        !           290:                if (c == 'd') puty(getchal());
        !           291:                break;
        !           292:        case ')':
        !           293:                putstr("\033)");
        !           294:                puty(getchal());
        !           295:                break;
        !           296: default:
        !           297:                puty(ESC);
        !           298:                puty(getchal());
        !           299:                break;
        !           300:        }
        !           301: }
        !           302: 
        !           303: char peeku[3];
        !           304: /*     backsp: handle backspacing */
        !           305: /* sequences are handled such that : ( \b is backspace )   */
        !           306: /*     a\b_ -> a in inverse video    */
        !           307: /*     _\ba -> a in inverse video    */
        !           308: /*     c\bd -> c in inverse video    */
        !           309: /* if a control char (ESC) precedes or follows '\b'  */
        !           310: /* then an actual backspace movement is performed    */
        !           311: backsp()
        !           312: {
        !           313:        register char *bftmp;
        !           314:        register int c;
        !           315:        char *bfhi;
        !           316:        int i, j, ncnt, bscnt;
        !           317:        char *p, *p1;
        !           318:        p = bfnext-2;
        !           319:        p1 = bfnext-4;
        !           320:        /* check if last char put in buffer was escape sequence */
        !           321:        /* if so, put backspace control sequence in buffer */
        !           322:        /* check against "\033&d" */
        !           323:        if ((*p == flg(ESC)) ||
        !           324:           (*p1++ == flg(ESC) && *p1++==flg(AMP) && *p1==flg(DEE))) {
        !           325:                putstr("\033D");
        !           326:                while((c=getchal())=='\b') putstr("\033D");
        !           327:                /* put last char back */
        !           328:                peeku[0] = c;
        !           329:                peeku[1] = '\0';
        !           330:                peekstr = peeku;
        !           331:                return;
        !           332:        }
        !           333:        bscnt = 1;
        !           334:        c = getchal();
        !           335:        /* count backspaces */
        !           336:        while (c == '\b') {
        !           337:                bscnt++;
        !           338:                c = getchal();
        !           339:        }       
        !           340:        /* read in chars until bscnt have been read */
        !           341:        /* or until an ESC is read */
        !           342:        ncnt = 0;
        !           343:        if (c!=ESC) {
        !           344:                for (ncnt=0; (ncnt<bscnt && c!=ESC); ncnt++)
        !           345:                        c = getchal();
        !           346:                /* since there were normal chars with backsp */
        !           347:                /* insert inverse video chars in buffer */
        !           348:                bftmp = bfhi = bfnext + 4;
        !           349:                for (i=0; i<bscnt;)
        !           350:                        if (((*--bftmp = *--bfnext) & NFLAG) == 0) i++;
        !           351:                putstr(enunder);
        !           352:                bfnext = bfhi;
        !           353:                }
        !           354:        /* if number of bcksp is not = to number normal chars */
        !           355:        /* then some bcksp chars will be inserted as actual */
        !           356:        /* bcksp movement and not inverse video for another char */
        !           357:        j = bscnt - ncnt;
        !           358:        if (j == 0) putstr(ennorml);
        !           359:        else {
        !           360:                /* move chars over and insert normal char seq */
        !           361:                if (ncnt > 0) {
        !           362:                        bftmp = bfhi = bfnext + 4;
        !           363:                        for (i=0; i<j;)
        !           364:                                if (((*--bftmp = *--bfnext) & NFLAG) == 0) i++;
        !           365:                        putstr(ennorml);
        !           366:                        bfnext = bfhi;
        !           367:                }
        !           368:                /* insert backspace movement chars */
        !           369:                while (j--) putstr("\033D");
        !           370:        }
        !           371:        /* put last char read back */
        !           372:        peeku[0] = c;
        !           373:        peeku[1] = '\0';
        !           374:        peekstr = peeku;
        !           375: }
        !           376: /*     undersc: handle C nroff's (_ BS char)+ sequences
        !           377:  *     assumes _ BS already found
        !           378:  *     if char is a control char, put char back and break.
        !           379:  */
        !           380: undersc()
        !           381: {
        !           382:        register char c;
        !           383: 
        !           384:        putstr(enunder);
        !           385:        while (1) {
        !           386:                if ((c=getchal())==ESC) {
        !           387:                        peeku[0] = c; peeku[1] = '\0';
        !           388:                        peekstr = peeku;
        !           389:                        break;
        !           390:                }
        !           391:                else
        !           392:                        putx(c);
        !           393:                if ((c = getchal()) != '_') {
        !           394:                        peeku[0] = c; peeku[1] = '\0';
        !           395:                        peekstr = peeku;
        !           396:                        break;
        !           397:                }
        !           398:                if ((c = getchal()) != '\b') {
        !           399:                        peeku[0] = '_'; peeku[1] = c;
        !           400:                        peekstr = peeku;
        !           401:                        break;
        !           402:                }
        !           403:        }
        !           404:        putstr(ennorml);
        !           405: }
        !           406: 
        !           407: /*     flushln: flush out accumulated line */
        !           408: flushln()
        !           409: {
        !           410: register char c, *p;
        !           411:        putx('\0');
        !           412:        p = outbf;
        !           413:        while (c = (*p++ & NMASK)) putchar(c);
        !           414:        bfnext = outbf;
        !           415: }
        !           416: 
        !           417: /*     putx: add normal (printing) char to output */
        !           418: putx(c)
        !           419: char c;
        !           420: {
        !           421:        if (bfnext <= bflast)
        !           422:                *bfnext++ = c;
        !           423:        else die("line too long\n");
        !           424: }
        !           425: 
        !           426: die(mesg)
        !           427: char *mesg;
        !           428: {
        !           429:        register char *p;
        !           430:        char *c = "hp: ";
        !           431: 
        !           432:        write(2, c, 4);
        !           433:        p = mesg;
        !           434:        while (*p)
        !           435:                write(2, p++, 1);
        !           436:        restore();
        !           437: }

unix.superglobalmegacorp.com

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