Annotation of coherent/b/bin/readPCL.c, revision 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.