Annotation of coherent/b/bin/readPCL.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * readPCL.c
                      3:  * 5/20/93
                      4:  *
                      5:  * Usage: readPCL [ -n ] [ infile [ outfile ]]
                      6:  * Option:
                      7:  *     -n      Produce nroff font info in output;
                      8:  *             e.g. "troff foo.r | readPCL -n | nroff -x | more"
                      9:  * Exit status:
                     10:  *     0       success
                     11:  *     1       unrecognized escape sequences seen
                     12:  *     2       fatal error, e.g. file not found
                     13:  * Requires floating point output: cc readPCL.c -f
                     14:  *
                     15:  * Expand PCL commands into readable text.
                     16:  * This currently handles a very small subset of PCL-5,
                     17:  * including only commands which the troff PCL output writer
                     18:  * and /bin/hp write.
                     19:  * Reference: HP "LaserJet III Technical Reference Manual", App. B.
                     20:  */
                     21:  
                     22: #if    __STDC__
                     23: #define        __(args)        args
                     24: #else
                     25: #define        __(args)        ()
                     26: #endif
                     27: 
                     28: #include <stdio.h>
                     29: #include <ctype.h>
                     30: 
                     31: #define        VERSION "1.4"
                     32: #define        ESC     '\033'
                     33: #define        NVALUE  80                              /* max parameter value length */
                     34: 
                     35: /*
                     36:  * Parameterized commands.
                     37:  * Very small subset of those available.
                     38:  * PVCMD command format depends on parameter value,
                     39:  * PCMD command format does not;
                     40:  * the PVCMD list gets searched first.
                     41:  */
                     42: typedef        struct  pvcmd   {
                     43:        char    pv_char;
                     44:        char    pv_group;
                     45:        int     pv_value;
                     46:        char    pv_param;
                     47:        char    *pv_fmt;
                     48: } PVCMD;
                     49: typedef        struct  pcmd    {
                     50:        char    p_char;
                     51:        char    p_group;
                     52:        char    p_param;
                     53:        char    *p_fmt;
                     54: } PCMD;
                     55: 
                     56: /* Parameterized commands with fixed values. */
                     57: PVCMD  pvcmds[] = {
                     58:        {       '(',    's',    0,      'p',    "fixed"         },
                     59:        {       '(',    's',    1,      'p',    "proportional"  },
                     60:        {       '(',    's',    0,      's',    "upright"       },
                     61:        {       '(',    's',    1,      's',    "italic"        },
                     62:        {       '&',    'd',    0,      'd',    "underline"     },
                     63:        {       '&',    'd',    3,      'd',    "fl underline"  },
                     64:        {       '&',    'l',    0,      'o',    "portrait"      },
                     65:        {       '&',    'l',    1,      'o',    "landscape"     },
                     66:        {       '&',    'l',    2,      'o',    "reverse portrait"      },
                     67:        {       '&',    'l',    3,      'o',    "reverse landscape"     },
                     68:        {       '&',    'l',    0,      'h',    "page eject"    }
                     69: };
                     70: #define        NPVCMDS (sizeof(pvcmds) / sizeof(pvcmds[0]))
                     71: 
                     72: /* Parameterized commands with arbitrary values; format expects double arg. */
                     73: PCMD   pcmds[] = {
                     74:        {       '&',    'a',    'c',    "hcol=%g"               },
                     75:        {       '&',    'a',    'h',    "h=%g"                  },
                     76:        {       '&',    'a',    'l',    "left margin=%g"        },
                     77:        {       '&',    'a',    'v',    "v=%g"                  },
                     78:        {       '&',    'd',    '@'+32, "underline off"         },
                     79:        {       '&',    'l',    'd',    "line spacing=%g"       },
                     80:        {       '&',    'l',    'e',    "top margin=%g"         },
                     81:        {       '&',    'l',    'f',    "text length=%g"        },
                     82:        {       '&',    'l',    'p',    "page length=%g"        },
                     83:        {       '(',    '0',    'u',    "symset=ASCII"          },
                     84:        {       '(',    's',    'b',    "weight=%g"             },
                     85:        {       '(',    's',    'h',    "pitch=%g"              },
                     86:        {       '(',    's',    't',    "typeface=%g"           },
                     87:        {       '(',    's',    'v',    "pointsize=%g"          }
                     88: };
                     89: #define        NPCMDS  (sizeof(pcmds) / sizeof(pcmds[0]))
                     90: 
                     91: /*
                     92:  * Two-character commands.
                     93:  * Small subset of those available.
                     94:  */
                     95: typedef        struct  tcmd    {
                     96:        char    t_char;
                     97:        char    *t_fmt;
                     98: } TCMD;
                     99: TCMD   tcmds[] = {
                    100:        {       '9',    "clear"         },
                    101:        {       'E',    "reset"         }
                    102: };
                    103: #define        NTCMDS  (sizeof(tcmds) / sizeof(tcmds[0]))
                    104: 
                    105: /* External. */
                    106: extern double  atof();
                    107: 
                    108: /* Forward. */
                    109: extern void    error   __((char *fmt, ...              ));
                    110: extern void    escape  __((void                        ));
                    111: extern void    esc_param __((int c                     ));
                    112: extern void    esc_two __((int c                       ));
                    113: extern void    fatal   __((char *fmt, ...              ));
                    114: extern void    lookup  __((int c, int group, double val, int param));
                    115: extern FILE    *openfile __((char *name, char *mode    ));
                    116: extern void    usage   __((void                        ));
                    117: extern double  value   __((int *signp                  ));
                    118: 
                    119: /* Globals. */
                    120: int    nflag;                                  /* nroff output */
                    121: int    status;                                 /* exit status  */
                    122: FILE   *ifp = stdin;                           /* input FILE   */
                    123: FILE   *ofp = stdout;                          /* output FILE  */
                    124: 
                    125: int
                    126: main(argc, argv) int argc; char *argv[];
                    127: {
                    128:        register char *s;
                    129:        register int c;
                    130: 
                    131:        /* Look for options. */
                    132:        if (argc > 1 && argv[1][0] == '-') {
                    133:                for (s = &argv[1][1]; *s != '\0'; s++) {
                    134:                        switch(*s) {
                    135:                        case 'n':       ++nflag;        break;
                    136:                        case 'V':
                    137:                                fprintf(stderr, "readPCL: V" VERSION "\n");
                    138:                                break;
                    139:                        default:        usage();        break;
                    140:                        }
                    141:                }
                    142:                --argc;
                    143:                ++argv;
                    144:        }
                    145: 
                    146:        /* Open files. */
                    147:        if (argc > 1)
                    148:                ifp = openfile(argv[1], "rb");
                    149:        if (argc > 2)
                    150:                ofp = openfile(argv[2], "w");
                    151: 
                    152:        /* Process. */
                    153:        if (nflag)
                    154:                fprintf(ofp, ".nf\n");
                    155:        while ((c = getc(ifp)) != EOF) {
                    156:                if (c == ESC)
                    157:                        escape();
                    158:                else
                    159:                        putc(c, ofp);
                    160:        }
                    161: 
                    162:        /* Done. */
                    163:        if (ifp != stdin)
                    164:                fclose(ifp);
                    165:        if (ofp != stdout)
                    166:                fclose(ofp);
                    167:        exit(status);
                    168: }
                    169: 
                    170: /*
                    171:  * Print an unrecognized escape sequence to the output text
                    172:  * and an error message to stderr.
                    173:  * Bump the error count.
                    174:  */
                    175: /* VARARGS */
                    176: void
                    177: error(fmt) char *fmt;
                    178: {
                    179:        status = 1;
                    180:        fprintf(ofp, "ESC %r", &fmt);
                    181:        fprintf(stderr, "readPCL: unrecognized ESC sequence: ESC %r\n", &fmt);
                    182: }
                    183: 
                    184: /*
                    185:  * Handle an escape sequence.
                    186:  */
                    187: void
                    188: escape()
                    189: {
                    190:        register int c;
                    191: 
                    192:        putc('\n', ofp);
                    193:        if (nflag)
                    194:                fprintf(ofp, "\\fB");
                    195:        putc('{', ofp);
                    196:        if ((c = getc(ifp)) >= 33 && c <= 47)
                    197:                esc_param(c);                   /* parameterized */
                    198:        else if (c >= 48 && c <= 126)
                    199:                esc_two(c);                     /* two-character */
                    200:        else
                    201:                error("%c (0x%X)", c, c);
                    202:        putc('}', ofp);
                    203:        if (nflag)
                    204:                fprintf(ofp, "\\fP");
                    205: }
                    206: 
                    207: /*
                    208:  * Parameterized escape sequence starting with c.
                    209:  */
                    210: void
                    211: esc_param(c) register int c;
                    212: {
                    213:        int group, param, done, sign;
                    214:        double val;
                    215: 
                    216:        group = getc(ifp);
                    217:        for (done = 0; !done; ) {
                    218:                val = value(&sign);
                    219:                param = getc(ifp);
                    220:                if (param >= 64 && param <= 94) {
                    221:                        ++done;
                    222:                        param += 32;
                    223:                }
                    224:                if (sign)
                    225:                        fprintf(ofp, "relative ");
                    226:                lookup(c, group, val, param);
                    227:                if (!done)
                    228:                        putc(';', ofp);
                    229:        }
                    230: }
                    231: 
                    232: /*
                    233:  * Two-character escape sequence starting with c.
                    234:  */
                    235: void
                    236: esc_two(c) register int c;
                    237: {
                    238:        register TCMD *p;
                    239: 
                    240:        for (p = tcmds; p < &tcmds[NPCMDS]; p++) {
                    241:                if (c == p->t_char) {
                    242:                        fprintf(ofp, p->t_fmt);
                    243:                        return;
                    244:                }
                    245:        }
                    246:        error("%c (0x%X)", c, c);
                    247: }
                    248: 
                    249: /*
                    250:  * Print a fatal error message and die.
                    251:  */
                    252: /* VARARGS */
                    253: void
                    254: fatal(fmt) char *fmt;
                    255: {
                    256:        fprintf(stderr, "readPCL: %r\n", &fmt);
                    257:        exit(2);
                    258: }
                    259: 
                    260: /*
                    261:  * Look up a parameterized command.
                    262:  * Print either a formatted message or an error message.
                    263:  */
                    264: void
                    265: lookup(c, group, val, param) int c, group; double val; int param;
                    266: {
                    267:        register PVCMD *pvp;
                    268:        register PCMD *pcp;
                    269: 
                    270:        /* Look for commands with matching value first. */
                    271:        for (pvp = pvcmds; pvp < &pvcmds[NPVCMDS]; pvp++) {
                    272:                if (c == pvp->pv_char
                    273:                 && group == pvp->pv_group
                    274:                 && (int)val == pvp->pv_value
                    275:                 && param == pvp->pv_param) {
                    276:                        fprintf(ofp, pvp->pv_fmt);
                    277:                        return;
                    278:                }
                    279:        }
                    280: 
                    281:        /* Then look for commands with arbitrary value. */
                    282:        for (pcp = pcmds; pcp < &pcmds[NPCMDS]; pcp++) {
                    283:                if (c == pcp->p_char
                    284:                 && group == pcp->p_group
                    285:                 && param == pcp->p_param) {
                    286:                        fprintf(ofp, pcp->p_fmt, val);
                    287:                        return;
                    288:                }
                    289:        }
                    290: 
                    291:        /* Not found. */
                    292:        error("%c %c %g %c", c, group, val, param);
                    293: }
                    294: 
                    295: /*
                    296:  * Open a FILE.
                    297:  */
                    298: FILE *
                    299: openfile (name, mode) char *name; char *mode;
                    300: {
                    301:        register FILE *fp;
                    302: 
                    303:        if ((fp = fopen(name, mode)) == NULL)
                    304:                fatal("cannot open file \"%s\"", name);
                    305:        return fp;
                    306: }
                    307: 
                    308: /*
                    309:  * Print a usage message and die.
                    310:  */
                    311: void
                    312: usage()
                    313: {
                    314:        fprintf(stderr,
                    315:                "Usage: readPCL [ -n ] [ infile [ outfile ]]\n"
                    316:                "Option:\n"
                    317:                "\t-n\tProduce nroff output;\n"
                    318:                "\t\te.g. \"troff foo.r | readPCL -n | nroff -x | more\"\n"
                    319:                );
                    320:        exit(1);
                    321: }
                    322: 
                    323: /*
                    324:  * Read a PCL value field:
                    325:  * ASCII number consisting of optional sign, digits and optional decimal point.
                    326:  * Store the sign through *signp: -1 for '-', 0 for none, 1 for '+';
                    327:  * for some PCL commands, the value can be absolute or relative,
                    328:  * depending on the presence/absence of the sign.
                    329:  * Return 0.0 if the value is missing.
                    330:  */
                    331: double
                    332: value(signp) int *signp;
                    333: {
                    334:        char buf[NVALUE];
                    335:        register char *cp;
                    336:        register int c, s, dotseen;
                    337:        double d;
                    338: 
                    339:        /* Handle optional sign. */
                    340:        dotseen = s = 0;
                    341:        if ((c = getc(ifp)) == '-')
                    342:                --s;
                    343:        else if (c == '+')
                    344:                ++s;
                    345:        else
                    346:                ungetc(c, ifp);
                    347: 
                    348:        /* Read the number into buf[]. */
                    349:        for (cp = buf; isdigit(c = getc(ifp)) || (c=='.' && (dotseen++ == 0)); )
                    350:                *cp++ = c;
                    351:        *cp = '\0';
                    352:        ungetc(c, ifp);
                    353: 
                    354:        /* Return converted value; note that atof("") returns 0.0. */
                    355:        d = atof(buf);
                    356:        *signp = s;
                    357:        return (s == -1) ? -d : d;
                    358: }
                    359: 
                    360: /* end of readPCL.c */

unix.superglobalmegacorp.com

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