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