Annotation of researchv10no/cmd/hp.c, revision 1.1.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.