Annotation of coherent/d/bin/lpr/hp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * hp.c
        !             3:  * 11/13/90
        !             4:  * Hewlett Packard LaserJet printer filter.
        !             5:  * Translate page format and nroff font information
        !             6:  * into HP LaserJet printer escape sequences (PCL).
        !             7:  * Usage: hp [-acflr] [-in] [-pn] [-tn] [file ...]
        !             8:  * Options:
        !             9:  *     -a      Use HP font acute accent character for '\''; default is '\''.
        !            10:  *     -c      Font cartridge not available, use underline for italics.
        !            11:  *     -f      [Archaic] Print pages in normal order; this is now the default.
        !            12:  *     -in     Set left margin (indent) to n; default is 0.
        !            13:  *     -l      Print in landscape mode; default is portrait mode.
        !            14:  *     -pn     Set text length to n; default is NLINES, i.e. 66.
        !            15:  *     -r      Print pages in reverse order (for LaserJet I).
        !            16:  *             [Writes to temp FILE 'output', then readback() rewrites
        !            17:  *             temp file to stdout with pages reversed.]
        !            18:  *     -tn     Set top margin to n; default is 0.
        !            19:  * Exit status is 0 if successful, 1 if error, 2 if interrupted.
        !            20:  *
        !            21:  * Edit history:
        !            22:  *     3/21/85 (jtk) -- Changed so that pages were printed in reverse order,
        !            23:  *             and fixed bug where trailing lines with only
        !            24:  *             non-blank character were deleted.
        !            25:  *     4/09/85 (ella) -- Changed so that pages were printed in
        !            26:  *             the landscape mode with the pitch 16.66, and 
        !            27:  *             fixed bug where underlining in the landscape mode
        !            28:  *             and/or !cartridge wasn't ever terminated.
        !            29:  *             Incorporated rma's fix (-a option) to reflect the
        !            30:  *             manual page and properly process acute accents:
        !            31:  *             default: straight (apostrophe), with -a: slanted
        !            32:  *             (single quote).
        !            33:  *             Included all available options into Usage message.
        !            34:  *     10/31/90 (norm) -- fixed the brain damage regarding
        !            35:  *             formfeeds. Change default to printing pages in
        !            36:  *             order since almost all printers do.  Close any
        !            37:  *             files that we open. Guess that shows how much testing
        !            38:  *             was done by the author...
        !            39:  *     11/7/90 (steve) -- Reordered and rewrote text extensively
        !            40:  *             for legibility, hopefully no substantive changes.
        !            41:  */
        !            42: 
        !            43: #include <stdio.h>
        !            44: #include <signal.h>
        !            45: 
        !            46: extern long    ftell();
        !            47: 
        !            48: /* Miscellany. */
        !            49: #define        VERSION         "1.3"
        !            50: #define        ACCENTACUTE     0xA8
        !            51: #define        ACCENTGRAVE     0xA9
        !            52: #define        LINESZ          512
        !            53: #define        NLINES          66
        !            54: #define        NPAGES          1000
        !            55: #define        USAGEMSG        "Usage: hp [ -acflr ] [ -in ] [ -pn ] [ -tn ] [ file ... ]"
        !            56: 
        !            57: /* Fonts. */
        !            58: #define        ROMAN_F         0               /* all except below means Roman */
        !            59: #define        BOLD_F          1               /* "x\bx" means bold 'x' */
        !            60: #define        ITALIC_F        2               /* "_\bx" means italic '_' */
        !            61: 
        !            62: /* HP Printer Control Language (PCL) commands. */
        !            63: /* These are printf() format strings, some require additional arguments. */
        !            64: #define        HMOVEFWD        "\033&a+%dH"
        !            65: #define        HMOVEBACK       "\033&a-%dH"
        !            66: #define        LANDSCAPE       "\033&l%dO"     /* arg 0==portrait, 1==landscape */
        !            67: #define        LEFTMARGIN      "\033&a%dL"
        !            68: #define        LINESPACING     "\033&l%dD"
        !            69: #define        MOVETOCOL       "\033&a%dC"
        !            70: #define        PAGELENGTH      "\033&l%dP"
        !            71: #define        PITCH16         "\033(s16.66H"  /* pitch 16.66 cpi */
        !            72: #define        RESET           "\033E"
        !            73: #define        STROKEWEIGHT    "\033(s%dB"
        !            74: #define        STYLE           "\033(s%dS"
        !            75: #define        STYLEWEIGHT     "\033(s%ds%dB"
        !            76: #define        TEXTLENGTH      "\033&l%dF"
        !            77: #define        TOPMARGIN       "\033&l%dE"
        !            78: #define        UNDEROFF        "\033&d@"
        !            79: #define        UNDERON         "\033&dD"
        !            80: 
        !            81: /* Forward. */
        !            82: #if    0
        !            83: void   debug();
        !            84: #endif
        !            85: void   done();
        !            86: void   fakebold();
        !            87: void   fatal();
        !            88: int    hasFF();
        !            89: void   initialize();
        !            90: void   newfont();
        !            91: int    nonblank();
        !            92: void   printfile();
        !            93: void   printline();
        !            94: void   readback();
        !            95: void   trap();
        !            96: void   usage();
        !            97: 
        !            98: /* Globals. */
        !            99: int    aflag;                  /* Accent flag                          */
        !           100: char   *argv0;                 /* Command name for error messages      */
        !           101: int    cartridge = 1;          /* Font cartridge is available          */
        !           102: int    font = ROMAN_F;         /* Current font                         */
        !           103: int    landscape;              /* 0 for portrait mode, 1 for landscape */
        !           104: int    leftmargin;             /* Left margin                          */
        !           105: int    linespacing = 6;        /* Vertical lines per inch              */
        !           106: int    nfiles;                 /* Number of files to print             */
        !           107: int    npages;                 /* Number of pages marked on input      */
        !           108: FILE   *output = NULL;         /* FILE containing unreversed pages     */
        !           109: char   page[NLINES][LINESZ];   /* Current page buffer                  */
        !           110: long   pageaddr[NPAGES];       /* Seek pointers to top of output pages */
        !           111: int    quit;                   /* Signal to interrupt program          */
        !           112: int    rflag;                  /* Reverse page order                   */
        !           113: char   tempfile[20];           /* Temporary file name                  */
        !           114: int    textlength = NLINES;    /* Text length -- must satisfy          */
        !           115:                                /*      textlength <= NLINES-topmargin  */
        !           116: int    topmargin;              /* Top margin                           */
        !           117: 
        !           118: main(argc, argv) int argc; char *argv[];
        !           119: {
        !           120:        /* Process arguments. */
        !           121:        argv0 = argv[0];
        !           122:        argc--;
        !           123:        argv++;
        !           124:        while (argc > 0)  {
        !           125:                switch(**argv)  {
        !           126:                case '-':
        !           127:                        switch(*++*argv)  {
        !           128:                        case 'a':
        !           129:                                aflag = 1;
        !           130:                                break;
        !           131:                        case 'c':
        !           132:                                cartridge = 0;
        !           133:                                break;
        !           134:                        case 'f':
        !           135:                                /* Recognized for historical reasons, ignore. */
        !           136:                                break;
        !           137:                        case 'i':
        !           138:                                leftmargin = atoi(++*argv);
        !           139:                                break;
        !           140:                        case 'l':
        !           141:                                landscape = 1;
        !           142:                                linespacing = 8;
        !           143:                                break;
        !           144:                        case 'p':
        !           145:                                textlength = atoi(++*argv);
        !           146:                                break;
        !           147:                        case 'r':
        !           148:                                rflag = 1;
        !           149:                                break;
        !           150:                        case 't':
        !           151:                                topmargin = atoi(++*argv);
        !           152:                                break;
        !           153:                        case 'V':
        !           154:                                fprintf(stderr, "%s: V%s\n", argv0, VERSION);
        !           155:                                break;
        !           156:                        default:
        !           157:                                usage();
        !           158:                                break;
        !           159:                        }
        !           160:                        break;
        !           161:                default:
        !           162:                        if (nfiles++ == 0)
        !           163:                                initialize();
        !           164:                        printfile(*argv);
        !           165:                        break;
        !           166:                }
        !           167:                argv++;
        !           168:                argc--;
        !           169:        }
        !           170: 
        !           171:        /* If no command line files, process stdin. */
        !           172:        if (nfiles == 0) {
        !           173:                initialize();
        !           174:                printfile(NULL);
        !           175:        }
        !           176: 
        !           177:        /* Done. */
        !           178:        if (rflag)
        !           179:                readback();
        !           180:        done(0);
        !           181: }
        !           182: 
        !           183: #if    0
        !           184: /*
        !           185:  * Print debugging output to file "hp.db".
        !           186:  */
        !           187: /* VARARGS */
        !           188: void
        !           189: debug(s) char *s;
        !           190: {
        !           191:        register FILE *fp;
        !           192: 
        !           193:        if ((fp = fopen("hp.db", "ar")) == NULL)
        !           194:                return;
        !           195:        fprintf(fp, "hp: %r\n" &s);
        !           196:        fclose(fp);
        !           197: }
        !           198: #endif
        !           199: 
        !           200: /*
        !           201:  * Finish up.  Remove temporary file if it has been opened, then exit.
        !           202:  */
        !           203: void
        !           204: done(status) int status;
        !           205: {
        !           206:        printf(RESET);
        !           207:        if (output != NULL) {
        !           208:                fclose(output);
        !           209:                if (output != stdout)
        !           210:                        unlink(tempfile);
        !           211:        }
        !           212:        exit(status);
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Fake boldface of given character when font not available.
        !           217:  */
        !           218: void
        !           219: fakebold(c) register int c;
        !           220: {
        !           221:        register int d;
        !           222: 
        !           223:        if (font != ROMAN_F)
        !           224:                newfont(ROMAN_F);               /* terminate previous font */
        !           225:        d = (landscape) ? 7 : 8;                /* decipoint distance */
        !           226:        putc(c, output);                        /* print it */
        !           227:        fprintf(output, MOVETOCOL, -1);         /* move back one column */
        !           228:        fprintf(output, HMOVEFWD, d);           /* and forward d decipoints */
        !           229:        putc(c, output);                        /* print it again */
        !           230:        fprintf(output, HMOVEBACK, d);          /* and move back d decipoints */
        !           231: }
        !           232: 
        !           233: /*
        !           234:  * Print a fatal error message and die.
        !           235:  */
        !           236: /* VARARGS */
        !           237: void
        !           238: fatal(s) char *s;
        !           239: {
        !           240:        fprintf(stderr, "%s: %r\n", argv0, &s);
        !           241:        done(1);
        !           242: }
        !           243: 
        !           244: /*
        !           245:  * Test whether string s contains a formfeed.
        !           246:  */
        !           247: int
        !           248: hasFF(s) register char *s;
        !           249: {
        !           250:        register char c;
        !           251: 
        !           252:        while (c = *s++)
        !           253:                if (c == '\f')
        !           254:                        return 1;
        !           255:        return 0;
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * Set interrupt trap and initialize the printer.
        !           260:  * Open temporary file if rflag is specified,
        !           261:  * otherwise output just goes to stdout.
        !           262:  */
        !           263: void
        !           264: initialize()
        !           265: {
        !           266:        /* Trap SIGINT to set quit flag. */
        !           267:        signal(SIGINT, trap);
        !           268: 
        !           269:        /* HP initialization. */
        !           270:        printf(RESET);
        !           271:        if (landscape)
        !           272:                printf(PITCH16);
        !           273:        printf(LANDSCAPE, landscape);
        !           274:        printf(PAGELENGTH, NLINES);
        !           275:        printf(LINESPACING, linespacing);
        !           276:        printf(TOPMARGIN, topmargin);
        !           277:        printf(TEXTLENGTH, textlength);
        !           278:        printf(LEFTMARGIN, leftmargin);
        !           279: 
        !           280:        /* Initialize output file. */
        !           281:        if (quit)
        !           282:                done(2);
        !           283:        if (rflag) {
        !           284:                sprintf(tempfile, "/tmp/hptmp.%d", getpid());
        !           285:                if ((output = fopen(tempfile, "wr")) == NULL)
        !           286:                        fatal("cannot open temporary file \"%s\"", tempfile);
        !           287:        } else 
        !           288:                output = stdout;
        !           289: }
        !           290: 
        !           291: /* 
        !           292:  * Change to a new font.
        !           293:  * For each of the three fonts (ROMAN_F, BOLD_F, ITALIC_F),
        !           294:  * this routine prints the font escape appropriate to the given configuration.
        !           295:  * There are currently four possible printer configurations:
        !           296:  *     normal  portrait  && cartridge
        !           297:  *     -l      landscape && cartridge
        !           298:  *     -c      portrait  && no cartridge
        !           299:  *     -c -l   landscape && no cartridge
        !           300:  * In the first case, do bold and italic with style and weight changes.
        !           301:  * bold is faked from printline() per-character in the other cases,
        !           302:  * italic is underlined Roman in the other cases.
        !           303:  */
        !           304: void
        !           305: newfont(new) int new;
        !           306: {
        !           307:        static int style = 0;           /* initial style == upright */
        !           308:        static int weight = 0;          /* initial weight == medium */
        !           309:        static int under = 0;           /* initial underline state == off */
        !           310:        register int newstyle, newweight, newunder;
        !           311: 
        !           312:        if (font == new)
        !           313:                return;                                 /* unchanged */
        !           314:        font = new;
        !           315:        newstyle = newweight = newunder = 0;            /* defaults */
        !           316:        switch(font) {
        !           317:        case ROMAN_F:
        !           318:                break;                                  /* upright medium */
        !           319:        case BOLD_F:
        !           320:                newweight = 1;                          /* bold */
        !           321:                break;
        !           322:        case ITALIC_F:
        !           323:                if (cartridge && !landscape) {
        !           324:                        newstyle = 1;                   /* italic */
        !           325:                        newweight = -1;                 /* weight -1 */
        !           326:                } else
        !           327:                        newunder = 1;           /* underlined upright medium */
        !           328:                break;
        !           329:        default:
        !           330:                fatal("unrecognized font type %d", font);
        !           331:                break;
        !           332:        }
        !           333:        if (under != newunder) {
        !           334:                under = newunder;
        !           335:                fprintf(output, (under) ? UNDERON : UNDEROFF);
        !           336:        }
        !           337:        if (style != newstyle && weight != newweight) {
        !           338:                style = newstyle;
        !           339:                weight = newweight;
        !           340:                fprintf(output, STYLEWEIGHT, style, weight);
        !           341:        } else if (style != newstyle) {
        !           342:                style = newstyle;
        !           343:                fprintf(output, STYLE, style);
        !           344:        } else if (weight != newweight) {
        !           345:                weight = newweight;
        !           346:                fprintf(output, STROKEWEIGHT, weight);
        !           347:        }
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * Return 1 if line s is not blank.
        !           352:  */
        !           353: int
        !           354: nonblank(s) register char *s;
        !           355: {
        !           356:        register int c;
        !           357: 
        !           358:        while ((c = *s) == ' ' || c == '\t')
        !           359:                s++;
        !           360:        return (c != '\0' && c != '\n' && c != '\f');
        !           361: }
        !           362: 
        !           363: /*
        !           364:  * Print a file.
        !           365:  * NULL means stdin.
        !           366:  */
        !           367: void
        !           368: printfile(file) char *file;
        !           369: {
        !           370:        FILE *fp;
        !           371:        register int i;
        !           372:        int last, end;
        !           373: 
        !           374:        if (file == NULL)
        !           375:                fp = stdin;
        !           376:        else if ((fp = fopen(file, "r")) == NULL)
        !           377:                fatal("cannot open file \"%s\"", file);
        !           378: 
        !           379:        if (font != ROMAN_F)
        !           380:                newfont(ROMAN_F);
        !           381:        for (end = 0; !end; ) {
        !           382:                if (rflag) {
        !           383:                        if (npages >= NPAGES)
        !           384:                                fatal("more than %d pages", NPAGES);
        !           385:                        pageaddr[npages++] = ftell(output);
        !           386:                }
        !           387:                for (i = 0; i < NLINES; i++) {
        !           388:                        if (fgets(&page[i][0], LINESZ, fp) == NULL) {
        !           389:                                if (i == 0) {
        !           390:                                        npages--;       /* last page empty */
        !           391:                                        return;
        !           392:                                }
        !           393:                                end = 1;
        !           394:                                break;
        !           395:                        } else if (hasFF(page[i])) {    /* formfeed seen */
        !           396:                                ++i;
        !           397:                                break;
        !           398:                        }
        !           399:                }
        !           400:                for (last = --i; last >= 0; --last)
        !           401:                        if (nonblank(page[last]))
        !           402:                                break;                  /* nonblank line */
        !           403:                for (i = 0; i <= last; i++)
        !           404:                        printline(page[i]);
        !           405:                putc('\r', output);
        !           406:                if (last < NLINES - 1)
        !           407:                        putc('\f', output);
        !           408:        }
        !           409:        if (file != NULL)
        !           410:                fclose(fp);
        !           411: }
        !           412: 
        !           413: /*
        !           414:  * Print one line, substituting special characters from the HP character set.
        !           415:  */
        !           416: void
        !           417: printline(cp) register char *cp;
        !           418: {
        !           419:        register int c1, c2, new;
        !           420:        char *s;
        !           421: 
        !           422:        /* Replace accents with equivalents from the extended character set. */
        !           423:        for (s = cp; *s != '\0'; ++s) {
        !           424:                if (*s == '\'' && aflag)
        !           425:                        *s = ACCENTACUTE;
        !           426:                else if (*s == '`')
        !           427:                        *s = ACCENTGRAVE;
        !           428:        }
        !           429: 
        !           430:        /* Look for nroff font sequences. */
        !           431:        while ((c1 = *cp++) != '\0') {
        !           432: 
        !           433:                /* Check for the interrupt signal. */
        !           434:                if (quit)
        !           435:                        done(2);
        !           436: 
        !           437:                /* By default, Roman c1 gets printed at the end of this loop. */
        !           438:                new = ROMAN_F;
        !           439:                if (c1 == '\f')
        !           440:                        return;         /* chars after FF on line get eaten */
        !           441:                else if (c1 == ' ' || c1 == '\t')
        !           442:                        new = font;     /* no font change on whitespace */
        !           443:                else if (c1 == '_') {
        !           444:                        if ((c2 = *cp++) == '\b') {
        !           445:                                /* "_\bx" means italic x. */
        !           446:                                new = ITALIC_F;
        !           447:                                c1 = *cp++;
        !           448:                        } else
        !           449:                                cp--;           /* put back c2 */
        !           450:                } else if ((c2 = *cp++) == '\b') {
        !           451:                        if ((c2 = *cp++) == c1) {
        !           452:                                /* "x\bx" means bold x. */
        !           453:                                if (!cartridge || landscape) {
        !           454:                                        fakebold(c1);   /* fake it */
        !           455:                                        continue;
        !           456:                                } else
        !           457:                                        new = BOLD_F;
        !           458:                        } else
        !           459:                                cp -= 2;        /* put back '\b' and c2 */
        !           460:                } else
        !           461:                        cp--;                   /* put back c2 */
        !           462:                if (font != new)
        !           463:                        newfont(new);           /* font change */
        !           464:                putc(c1, output);               /* print c1 in new font */
        !           465:        }
        !           466: }
        !           467: 
        !           468: /*
        !           469:  * Copy the temporary file to stdout with the pages in reverse order.
        !           470:  */
        !           471: void
        !           472: readback()
        !           473: {
        !           474:        char c;
        !           475: 
        !           476:        while (--npages >= 0) {
        !           477:                /* Check for interrupt signal at each page. */
        !           478:                if (quit)
        !           479:                        done(2);
        !           480:                fseek(output, pageaddr[npages], 0);
        !           481:                while ((c = getc(output)) != '\f')
        !           482:                        putchar(c);
        !           483:                putchar(c);
        !           484:        }
        !           485: }
        !           486: 
        !           487: /*
        !           488:  * Set quit flag when interrupt signal is received.
        !           489:  */
        !           490: void
        !           491: trap()
        !           492: {
        !           493:        quit = 1;
        !           494: }
        !           495: 
        !           496: /*
        !           497:  * Print a usage message and die.
        !           498:  */
        !           499: void
        !           500: usage()
        !           501: {
        !           502:        fprintf(stderr, "%s\n", USAGEMSG);
        !           503:        exit(1);
        !           504: }
        !           505: 
        !           506: /* end of hp.c */

unix.superglobalmegacorp.com

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