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

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