17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
59a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License").
69a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
229a70fc3bSMark J. Nelson * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * lwlp - Convert ASCII text to PostScript
287c478bd9Sstevel@tonic-gate *
297c478bd9Sstevel@tonic-gate * Usage:
307c478bd9Sstevel@tonic-gate * lwlp [-{2|4|8}] [-p] [-L] [-r] [-n#] [-l#|-w#] [-c#] [-t#]
317c478bd9Sstevel@tonic-gate * [-hstring] [-Bstring] [-Istring] [-Xstring] [-Pfile] [file ...]
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * Options:
347c478bd9Sstevel@tonic-gate * -{1|2|4|8} print multiple logical pages per page
357c478bd9Sstevel@tonic-gate * -d debug, don't remove temporary file
367c478bd9Sstevel@tonic-gate * -L specify Landscape instead of Portrait
377c478bd9Sstevel@tonic-gate * -p filter input through pr
387c478bd9Sstevel@tonic-gate * -r toggle page reversal flag (default is off)
397c478bd9Sstevel@tonic-gate * -e elide unchanged functions
407c478bd9Sstevel@tonic-gate * -n# number with numberwidth digits
417c478bd9Sstevel@tonic-gate * -l# specify number of lines/logical page, default 66
427c478bd9Sstevel@tonic-gate * -w# specify number of columns
437c478bd9Sstevel@tonic-gate * -c# specify number of copies
447c478bd9Sstevel@tonic-gate * -t# specify tab spacing
457c478bd9Sstevel@tonic-gate * -htext specify header text
467c478bd9Sstevel@tonic-gate * -Btext specify bold font selector
477c478bd9Sstevel@tonic-gate * -Itext specify italic font selector
487c478bd9Sstevel@tonic-gate * -Xtext specify bold-italic font selector
497c478bd9Sstevel@tonic-gate * -Gtext specify graying selector
507c478bd9Sstevel@tonic-gate * -Pfile specify different Postscript prologue file
517c478bd9Sstevel@tonic-gate *
527c478bd9Sstevel@tonic-gate * If no files are specified, stdin is used.
537c478bd9Sstevel@tonic-gate * Form feeds handled
547c478bd9Sstevel@tonic-gate * Backspacing with underlining (or overprinting) works
557c478bd9Sstevel@tonic-gate * The output conforms to Adobe 2.0
567c478bd9Sstevel@tonic-gate *
577c478bd9Sstevel@tonic-gate * Problems:
587c478bd9Sstevel@tonic-gate * - assumes fixed-width (non-proportional) font in some places
597c478bd9Sstevel@tonic-gate * - can't back up (using backspaces) over tabs
607c478bd9Sstevel@tonic-gate * - assumes 8.5 x 11.0 paper
617c478bd9Sstevel@tonic-gate * - uses logical page with aspect ratio of 3 * 4
627c478bd9Sstevel@tonic-gate *
637c478bd9Sstevel@tonic-gate */
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate #define USAGE1 "[-{1|2|4|8}] [-p] [-L] [-r] [-n<numberwidth]"
667c478bd9Sstevel@tonic-gate #define USAGE2 "[-l<lines>|-w<columns>] [-c<count>] [-t<tabs>]"
677c478bd9Sstevel@tonic-gate #define USAGE3 "[-hstring] [-Bstring] [-Istring] [-Xstring] [-Gstring]"
687c478bd9Sstevel@tonic-gate #define USAGE4 "[-Pfile] [file ...]"
693c2f5c48Sjwadams #define USAGE6 "[-hstring] [-e] [-y comment] oldfile newfile"
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate #include <stdio.h>
727c478bd9Sstevel@tonic-gate #include <string.h>
737c478bd9Sstevel@tonic-gate #include <stdlib.h>
747c478bd9Sstevel@tonic-gate #include <sys/file.h>
757c478bd9Sstevel@tonic-gate #include <ctype.h>
767c478bd9Sstevel@tonic-gate #include <pwd.h>
777c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
787c478bd9Sstevel@tonic-gate #include <sys/stat.h>
797c478bd9Sstevel@tonic-gate #include <unistd.h>
807c478bd9Sstevel@tonic-gate #include <sys/types.h>
817c478bd9Sstevel@tonic-gate #include <time.h>
827c478bd9Sstevel@tonic-gate #include <stdarg.h>
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate * Configurable...
867c478bd9Sstevel@tonic-gate * BUFOUT should be fairly large
877c478bd9Sstevel@tonic-gate */
887c478bd9Sstevel@tonic-gate #define BUFIN 1024 /* maximum length of an input line */
897c478bd9Sstevel@tonic-gate #define BUFOUT (BUFIN * 5)
907c478bd9Sstevel@tonic-gate #define MAXPAGES 10000
917c478bd9Sstevel@tonic-gate #define REVERSE_OFF 0
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate #define DEFAULT_PAPER_HEIGHT 11.0
947c478bd9Sstevel@tonic-gate #define DEFAULT_PAPER_WIDTH 8.50
957c478bd9Sstevel@tonic-gate #define DEFAULT_PAGE_HEIGHT 10.0
967c478bd9Sstevel@tonic-gate #define DEFAULT_PAGE_WIDTH 7.50
977c478bd9Sstevel@tonic-gate #define DEFAULT_LINES_PER_PAGE 66
987c478bd9Sstevel@tonic-gate #define DEFAULT_TAB_SIZE 8
997c478bd9Sstevel@tonic-gate static char *default_font = "Courier";
1007c478bd9Sstevel@tonic-gate static char *default_font_bold = "Courier-Bold";
1017c478bd9Sstevel@tonic-gate static char *default_font_italic = "Courier-Oblique";
1027c478bd9Sstevel@tonic-gate static char *default_font_bold_italic = "Courier-BoldOblique";
1037c478bd9Sstevel@tonic-gate static char *select_default_font = "FRN";
1047c478bd9Sstevel@tonic-gate static char *select_default_font_bold = "FRB";
1057c478bd9Sstevel@tonic-gate static char *select_default_font_italic = "FIN";
1067c478bd9Sstevel@tonic-gate static char *select_default_font_bold_italic = "FIB";
1077c478bd9Sstevel@tonic-gate #define DEFAULT_FONT select_default_font
1087c478bd9Sstevel@tonic-gate #define DEFAULT_FONT_BOLD select_default_font_bold
1097c478bd9Sstevel@tonic-gate #define DEFAULT_FONT_ITALIC select_default_font_italic
1107c478bd9Sstevel@tonic-gate #define DEFAULT_FONT_BOLD_ITALIC select_default_font_bold_italic
1117c478bd9Sstevel@tonic-gate #define DEFAULT_CHAR_WIDTH (.6)
1127c478bd9Sstevel@tonic-gate #define DEFAULT_SPACES_AFTER_NUMBER 1
1137c478bd9Sstevel@tonic-gate #define DEFAULT_DESCENDER_FRACTION 0.3
1147c478bd9Sstevel@tonic-gate #define LWLP "lwlp"
1157c478bd9Sstevel@tonic-gate #define CODEREVIEW "codereview"
1167c478bd9Sstevel@tonic-gate #define END_C_FUNCTION '}'
1177c478bd9Sstevel@tonic-gate #define END_ASM_FUNCTION "SET_SIZE("
1187c478bd9Sstevel@tonic-gate static char *banner =
1197c478bd9Sstevel@tonic-gate "**********************************************************";
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate /*
1227c478bd9Sstevel@tonic-gate * PostScript command strings
1237c478bd9Sstevel@tonic-gate */
1247c478bd9Sstevel@tonic-gate #define LINETO "lineto"
1257c478bd9Sstevel@tonic-gate #define NEWPATH "newpath"
1267c478bd9Sstevel@tonic-gate #define SETLINEWIDTH "setlinewidth"
1277c478bd9Sstevel@tonic-gate #define STROKE "stroke"
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate * PostScript command strings defined in the prologue file
1307c478bd9Sstevel@tonic-gate */
1317c478bd9Sstevel@tonic-gate #define BACKSPACE "B"
1327c478bd9Sstevel@tonic-gate #define MOVETO "M" /* x y */
1337c478bd9Sstevel@tonic-gate #define SHOW "S" /* string */
1347c478bd9Sstevel@tonic-gate #define TAB "T" /* spaces */
1357c478bd9Sstevel@tonic-gate #define ZEROMOVETO "Z" /* y */
1367c478bd9Sstevel@tonic-gate #define SELECT_FONT "SFT" /* size font */
1377c478bd9Sstevel@tonic-gate #define SET_WIDTHS "SWT"
1387c478bd9Sstevel@tonic-gate #define START_PAGE "SPG" /* angle scale x y */
1397c478bd9Sstevel@tonic-gate #define END_PAGE "EPG"
1407c478bd9Sstevel@tonic-gate #define FLUSH_PAGE "FPG" /* ncopies */
1417c478bd9Sstevel@tonic-gate #define SHADE "SHD" /* x0 y0 x1 y1 */
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate * Conformance requires that no PostScript line exceed 256 characters
1457c478bd9Sstevel@tonic-gate */
1467c478bd9Sstevel@tonic-gate #define POINTS_PER_INCH 72
1477c478bd9Sstevel@tonic-gate #define MAX_OUTPUT_LINE_LENGTH 256
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate #define START_X 0 /* position of start of each line */
1507c478bd9Sstevel@tonic-gate #define THREE_HOLE_X 1.0 /* portrait x offset (inches) 3 hole */
1517c478bd9Sstevel@tonic-gate #define THREE_HOLE_Y 0.5 /* landscape y offset (inches) 3 hole */
1527c478bd9Sstevel@tonic-gate #define RULE_WIDTH 0.25 /* width in units of paging rules */
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate static struct print_state {
1557c478bd9Sstevel@tonic-gate int page_count;
1567c478bd9Sstevel@tonic-gate int logical_page_count;
1577c478bd9Sstevel@tonic-gate int lineno;
1587c478bd9Sstevel@tonic-gate long offset;
1597c478bd9Sstevel@tonic-gate float row;
1607c478bd9Sstevel@tonic-gate char *font;
1617c478bd9Sstevel@tonic-gate } current, saved;
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate struct format_state {
1647c478bd9Sstevel@tonic-gate int numberwidth, linenumber, altlinenumber;
1657c478bd9Sstevel@tonic-gate int makegray;
1667c478bd9Sstevel@tonic-gate char *font;
1677c478bd9Sstevel@tonic-gate };
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate static int change_seen, dots_inserted, in_change, old_stuff, makegray;
1707c478bd9Sstevel@tonic-gate static int lines_per_page;
1717c478bd9Sstevel@tonic-gate static int columns;
1727c478bd9Sstevel@tonic-gate static float point_size;
1737c478bd9Sstevel@tonic-gate static int start_x, start_y, end_x;
1747c478bd9Sstevel@tonic-gate static int landscape, rot_text;
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate static int ncopies;
1777c478bd9Sstevel@tonic-gate static int tabstop;
1787c478bd9Sstevel@tonic-gate static int reverse;
1797c478bd9Sstevel@tonic-gate static int elide;
1807c478bd9Sstevel@tonic-gate static int usetmp;
1817c478bd9Sstevel@tonic-gate static int dflag, lflag, pflag, vflag, wflag;
1827c478bd9Sstevel@tonic-gate static int numberwidth, linenumber, altlinenumber;
1837c478bd9Sstevel@tonic-gate static int boldlength, itlclength, bitclength, graylength;
1847c478bd9Sstevel@tonic-gate static char *boldstring, *itlcstring, *bitcstring, *graystring;
1857c478bd9Sstevel@tonic-gate #define HEADER_EXPLICIT 1
1867c478bd9Sstevel@tonic-gate #define HEADER_IMPLICIT 2
1877c478bd9Sstevel@tonic-gate static int header = HEADER_IMPLICIT;
1887c478bd9Sstevel@tonic-gate static char *headerstring;
1897c478bd9Sstevel@tonic-gate static char *bannerfile;
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate static char bufin[BUFIN]; /* input buffer */
1927c478bd9Sstevel@tonic-gate static char bufout[BUFOUT]; /* output buffer */
1937c478bd9Sstevel@tonic-gate static long *page_map; /* offset of first byte of each page */
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate static char *username, *hostname, *currentdate;
1963c2f5c48Sjwadams static char *comment;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate static void preamble(void);
1997c478bd9Sstevel@tonic-gate static void postamble(void);
2007c478bd9Sstevel@tonic-gate static void setcurrentfont(char *, FILE *);
2017c478bd9Sstevel@tonic-gate static void savestate(FILE *);
2027c478bd9Sstevel@tonic-gate static void restorestate(FILE *);
2037c478bd9Sstevel@tonic-gate static void save_format_state(struct format_state *);
2047c478bd9Sstevel@tonic-gate static void printfile(FILE *);
2057c478bd9Sstevel@tonic-gate static int printpage(FILE *, FILE *);
2067c478bd9Sstevel@tonic-gate static int startpage(FILE *);
2077c478bd9Sstevel@tonic-gate static void endpage(FILE *);
2087c478bd9Sstevel@tonic-gate static void copypage(FILE *, long, long);
2097c478bd9Sstevel@tonic-gate static void process_elide(FILE *);
2107c478bd9Sstevel@tonic-gate static void setheaderfile(char *);
2117c478bd9Sstevel@tonic-gate static void restore_format_state(struct format_state *, FILE *);
2127c478bd9Sstevel@tonic-gate static void flushpage(FILE *);
2137c478bd9Sstevel@tonic-gate static void setuppage(FILE *);
2147c478bd9Sstevel@tonic-gate static void reversepages(FILE *);
2157c478bd9Sstevel@tonic-gate static void proc(char *, FILE *);
2167c478bd9Sstevel@tonic-gate static void setup(void);
2177c478bd9Sstevel@tonic-gate static int printbanner(char *, FILE *);
2187c478bd9Sstevel@tonic-gate static char *fgetline(char *, int, FILE *);
2197c478bd9Sstevel@tonic-gate static void fatal(char *fmt, ...);
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate static char *prologue;
2227c478bd9Sstevel@tonic-gate static char *progname;
2237c478bd9Sstevel@tonic-gate static int iscodereview;
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate static char *default_prologue[] = {
2267c478bd9Sstevel@tonic-gate "%%EndComments\n",
2277c478bd9Sstevel@tonic-gate "%\n",
2287c478bd9Sstevel@tonic-gate "% PostScript Prologue for lwlp LaserWriter Line Printer\n",
2297c478bd9Sstevel@tonic-gate "%\n",
2307c478bd9Sstevel@tonic-gate "/SFT {findfont exch scalefont setfont}bind def\n",
2317c478bd9Sstevel@tonic-gate "/SWT {( ) stringwidth pop dup /W exch def neg /NW exch def}bind def\n",
2327c478bd9Sstevel@tonic-gate "/SPG {/SV save def translate dup scale rotate}bind def\n",
2337c478bd9Sstevel@tonic-gate "/EPG {SV restore}bind def\n",
2347c478bd9Sstevel@tonic-gate "/FPG {/#copies exch def showpage}bind def\n",
2357c478bd9Sstevel@tonic-gate "/B {NW 0 rmoveto}def\n",
2367c478bd9Sstevel@tonic-gate "/M /moveto load def\n",
2377c478bd9Sstevel@tonic-gate "/T {W mul 0 rmoveto}def\n",
2387c478bd9Sstevel@tonic-gate "/S /show load def\n",
2397c478bd9Sstevel@tonic-gate "/Z {0 exch moveto}bind def\n",
2407c478bd9Sstevel@tonic-gate "/SHD {save 5 1 roll % S x1 y1 x0 y0\n",
2417c478bd9Sstevel@tonic-gate " 2 copy moveto % S x1 y1 x0 y0\n",
2427c478bd9Sstevel@tonic-gate " 3 index exch lineto % S x1 y1 x0\n",
2437c478bd9Sstevel@tonic-gate " 3 -1 roll 2 index lineto % S y1 x0\n",
2447c478bd9Sstevel@tonic-gate " exch lineto % S\n",
2457c478bd9Sstevel@tonic-gate " 0.95 setgray fill % S\n",
2467c478bd9Sstevel@tonic-gate " restore}def\n",
2477c478bd9Sstevel@tonic-gate "%%EndProlog\n",
2487c478bd9Sstevel@tonic-gate NULL
2497c478bd9Sstevel@tonic-gate };
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate struct layout {
2527c478bd9Sstevel@tonic-gate float scale;
2537c478bd9Sstevel@tonic-gate int pages, page_rows, page_cols;
2547c478bd9Sstevel@tonic-gate int rotation;
2557c478bd9Sstevel@tonic-gate };
2567c478bd9Sstevel@tonic-gate static struct layout *layoutp;
2577c478bd9Sstevel@tonic-gate static struct layout layout1 = { 1.000000, 1, 1, 1, 0 };
2587c478bd9Sstevel@tonic-gate static struct layout layout2 = { 0.666666, 2, 2, 1, 90 };
2597c478bd9Sstevel@tonic-gate static struct layout layout4 = { 0.500000, 4, 2, 2, 0 };
2607c478bd9Sstevel@tonic-gate static struct layout layout8 = { 0.333333, 8, 4, 2, 90 };
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate static int box_width, box_height;
2637c478bd9Sstevel@tonic-gate static int gap_width, gap_height;
2647c478bd9Sstevel@tonic-gate static int margin_x, margin_y;
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate static struct position {
2677c478bd9Sstevel@tonic-gate int base_x;
2687c478bd9Sstevel@tonic-gate int base_y;
2697c478bd9Sstevel@tonic-gate } positions[8];
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)2727c478bd9Sstevel@tonic-gate main(int argc, char **argv)
2737c478bd9Sstevel@tonic-gate {
2747c478bd9Sstevel@tonic-gate int ch, i, j, first_file;
2757c478bd9Sstevel@tonic-gate char *pc;
2767c478bd9Sstevel@tonic-gate FILE *infile;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate if ((pc = strrchr(argv[0], '/')) != NULL)
2797c478bd9Sstevel@tonic-gate progname = pc + 1;
2807c478bd9Sstevel@tonic-gate else
2817c478bd9Sstevel@tonic-gate progname = argv[0];
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate lines_per_page = DEFAULT_LINES_PER_PAGE;
2847c478bd9Sstevel@tonic-gate layoutp = &layout1;
2857c478bd9Sstevel@tonic-gate tabstop = DEFAULT_TAB_SIZE;
2867c478bd9Sstevel@tonic-gate current.page_count = 0;
2877c478bd9Sstevel@tonic-gate ncopies = 1;
2887c478bd9Sstevel@tonic-gate reverse = REVERSE_OFF;
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate /*LINTED*/
2917c478bd9Sstevel@tonic-gate if (iscodereview = strncmp(progname, CODEREVIEW,
2927c478bd9Sstevel@tonic-gate sizeof (CODEREVIEW) - 1) == 0) {
2937c478bd9Sstevel@tonic-gate layoutp = &layout2;
2947c478bd9Sstevel@tonic-gate numberwidth = 4;
2957c478bd9Sstevel@tonic-gate columns = 85; /* extra space for numbering */
2967c478bd9Sstevel@tonic-gate wflag = -1;
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate while ((ch = getopt(argc, argv,
3003c2f5c48Sjwadams "1248B:c:deG:h:I:l:Ln:P:prt:vw:X:y:")) != -1) {
3017c478bd9Sstevel@tonic-gate switch (ch) {
3027c478bd9Sstevel@tonic-gate case '1':
3037c478bd9Sstevel@tonic-gate layoutp = &layout1;
3047c478bd9Sstevel@tonic-gate break;
3057c478bd9Sstevel@tonic-gate case '2':
3067c478bd9Sstevel@tonic-gate layoutp = &layout2;
3077c478bd9Sstevel@tonic-gate break;
3087c478bd9Sstevel@tonic-gate case '4':
3097c478bd9Sstevel@tonic-gate layoutp = &layout4;
3107c478bd9Sstevel@tonic-gate break;
3117c478bd9Sstevel@tonic-gate case '8':
3127c478bd9Sstevel@tonic-gate layoutp = &layout8;
3137c478bd9Sstevel@tonic-gate break;
3147c478bd9Sstevel@tonic-gate case 'B':
3157c478bd9Sstevel@tonic-gate boldlength = strlen(optarg);
3167c478bd9Sstevel@tonic-gate boldstring = malloc((size_t)(boldlength + 1));
3177c478bd9Sstevel@tonic-gate (void) strcpy(boldstring, optarg);
3187c478bd9Sstevel@tonic-gate break;
3197c478bd9Sstevel@tonic-gate case 'c':
3207c478bd9Sstevel@tonic-gate ncopies = atof(optarg);
3217c478bd9Sstevel@tonic-gate if (ncopies <= 0) {
3227c478bd9Sstevel@tonic-gate fatal("number of copies must be > 0");
3237c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate break;
3267c478bd9Sstevel@tonic-gate case 'd':
3277c478bd9Sstevel@tonic-gate dflag = 1;
3287c478bd9Sstevel@tonic-gate break;
3297c478bd9Sstevel@tonic-gate case 'e':
3307c478bd9Sstevel@tonic-gate elide = 1;
3317c478bd9Sstevel@tonic-gate break;
3327c478bd9Sstevel@tonic-gate case 'G':
3337c478bd9Sstevel@tonic-gate graylength = strlen(optarg);
3347c478bd9Sstevel@tonic-gate graystring = malloc((size_t)(graylength + 1));
3357c478bd9Sstevel@tonic-gate (void) strcpy(graystring, optarg);
3367c478bd9Sstevel@tonic-gate break;
3377c478bd9Sstevel@tonic-gate case 'h':
3387c478bd9Sstevel@tonic-gate header = HEADER_EXPLICIT;
3397c478bd9Sstevel@tonic-gate i = strlen(optarg);
3407c478bd9Sstevel@tonic-gate headerstring = malloc((size_t)(i + 1));
3417c478bd9Sstevel@tonic-gate (void) strcpy(headerstring, optarg);
3427c478bd9Sstevel@tonic-gate if (strcmp(headerstring, "-") == 0)
3437c478bd9Sstevel@tonic-gate header = HEADER_IMPLICIT;
3447c478bd9Sstevel@tonic-gate break;
3457c478bd9Sstevel@tonic-gate case 'I':
3467c478bd9Sstevel@tonic-gate itlclength = strlen(optarg);
3477c478bd9Sstevel@tonic-gate itlcstring = malloc((size_t)(itlclength + 1));
3487c478bd9Sstevel@tonic-gate (void) strcpy(itlcstring, optarg);
3497c478bd9Sstevel@tonic-gate break;
3507c478bd9Sstevel@tonic-gate case 'l':
3517c478bd9Sstevel@tonic-gate lines_per_page = atoi(optarg);
3527c478bd9Sstevel@tonic-gate if (lines_per_page < 1) {
3537c478bd9Sstevel@tonic-gate fatal("invalid number of lines/page");
3547c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate lflag = 1;
3577c478bd9Sstevel@tonic-gate if (wflag > 0) {
3587c478bd9Sstevel@tonic-gate fatal("can't have both -l and -w");
3597c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate wflag = 0;
3627c478bd9Sstevel@tonic-gate break;
3637c478bd9Sstevel@tonic-gate case 'L':
3647c478bd9Sstevel@tonic-gate landscape = 1;
3657c478bd9Sstevel@tonic-gate break;
3667c478bd9Sstevel@tonic-gate case 'm':
3677c478bd9Sstevel@tonic-gate break;
3687c478bd9Sstevel@tonic-gate case 'n':
3697c478bd9Sstevel@tonic-gate numberwidth = atoi(optarg);
3707c478bd9Sstevel@tonic-gate if (numberwidth < 2) {
3717c478bd9Sstevel@tonic-gate fatal("invalid numbering width");
3727c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate break;
3757c478bd9Sstevel@tonic-gate case 'P':
3767c478bd9Sstevel@tonic-gate prologue = optarg;
3777c478bd9Sstevel@tonic-gate break;
3787c478bd9Sstevel@tonic-gate case 'p':
3797c478bd9Sstevel@tonic-gate pflag = 1;
3807c478bd9Sstevel@tonic-gate break;
3817c478bd9Sstevel@tonic-gate case 'r':
3827c478bd9Sstevel@tonic-gate reverse = !reverse;
3837c478bd9Sstevel@tonic-gate break;
3847c478bd9Sstevel@tonic-gate case 't':
3857c478bd9Sstevel@tonic-gate tabstop = atoi(optarg);
3867c478bd9Sstevel@tonic-gate if (tabstop < 1) {
3877c478bd9Sstevel@tonic-gate fatal("negative tabstop");
3887c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate break;
3917c478bd9Sstevel@tonic-gate case 'v':
3927c478bd9Sstevel@tonic-gate vflag = 1;
3937c478bd9Sstevel@tonic-gate break;
3947c478bd9Sstevel@tonic-gate case 'w':
3957c478bd9Sstevel@tonic-gate columns = atoi(optarg);
3967c478bd9Sstevel@tonic-gate if (columns < 1) {
3977c478bd9Sstevel@tonic-gate fatal("invalid number of columns");
3987c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate wflag = 1;
4017c478bd9Sstevel@tonic-gate if (lflag) {
4027c478bd9Sstevel@tonic-gate fatal("can't have both -l and -w");
4037c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate break;
4067c478bd9Sstevel@tonic-gate case 'X':
4077c478bd9Sstevel@tonic-gate bitclength = strlen(optarg);
4087c478bd9Sstevel@tonic-gate bitcstring = malloc((size_t)(bitclength + 1));
4097c478bd9Sstevel@tonic-gate (void) strcpy(bitcstring, optarg);
4107c478bd9Sstevel@tonic-gate break;
4113c2f5c48Sjwadams case 'y':
4123c2f5c48Sjwadams comment = optarg;
4133c2f5c48Sjwadams break;
4147c478bd9Sstevel@tonic-gate default:
4157c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
4167c478bd9Sstevel@tonic-gate "usage: %s %s\n\t%s\n\t%s\n\t%s\n",
4177c478bd9Sstevel@tonic-gate iscodereview ? LWLP : progname,
4187c478bd9Sstevel@tonic-gate USAGE1, USAGE2, USAGE3, USAGE4);
4197c478bd9Sstevel@tonic-gate if (iscodereview)
4207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s [%s flags] %s\n",
4217c478bd9Sstevel@tonic-gate CODEREVIEW, LWLP, USAGE6);
4227c478bd9Sstevel@tonic-gate exit(1);
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate if (elide && !iscodereview) {
4277c478bd9Sstevel@tonic-gate fatal("-e option valid only with codereview");
4287c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate usetmp = reverse || elide;
4317c478bd9Sstevel@tonic-gate /* allocate page_map if we need one */
4327c478bd9Sstevel@tonic-gate if (reverse) {
4337c478bd9Sstevel@tonic-gate page_map = malloc((size_t)(MAXPAGES * sizeof (long *)));
4347c478bd9Sstevel@tonic-gate if (page_map == NULL) {
4357c478bd9Sstevel@tonic-gate fatal("unable to allocate memory for page reversal");
4367c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate * Check that all files are readable
4427c478bd9Sstevel@tonic-gate * This is so that no output at all is produced if any file is not
4437c478bd9Sstevel@tonic-gate * readable in case the output is being piped to a printer
4447c478bd9Sstevel@tonic-gate */
4457c478bd9Sstevel@tonic-gate first_file = optind;
4467c478bd9Sstevel@tonic-gate for (j = first_file; j < argc; j++) {
4477c478bd9Sstevel@tonic-gate if (access(argv[j], R_OK) == -1 && !(iscodereview &&
4487c478bd9Sstevel@tonic-gate strcmp(argv[j], "-") == 0)) {
4497c478bd9Sstevel@tonic-gate fatal("cannot access %s", argv[j]);
4507c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate if (iscodereview && (first_file + 2) != argc) {
4547c478bd9Sstevel@tonic-gate fatal("codereview: need old and new file");
4557c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate /* compute logical point size, logical dimensions */
4597c478bd9Sstevel@tonic-gate if (!landscape) {
4607c478bd9Sstevel@tonic-gate rot_text = layoutp->rotation;
4617c478bd9Sstevel@tonic-gate start_y = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH;
4627c478bd9Sstevel@tonic-gate start_x = START_X;
4637c478bd9Sstevel@tonic-gate end_x = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH;
4647c478bd9Sstevel@tonic-gate if (wflag) {
4657c478bd9Sstevel@tonic-gate point_size = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH /
4667c478bd9Sstevel@tonic-gate ((columns + 0.5) * DEFAULT_CHAR_WIDTH);
4677c478bd9Sstevel@tonic-gate lines_per_page = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH /
4687c478bd9Sstevel@tonic-gate point_size;
4697c478bd9Sstevel@tonic-gate } else {
4707c478bd9Sstevel@tonic-gate point_size = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH /
4717c478bd9Sstevel@tonic-gate (lines_per_page + 0.5);
4727c478bd9Sstevel@tonic-gate columns = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH /
4737c478bd9Sstevel@tonic-gate (point_size * DEFAULT_CHAR_WIDTH);
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate } else {
4767c478bd9Sstevel@tonic-gate rot_text = 90 - layoutp->rotation;
4777c478bd9Sstevel@tonic-gate start_y = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH;
4787c478bd9Sstevel@tonic-gate start_x = START_X;
4797c478bd9Sstevel@tonic-gate end_x = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH;
4807c478bd9Sstevel@tonic-gate if (wflag) {
4817c478bd9Sstevel@tonic-gate point_size = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH /
4827c478bd9Sstevel@tonic-gate ((columns + 0.5) * DEFAULT_CHAR_WIDTH);
4837c478bd9Sstevel@tonic-gate lines_per_page = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH /
4847c478bd9Sstevel@tonic-gate point_size;
4857c478bd9Sstevel@tonic-gate } else {
4867c478bd9Sstevel@tonic-gate point_size = DEFAULT_PAGE_WIDTH * POINTS_PER_INCH /
4877c478bd9Sstevel@tonic-gate (lines_per_page + 0.5);
4887c478bd9Sstevel@tonic-gate columns = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH /
4897c478bd9Sstevel@tonic-gate (point_size * DEFAULT_CHAR_WIDTH);
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate
4937c478bd9Sstevel@tonic-gate box_height = DEFAULT_PAGE_HEIGHT * POINTS_PER_INCH / layoutp->page_rows;
4947c478bd9Sstevel@tonic-gate if (layoutp->rotation == 0)
4957c478bd9Sstevel@tonic-gate box_width = box_height /
4967c478bd9Sstevel@tonic-gate DEFAULT_PAGE_HEIGHT * DEFAULT_PAGE_WIDTH;
4977c478bd9Sstevel@tonic-gate else
4987c478bd9Sstevel@tonic-gate box_width = box_height *
4997c478bd9Sstevel@tonic-gate DEFAULT_PAGE_HEIGHT / DEFAULT_PAGE_WIDTH;
5007c478bd9Sstevel@tonic-gate gap_width = DEFAULT_PAPER_WIDTH * POINTS_PER_INCH /
5017c478bd9Sstevel@tonic-gate layoutp->page_cols - box_width;
5027c478bd9Sstevel@tonic-gate gap_height = DEFAULT_PAPER_HEIGHT * POINTS_PER_INCH /
5037c478bd9Sstevel@tonic-gate layoutp->page_rows - box_height;
5047c478bd9Sstevel@tonic-gate margin_x = gap_width/2;
5057c478bd9Sstevel@tonic-gate margin_y = gap_height/2;
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate columns -= numberwidth + DEFAULT_SPACES_AFTER_NUMBER;
5087c478bd9Sstevel@tonic-gate if (columns <= 0) {
5097c478bd9Sstevel@tonic-gate fatal("numbering width exceeds number of columns");
5107c478bd9Sstevel@tonic-gate /* NOT REACHED */
5117c478bd9Sstevel@tonic-gate }
5127c478bd9Sstevel@tonic-gate /* compute physical "lower left corner" of each logical page */
5137c478bd9Sstevel@tonic-gate for (j = 0; j < layoutp->pages; j++) {
5147c478bd9Sstevel@tonic-gate int phys_row; /* 0 is bottom row */
5157c478bd9Sstevel@tonic-gate int phys_col; /* 0 is left column */
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate if (landscape == (rot_text == 0)) {
5187c478bd9Sstevel@tonic-gate /* logical pages run physically up and down */
5197c478bd9Sstevel@tonic-gate phys_row = j % layoutp->page_rows;
5207c478bd9Sstevel@tonic-gate phys_col = j / layoutp->page_rows;
5217c478bd9Sstevel@tonic-gate } else {
5227c478bd9Sstevel@tonic-gate /* logical pages run physically left to right */
5237c478bd9Sstevel@tonic-gate phys_row = j / layoutp->page_cols;
5247c478bd9Sstevel@tonic-gate phys_col = j % layoutp->page_cols;
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate if (rot_text == 0) {
5277c478bd9Sstevel@tonic-gate /* top physical row is logically first */
5287c478bd9Sstevel@tonic-gate phys_row = layoutp->page_rows - 1 - phys_row;
5297c478bd9Sstevel@tonic-gate }
5307c478bd9Sstevel@tonic-gate
5317c478bd9Sstevel@tonic-gate positions[j].base_x = margin_x +
5327c478bd9Sstevel@tonic-gate phys_col * (box_width + gap_width);
5337c478bd9Sstevel@tonic-gate positions[j].base_y = margin_y +
5347c478bd9Sstevel@tonic-gate phys_row * (box_height + gap_height);
5357c478bd9Sstevel@tonic-gate if (rot_text != 0) {
5367c478bd9Sstevel@tonic-gate positions[j].base_x += box_width;
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate if (vflag) {
5419a70fc3bSMark J. Nelson (void) fprintf(stderr, "%s:\n\n", progname);
5427c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Lines/page = %d\n", lines_per_page);
5437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Columns = %d\n", columns);
5447c478bd9Sstevel@tonic-gate for (j = 0; j < layoutp->pages; j++) {
5457c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tx=%3d, y=%3d\n",
5469a70fc3bSMark J. Nelson positions[j].base_x, positions[j].base_y);
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "box_width=%3d, box_height=%3d\n",
5497c478bd9Sstevel@tonic-gate box_width, box_height);
5507c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "gap_width=%3d, gap_height=%3d\n",
5517c478bd9Sstevel@tonic-gate gap_width, gap_height);
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate setup();
5557c478bd9Sstevel@tonic-gate preamble();
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate if (iscodereview) {
5587c478bd9Sstevel@tonic-gate char command[BUFSIZ];
5597c478bd9Sstevel@tonic-gate
5607c478bd9Sstevel@tonic-gate (void) snprintf(command, BUFSIZ, "diff -b -D %s %s %s",
5617c478bd9Sstevel@tonic-gate CODEREVIEW, argv[first_file+1], argv[first_file]);
5627c478bd9Sstevel@tonic-gate infile = popen(command, "r");
5637c478bd9Sstevel@tonic-gate bannerfile = argv[first_file+1];
5647c478bd9Sstevel@tonic-gate if (ungetc(getc(infile), infile) == EOF) {
5657c478bd9Sstevel@tonic-gate (void) pclose(infile);
5667c478bd9Sstevel@tonic-gate (void) sprintf(command,
5677c478bd9Sstevel@tonic-gate "echo No differences encountered");
5687c478bd9Sstevel@tonic-gate infile = popen(command, "r");
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate setheaderfile(bannerfile);
5717c478bd9Sstevel@tonic-gate printfile(infile);
5727c478bd9Sstevel@tonic-gate (void) pclose(infile);
5737c478bd9Sstevel@tonic-gate } else if (first_file == argc) { /* no files on command line */
5747c478bd9Sstevel@tonic-gate if (vflag)
5757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tprinting stdin\n");
5767c478bd9Sstevel@tonic-gate setheaderfile("stdin");
5777c478bd9Sstevel@tonic-gate printfile(stdin);
5787c478bd9Sstevel@tonic-gate } else {
5797c478bd9Sstevel@tonic-gate for (i = first_file; i < argc; i++) {
5807c478bd9Sstevel@tonic-gate if ((infile = fopen(argv[i], "r")) == (FILE *)NULL) {
5817c478bd9Sstevel@tonic-gate fatal("can't open %s for reading", argv[i]);
5827c478bd9Sstevel@tonic-gate /*NOTREACHED*/
5837c478bd9Sstevel@tonic-gate }
5847c478bd9Sstevel@tonic-gate if (pflag) {
5857c478bd9Sstevel@tonic-gate char cmdbuf[BUFSIZ];
5867c478bd9Sstevel@tonic-gate (void) snprintf(cmdbuf, BUFSIZ, "pr %s",
5877c478bd9Sstevel@tonic-gate argv[i]);
5887c478bd9Sstevel@tonic-gate (void) fclose(infile);
5897c478bd9Sstevel@tonic-gate infile = popen(cmdbuf, "r");
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate if (vflag)
5927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tprinting %s\n",
5937c478bd9Sstevel@tonic-gate argv[i]);
5947c478bd9Sstevel@tonic-gate setheaderfile(argv[i]);
5957c478bd9Sstevel@tonic-gate printfile(infile);
5967c478bd9Sstevel@tonic-gate if (pflag)
5977c478bd9Sstevel@tonic-gate (void) pclose(infile);
5987c478bd9Sstevel@tonic-gate else
5997c478bd9Sstevel@tonic-gate (void) fclose(infile);
6007c478bd9Sstevel@tonic-gate }
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate postamble();
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate if (fflush(stdout) == EOF) {
6067c478bd9Sstevel@tonic-gate fatal("write error on stdout");
6077c478bd9Sstevel@tonic-gate /*NOTREACHED*/
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate exit(0);
6107c478bd9Sstevel@tonic-gate /*NOTREACHED*/
6117c478bd9Sstevel@tonic-gate /*LINTED*/
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate /*
6157c478bd9Sstevel@tonic-gate * Initial lines sent to the LaserWriter
6167c478bd9Sstevel@tonic-gate * Generates the PostScript header and includes the prologue file
6177c478bd9Sstevel@tonic-gate * There is limited checking for I/O errors here
6187c478bd9Sstevel@tonic-gate */
6197c478bd9Sstevel@tonic-gate void
preamble(void)6207c478bd9Sstevel@tonic-gate preamble(void)
6217c478bd9Sstevel@tonic-gate {
6227c478bd9Sstevel@tonic-gate (void) printf("%%!PS-Adobe-2.0\n");
6237c478bd9Sstevel@tonic-gate (void) printf("%%%%Creator: %s on %s\n", progname, hostname);
6247c478bd9Sstevel@tonic-gate (void) printf("%%%%CreationDate: %s\n", currentdate);
6257c478bd9Sstevel@tonic-gate (void) printf("%%%%For: %s\n", username);
6267c478bd9Sstevel@tonic-gate (void) printf("%%%%DocumentFonts: %s %s %s %s\n",
6277c478bd9Sstevel@tonic-gate default_font, default_font_bold,
6287c478bd9Sstevel@tonic-gate default_font_italic, default_font_bold_italic);
6297c478bd9Sstevel@tonic-gate (void) printf("%%%%Pages: (atend)\n");
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate if (prologue == NULL) {
6327c478bd9Sstevel@tonic-gate char **cpp;
6337c478bd9Sstevel@tonic-gate for (cpp = default_prologue; *cpp; cpp++) {
6347c478bd9Sstevel@tonic-gate (void) fputs(*cpp, stdout);
6357c478bd9Sstevel@tonic-gate }
6367c478bd9Sstevel@tonic-gate } else {
6377c478bd9Sstevel@tonic-gate FILE *fp;
6387c478bd9Sstevel@tonic-gate if ((fp = fopen(prologue, "r")) == NULL) {
6397c478bd9Sstevel@tonic-gate fatal("can't open prologue file %s", prologue);
6407c478bd9Sstevel@tonic-gate /*NOTREACHED*/
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate while (fgets(bufin, sizeof (bufin), fp) != NULL)
6437c478bd9Sstevel@tonic-gate (void) fputs(bufin, stdout);
6447c478bd9Sstevel@tonic-gate (void) fclose(fp);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate if (ferror(stdout) || fflush(stdout) == EOF) {
6477c478bd9Sstevel@tonic-gate fatal("write error on stdout");
6487c478bd9Sstevel@tonic-gate /*NOTREACHED*/
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gate (void) printf("/%s {%f /%s %s}bind def\n", DEFAULT_FONT,
6527c478bd9Sstevel@tonic-gate point_size, default_font, SELECT_FONT);
6537c478bd9Sstevel@tonic-gate (void) printf("/%s {%f /%s %s}bind def\n", DEFAULT_FONT_BOLD,
6547c478bd9Sstevel@tonic-gate point_size, default_font_bold, SELECT_FONT);
6557c478bd9Sstevel@tonic-gate (void) printf("/%s {%f /%s %s}bind def\n", DEFAULT_FONT_ITALIC,
6567c478bd9Sstevel@tonic-gate point_size, default_font_italic, SELECT_FONT);
6577c478bd9Sstevel@tonic-gate (void) printf("/%s {%f /%s %s}bind def\n", DEFAULT_FONT_BOLD_ITALIC,
6587c478bd9Sstevel@tonic-gate point_size, default_font_bold_italic, SELECT_FONT);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate void
postamble(void)6627c478bd9Sstevel@tonic-gate postamble(void)
6637c478bd9Sstevel@tonic-gate {
6647c478bd9Sstevel@tonic-gate (void) printf("%%%%Trailer\n");
6657c478bd9Sstevel@tonic-gate (void) printf("%%%%Pages: %d\n", current.page_count);
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate
6687c478bd9Sstevel@tonic-gate int
printbanner(char * filename,FILE * outfile)6697c478bd9Sstevel@tonic-gate printbanner(char *filename, FILE *outfile)
6707c478bd9Sstevel@tonic-gate {
6717c478bd9Sstevel@tonic-gate char buffer[BUFSIZ];
6727c478bd9Sstevel@tonic-gate struct stat statbuf;
6737c478bd9Sstevel@tonic-gate struct format_state format_state;
6747c478bd9Sstevel@tonic-gate int nlines = 0;
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate /* we've already verified readability */
6777c478bd9Sstevel@tonic-gate (void) stat(filename, &statbuf);
6787c478bd9Sstevel@tonic-gate
6797c478bd9Sstevel@tonic-gate save_format_state(&format_state);
6807c478bd9Sstevel@tonic-gate numberwidth = 0;
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_BOLD_ITALIC, outfile);
6837c478bd9Sstevel@tonic-gate
6847c478bd9Sstevel@tonic-gate current.row -= point_size;
6857c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n", start_x, current.row, MOVETO);
6867c478bd9Sstevel@tonic-gate proc(banner, outfile);
6877c478bd9Sstevel@tonic-gate nlines++;
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate current.row -= point_size;
6907c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n", start_x, current.row, MOVETO);
6917c478bd9Sstevel@tonic-gate (void) snprintf(buffer, BUFSIZ, "%8ld %.24s", statbuf.st_size,
6927c478bd9Sstevel@tonic-gate ctime(&statbuf.st_mtime));
6937c478bd9Sstevel@tonic-gate proc(buffer, outfile);
6947c478bd9Sstevel@tonic-gate nlines++;
6957c478bd9Sstevel@tonic-gate
6967c478bd9Sstevel@tonic-gate do {
6977c478bd9Sstevel@tonic-gate current.row -= point_size;
6987c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n", start_x, current.row,
6997c478bd9Sstevel@tonic-gate MOVETO);
7007c478bd9Sstevel@tonic-gate filename += sprintf(buffer, "%.*s", columns, filename);
7017c478bd9Sstevel@tonic-gate proc(buffer, outfile);
7027c478bd9Sstevel@tonic-gate nlines++;
7037c478bd9Sstevel@tonic-gate } while (strlen(filename) != 0);
7047c478bd9Sstevel@tonic-gate
7053c2f5c48Sjwadams if (comment != NULL && comment[0] != 0) {
7063c2f5c48Sjwadams const char *cur = comment;
7073c2f5c48Sjwadams const char *endl;
7083c2f5c48Sjwadams int len;
7093c2f5c48Sjwadams
7103c2f5c48Sjwadams while (*cur != 0) {
7113c2f5c48Sjwadams current.row -= point_size;
7123c2f5c48Sjwadams (void) fprintf(outfile, "%d %.2f %s\n", start_x,
7133c2f5c48Sjwadams current.row, MOVETO);
7143c2f5c48Sjwadams
7153c2f5c48Sjwadams endl = strchr(cur, '\n');
7163c2f5c48Sjwadams if (endl == NULL)
7173c2f5c48Sjwadams endl = cur + strlen(cur);
7183c2f5c48Sjwadams
7193c2f5c48Sjwadams /* truncate to columns */
7203c2f5c48Sjwadams len = endl - cur;
7213c2f5c48Sjwadams if (len > columns)
7223c2f5c48Sjwadams len = columns;
7233c2f5c48Sjwadams (void) sprintf(buffer, "%.*s", len, cur);
7243c2f5c48Sjwadams proc(buffer, outfile);
7253c2f5c48Sjwadams nlines++;
7263c2f5c48Sjwadams
7273c2f5c48Sjwadams if (*endl == 0)
7283c2f5c48Sjwadams break;
7293c2f5c48Sjwadams cur = endl + 1;
7303c2f5c48Sjwadams }
7313c2f5c48Sjwadams }
7323c2f5c48Sjwadams
7337c478bd9Sstevel@tonic-gate current.row -= point_size;
7347c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n", start_x, current.row, MOVETO);
7357c478bd9Sstevel@tonic-gate proc(banner, outfile);
7367c478bd9Sstevel@tonic-gate nlines++;
7377c478bd9Sstevel@tonic-gate
7387c478bd9Sstevel@tonic-gate restore_format_state(&format_state, outfile);
7397c478bd9Sstevel@tonic-gate return (nlines);
7407c478bd9Sstevel@tonic-gate }
7417c478bd9Sstevel@tonic-gate
7427c478bd9Sstevel@tonic-gate void
setcurrentfont(char * newfont,FILE * outfile)7437c478bd9Sstevel@tonic-gate setcurrentfont(char *newfont, FILE *outfile)
7447c478bd9Sstevel@tonic-gate {
7457c478bd9Sstevel@tonic-gate if (current.font != newfont) {
7467c478bd9Sstevel@tonic-gate if (newfont)
7477c478bd9Sstevel@tonic-gate current.font = newfont;
7487c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", current.font);
7497c478bd9Sstevel@tonic-gate }
7507c478bd9Sstevel@tonic-gate }
7517c478bd9Sstevel@tonic-gate
7527c478bd9Sstevel@tonic-gate void
savestate(FILE * f)7537c478bd9Sstevel@tonic-gate savestate(FILE *f)
7547c478bd9Sstevel@tonic-gate {
7557c478bd9Sstevel@tonic-gate current.offset = ftell(f);
7567c478bd9Sstevel@tonic-gate saved = current;
7577c478bd9Sstevel@tonic-gate }
7587c478bd9Sstevel@tonic-gate
7597c478bd9Sstevel@tonic-gate void
restorestate(FILE * f)7607c478bd9Sstevel@tonic-gate restorestate(FILE *f)
7617c478bd9Sstevel@tonic-gate {
7627c478bd9Sstevel@tonic-gate char *font;
7637c478bd9Sstevel@tonic-gate
7647c478bd9Sstevel@tonic-gate font = current.font;
7657c478bd9Sstevel@tonic-gate (void) fseek(f, saved.offset, 0);
7667c478bd9Sstevel@tonic-gate current = saved;
7677c478bd9Sstevel@tonic-gate setcurrentfont(font, f);
7687c478bd9Sstevel@tonic-gate }
7697c478bd9Sstevel@tonic-gate
7707c478bd9Sstevel@tonic-gate void
save_format_state(struct format_state * fs)7717c478bd9Sstevel@tonic-gate save_format_state(struct format_state *fs)
7727c478bd9Sstevel@tonic-gate {
7737c478bd9Sstevel@tonic-gate fs->numberwidth = numberwidth;
7747c478bd9Sstevel@tonic-gate fs->linenumber = linenumber;
7757c478bd9Sstevel@tonic-gate fs->altlinenumber = altlinenumber;
7767c478bd9Sstevel@tonic-gate fs->makegray = makegray;
7777c478bd9Sstevel@tonic-gate fs->font = current.font;
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate
7807c478bd9Sstevel@tonic-gate void
restore_format_state(struct format_state * fs,FILE * outfile)7817c478bd9Sstevel@tonic-gate restore_format_state(struct format_state *fs, FILE *outfile)
7827c478bd9Sstevel@tonic-gate {
7837c478bd9Sstevel@tonic-gate numberwidth = fs->numberwidth;
7847c478bd9Sstevel@tonic-gate linenumber = fs->linenumber;
7857c478bd9Sstevel@tonic-gate altlinenumber = fs->altlinenumber;
7867c478bd9Sstevel@tonic-gate makegray = fs->makegray;
7877c478bd9Sstevel@tonic-gate setcurrentfont(fs->font, outfile);
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate /*
7917c478bd9Sstevel@tonic-gate * Print a file
7927c478bd9Sstevel@tonic-gate *
7937c478bd9Sstevel@tonic-gate * The input stream may be stdin, a file, or a pipe
7947c478bd9Sstevel@tonic-gate */
7957c478bd9Sstevel@tonic-gate void
printfile(FILE * infile)7967c478bd9Sstevel@tonic-gate printfile(FILE *infile)
7977c478bd9Sstevel@tonic-gate {
7987c478bd9Sstevel@tonic-gate int eof;
7997c478bd9Sstevel@tonic-gate char *p;
8007c478bd9Sstevel@tonic-gate FILE *outfile;
8017c478bd9Sstevel@tonic-gate
8027c478bd9Sstevel@tonic-gate if (reverse)
8037c478bd9Sstevel@tonic-gate page_map[0] = 0L;
8047c478bd9Sstevel@tonic-gate if (usetmp) {
8057c478bd9Sstevel@tonic-gate (void) snprintf(bufin, BUFIN, "/tmp/%sXXXXXX", progname);
8067c478bd9Sstevel@tonic-gate p = mktemp(bufin);
8077c478bd9Sstevel@tonic-gate if ((outfile = fopen(p, "w+")) == NULL) {
8087c478bd9Sstevel@tonic-gate fatal("can't open temporary file %s", p);
8097c478bd9Sstevel@tonic-gate /* NOTREACHED */
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate if (!dflag)
8127c478bd9Sstevel@tonic-gate (void) unlink(p);
8137c478bd9Sstevel@tonic-gate else
8147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "will not unlink %s\n", p);
8157c478bd9Sstevel@tonic-gate }
8167c478bd9Sstevel@tonic-gate else
8177c478bd9Sstevel@tonic-gate outfile = stdout;
8187c478bd9Sstevel@tonic-gate
8197c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT, outfile);
8207c478bd9Sstevel@tonic-gate change_seen = 0;
8217c478bd9Sstevel@tonic-gate dots_inserted = 0;
8227c478bd9Sstevel@tonic-gate in_change = 0;
8237c478bd9Sstevel@tonic-gate makegray = 0;
8247c478bd9Sstevel@tonic-gate linenumber = 0;
8257c478bd9Sstevel@tonic-gate altlinenumber = 0;
8267c478bd9Sstevel@tonic-gate current.logical_page_count = 0;
8277c478bd9Sstevel@tonic-gate do {
8287c478bd9Sstevel@tonic-gate current.row = start_y;
8297c478bd9Sstevel@tonic-gate eof = printpage(infile, outfile);
8307c478bd9Sstevel@tonic-gate } while (!eof);
8317c478bd9Sstevel@tonic-gate
8327c478bd9Sstevel@tonic-gate if (((int)current.row) != start_y)
8337c478bd9Sstevel@tonic-gate endpage(outfile);
8347c478bd9Sstevel@tonic-gate if ((current.logical_page_count % layoutp->pages) != 0)
8357c478bd9Sstevel@tonic-gate flushpage(outfile);
8367c478bd9Sstevel@tonic-gate if (vflag)
8377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
8387c478bd9Sstevel@tonic-gate if (fflush(outfile) == EOF) {
8397c478bd9Sstevel@tonic-gate fatal("write error while flushing output");
8407c478bd9Sstevel@tonic-gate /*NOTREACHED*/
8417c478bd9Sstevel@tonic-gate }
8427c478bd9Sstevel@tonic-gate if (usetmp) {
8437c478bd9Sstevel@tonic-gate if (reverse)
8447c478bd9Sstevel@tonic-gate reversepages(outfile);
8457c478bd9Sstevel@tonic-gate else
8467c478bd9Sstevel@tonic-gate copypage(outfile, 0L, current.offset);
8477c478bd9Sstevel@tonic-gate (void) fclose(outfile);
8487c478bd9Sstevel@tonic-gate }
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate void
process_elide(FILE * outfile)8527c478bd9Sstevel@tonic-gate process_elide(FILE *outfile)
8537c478bd9Sstevel@tonic-gate {
8547c478bd9Sstevel@tonic-gate if (!change_seen && !in_change) {
8557c478bd9Sstevel@tonic-gate /* don't include function in output */
8567c478bd9Sstevel@tonic-gate restorestate(outfile);
8577c478bd9Sstevel@tonic-gate if (!dots_inserted) {
8587c478bd9Sstevel@tonic-gate struct format_state format_state;
8597c478bd9Sstevel@tonic-gate
8607c478bd9Sstevel@tonic-gate save_format_state(&format_state);
8617c478bd9Sstevel@tonic-gate numberwidth = 0;
8627c478bd9Sstevel@tonic-gate current.lineno++;
8637c478bd9Sstevel@tonic-gate current.row -= point_size;
8649a70fc3bSMark J. Nelson setcurrentfont(DEFAULT_FONT_BOLD_ITALIC, outfile);
8659a70fc3bSMark J. Nelson proc("______unchanged_portion_omitted_", outfile);
8669a70fc3bSMark J. Nelson restore_format_state(&format_state, outfile);
8677c478bd9Sstevel@tonic-gate savestate(outfile);
8687c478bd9Sstevel@tonic-gate dots_inserted = 1;
8697c478bd9Sstevel@tonic-gate }
8707c478bd9Sstevel@tonic-gate } else {
8717c478bd9Sstevel@tonic-gate savestate(outfile);
8727c478bd9Sstevel@tonic-gate change_seen = in_change;
8737c478bd9Sstevel@tonic-gate dots_inserted = 0;
8747c478bd9Sstevel@tonic-gate }
8757c478bd9Sstevel@tonic-gate }
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate /*
8787c478bd9Sstevel@tonic-gate * Process the next page
8797c478bd9Sstevel@tonic-gate * Return 1 on EOF, 0 otherwise
8807c478bd9Sstevel@tonic-gate */
8817c478bd9Sstevel@tonic-gate int
printpage(FILE * infile,FILE * outfile)8827c478bd9Sstevel@tonic-gate printpage(FILE *infile, FILE *outfile)
8837c478bd9Sstevel@tonic-gate {
8847c478bd9Sstevel@tonic-gate int tmplinenumber;
8857c478bd9Sstevel@tonic-gate char command[BUFSIZ], flag[BUFSIZ];
8867c478bd9Sstevel@tonic-gate
8877c478bd9Sstevel@tonic-gate if (ungetc(getc(infile), infile) == EOF)
8887c478bd9Sstevel@tonic-gate return (1);
8897c478bd9Sstevel@tonic-gate
8907c478bd9Sstevel@tonic-gate current.lineno = 0;
8917c478bd9Sstevel@tonic-gate current.lineno += startpage(outfile);
8927c478bd9Sstevel@tonic-gate if (bannerfile) {
8937c478bd9Sstevel@tonic-gate current.lineno += printbanner(bannerfile, outfile);
8947c478bd9Sstevel@tonic-gate bannerfile = NULL;
895*8ad4d6ddSJeff Bonwick savestate(outfile);
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate for (; current.lineno < lines_per_page; ) {
8987c478bd9Sstevel@tonic-gate if (fgetline(bufin, sizeof (bufin), infile) == (char *)NULL) {
8997c478bd9Sstevel@tonic-gate if (elide)
9007c478bd9Sstevel@tonic-gate process_elide(outfile);
9017c478bd9Sstevel@tonic-gate return (1);
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate /*
9047c478bd9Sstevel@tonic-gate * Allow C comment delimiters around flag; only really applies
9057c478bd9Sstevel@tonic-gate * to #else and #endif, but we don't expect to see C comments
9067c478bd9Sstevel@tonic-gate * around flag for #if. Also accept flag with no C comment
9077c478bd9Sstevel@tonic-gate * delimiters.
9087c478bd9Sstevel@tonic-gate */
9097c478bd9Sstevel@tonic-gate if (iscodereview &&
9107c478bd9Sstevel@tonic-gate (sscanf(bufin, "#%32s /* %80s */", command, flag) == 2 ||
9117c478bd9Sstevel@tonic-gate sscanf(bufin, "#%32s %80s", command, flag) == 2) &&
9127c478bd9Sstevel@tonic-gate strcmp(flag, CODEREVIEW) == 0) {
9137c478bd9Sstevel@tonic-gate if (strcmp(command, "ifdef") == 0) {
9147c478bd9Sstevel@tonic-gate change_seen = 1;
9157c478bd9Sstevel@tonic-gate in_change = 1;
9167c478bd9Sstevel@tonic-gate makegray = 1;
9177c478bd9Sstevel@tonic-gate old_stuff = 1;
9187c478bd9Sstevel@tonic-gate tmplinenumber = linenumber;
9197c478bd9Sstevel@tonic-gate linenumber = altlinenumber;
9207c478bd9Sstevel@tonic-gate altlinenumber = tmplinenumber;
9217c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_ITALIC, outfile);
9227c478bd9Sstevel@tonic-gate } else if (strcmp(command, "ifndef") == 0) {
9237c478bd9Sstevel@tonic-gate change_seen = 1;
9247c478bd9Sstevel@tonic-gate in_change = 1;
9257c478bd9Sstevel@tonic-gate makegray = 1;
9267c478bd9Sstevel@tonic-gate old_stuff = 0;
9277c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_BOLD, outfile);
9287c478bd9Sstevel@tonic-gate } else if (strcmp(command, "else") == 0) {
9297c478bd9Sstevel@tonic-gate makegray = 1;
9307c478bd9Sstevel@tonic-gate old_stuff = !old_stuff;
9317c478bd9Sstevel@tonic-gate tmplinenumber = linenumber;
9327c478bd9Sstevel@tonic-gate linenumber = altlinenumber;
9337c478bd9Sstevel@tonic-gate altlinenumber = tmplinenumber;
9347c478bd9Sstevel@tonic-gate if (!old_stuff)
9357c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_BOLD,
9367c478bd9Sstevel@tonic-gate outfile);
9377c478bd9Sstevel@tonic-gate else
9387c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_ITALIC,
9397c478bd9Sstevel@tonic-gate outfile);
9407c478bd9Sstevel@tonic-gate } else /* if (strcmp(command, "endif") == 0) */ {
9417c478bd9Sstevel@tonic-gate in_change = 0;
9427c478bd9Sstevel@tonic-gate makegray = 0;
9437c478bd9Sstevel@tonic-gate savestate(outfile);
9447c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT, outfile);
9457c478bd9Sstevel@tonic-gate if (old_stuff) {
9467c478bd9Sstevel@tonic-gate tmplinenumber = linenumber;
9477c478bd9Sstevel@tonic-gate linenumber = altlinenumber;
9487c478bd9Sstevel@tonic-gate altlinenumber = tmplinenumber;
9497c478bd9Sstevel@tonic-gate }
9507c478bd9Sstevel@tonic-gate }
9517c478bd9Sstevel@tonic-gate continue;
9527c478bd9Sstevel@tonic-gate }
9537c478bd9Sstevel@tonic-gate current.lineno++;
9547c478bd9Sstevel@tonic-gate current.row -= point_size;
9557c478bd9Sstevel@tonic-gate if (bufin[0] == '\f')
9567c478bd9Sstevel@tonic-gate break;
9577c478bd9Sstevel@tonic-gate proc(bufin, outfile);
9587c478bd9Sstevel@tonic-gate if (elide && (bufin[0] == END_C_FUNCTION ||
9597c478bd9Sstevel@tonic-gate (strstr(bufin, END_ASM_FUNCTION) != NULL)))
9607c478bd9Sstevel@tonic-gate process_elide(outfile);
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate endpage(outfile);
9637c478bd9Sstevel@tonic-gate return (0);
9647c478bd9Sstevel@tonic-gate }
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate /*
9677c478bd9Sstevel@tonic-gate * Start a new page
9687c478bd9Sstevel@tonic-gate */
9697c478bd9Sstevel@tonic-gate int
startpage(FILE * outfile)9707c478bd9Sstevel@tonic-gate startpage(FILE *outfile)
9717c478bd9Sstevel@tonic-gate {
9727c478bd9Sstevel@tonic-gate int logical_page, lines, buflen;
9737c478bd9Sstevel@tonic-gate struct format_state format_state;
9747c478bd9Sstevel@tonic-gate char buf[8];
9757c478bd9Sstevel@tonic-gate
9767c478bd9Sstevel@tonic-gate logical_page = current.logical_page_count % layoutp->pages;
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate if (logical_page == 0)
9797c478bd9Sstevel@tonic-gate setuppage(outfile);
9807c478bd9Sstevel@tonic-gate else
9817c478bd9Sstevel@tonic-gate setcurrentfont((char *)NULL, outfile);
9827c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s ", SET_WIDTHS);
9837c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %f %d %d %s\n",
9849a70fc3bSMark J. Nelson rot_text, layoutp->scale, positions[logical_page].base_x,
9859a70fc3bSMark J. Nelson positions[logical_page].base_y, START_PAGE);
9867c478bd9Sstevel@tonic-gate lines = 0;
9877c478bd9Sstevel@tonic-gate if (header) {
9887c478bd9Sstevel@tonic-gate save_format_state(&format_state);
9897c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT_BOLD, outfile);
9907c478bd9Sstevel@tonic-gate numberwidth = 0;
9917c478bd9Sstevel@tonic-gate makegray = 0;
9927c478bd9Sstevel@tonic-gate
9937c478bd9Sstevel@tonic-gate current.row -= point_size;
9947c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n", start_x, current.row,
9957c478bd9Sstevel@tonic-gate MOVETO);
9967c478bd9Sstevel@tonic-gate proc(headerstring, outfile);
9977c478bd9Sstevel@tonic-gate (void) snprintf(buf, 8, "%d", current.logical_page_count + 1);
9987c478bd9Sstevel@tonic-gate buflen = strlen(buf);
9997c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s (%s)%s\n",
10007c478bd9Sstevel@tonic-gate (int)(end_x - (buflen + 0.5) *
10017c478bd9Sstevel@tonic-gate DEFAULT_CHAR_WIDTH * point_size),
10027c478bd9Sstevel@tonic-gate current.row, MOVETO, buf, SHOW);
10037c478bd9Sstevel@tonic-gate current.row -= point_size;
10047c478bd9Sstevel@tonic-gate restore_format_state(&format_state, outfile);
10057c478bd9Sstevel@tonic-gate lines = 2;
10067c478bd9Sstevel@tonic-gate }
10077c478bd9Sstevel@tonic-gate return (lines);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate
10107c478bd9Sstevel@tonic-gate void
setheaderfile(char * filename)10117c478bd9Sstevel@tonic-gate setheaderfile(char *filename)
10127c478bd9Sstevel@tonic-gate {
10137c478bd9Sstevel@tonic-gate if (header == HEADER_IMPLICIT)
10147c478bd9Sstevel@tonic-gate headerstring = filename;
10157c478bd9Sstevel@tonic-gate }
10167c478bd9Sstevel@tonic-gate
10177c478bd9Sstevel@tonic-gate /*
10187c478bd9Sstevel@tonic-gate * Setup page
10197c478bd9Sstevel@tonic-gate */
10207c478bd9Sstevel@tonic-gate void
setuppage(FILE * outfile)10217c478bd9Sstevel@tonic-gate setuppage(FILE *outfile)
10227c478bd9Sstevel@tonic-gate {
10237c478bd9Sstevel@tonic-gate int i, ilimit;
10247c478bd9Sstevel@tonic-gate int begin, end, place;
10257c478bd9Sstevel@tonic-gate
10267c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%%%%Page: ? %d\n", current.page_count + 1);
10277c478bd9Sstevel@tonic-gate setcurrentfont((char *)NULL, outfile);
10287c478bd9Sstevel@tonic-gate if (layoutp->pages == 1)
10297c478bd9Sstevel@tonic-gate return;
10307c478bd9Sstevel@tonic-gate
10319a70fc3bSMark J. Nelson (void) fprintf(outfile, "%f %s %s\n", RULE_WIDTH, SETLINEWIDTH,
10329a70fc3bSMark J. Nelson NEWPATH);
10337c478bd9Sstevel@tonic-gate begin = 0; end = DEFAULT_PAPER_WIDTH * POINTS_PER_INCH;
10347c478bd9Sstevel@tonic-gate for (i = 1, ilimit = layoutp->page_rows; i < ilimit; i++) {
10357c478bd9Sstevel@tonic-gate place = margin_y - gap_height/2 + i * (box_height+gap_height);
10367c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %d %s ", begin, place, MOVETO);
10377c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %d %s\n", end, place, LINETO);
10387c478bd9Sstevel@tonic-gate }
10397c478bd9Sstevel@tonic-gate begin = 0; end = DEFAULT_PAPER_HEIGHT * POINTS_PER_INCH;
10407c478bd9Sstevel@tonic-gate for (i = 1, ilimit = layoutp->page_cols; i < ilimit; i++) {
10417c478bd9Sstevel@tonic-gate place = margin_x - gap_width/2 + i * (box_width+gap_width);
10427c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %d %s ", place, begin, MOVETO);
10437c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %d %s\n", place, end, LINETO);
10447c478bd9Sstevel@tonic-gate }
10457c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", STROKE);
10467c478bd9Sstevel@tonic-gate }
10477c478bd9Sstevel@tonic-gate
10487c478bd9Sstevel@tonic-gate /*
10497c478bd9Sstevel@tonic-gate * Terminate the logical page and indicate the start of the next
10507c478bd9Sstevel@tonic-gate */
10517c478bd9Sstevel@tonic-gate void
endpage(FILE * outfile)10527c478bd9Sstevel@tonic-gate endpage(FILE *outfile)
10537c478bd9Sstevel@tonic-gate {
10547c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", END_PAGE);
10557c478bd9Sstevel@tonic-gate current.logical_page_count++;
10567c478bd9Sstevel@tonic-gate if (vflag)
10577c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "x");
10587c478bd9Sstevel@tonic-gate if ((current.logical_page_count % layoutp->pages) == 0)
10597c478bd9Sstevel@tonic-gate flushpage(outfile);
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate
10627c478bd9Sstevel@tonic-gate /*
10637c478bd9Sstevel@tonic-gate * Flush the physical page
10647c478bd9Sstevel@tonic-gate * Record the start of the next page
10657c478bd9Sstevel@tonic-gate */
10667c478bd9Sstevel@tonic-gate void
flushpage(FILE * outfile)10677c478bd9Sstevel@tonic-gate flushpage(FILE *outfile)
10687c478bd9Sstevel@tonic-gate {
10697c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %s\n", ncopies, FLUSH_PAGE);
10707c478bd9Sstevel@tonic-gate current.page_count++;
10717c478bd9Sstevel@tonic-gate current.offset = ftell(outfile);
10727c478bd9Sstevel@tonic-gate if (reverse) {
10737c478bd9Sstevel@tonic-gate if (current.page_count >= MAXPAGES) {
10747c478bd9Sstevel@tonic-gate fatal("page reversal limit (%d) reached", MAXPAGES);
10757c478bd9Sstevel@tonic-gate /* NOTREACHED */
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate page_map[current.page_count] = current.offset;
10787c478bd9Sstevel@tonic-gate }
10797c478bd9Sstevel@tonic-gate if (vflag)
10807c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "|");
10817c478bd9Sstevel@tonic-gate }
10827c478bd9Sstevel@tonic-gate
10837c478bd9Sstevel@tonic-gate /*
10847c478bd9Sstevel@tonic-gate * reverse the order of pages
10857c478bd9Sstevel@tonic-gate */
10867c478bd9Sstevel@tonic-gate void
reversepages(FILE * outfile)10877c478bd9Sstevel@tonic-gate reversepages(FILE *outfile)
10887c478bd9Sstevel@tonic-gate {
10897c478bd9Sstevel@tonic-gate int i;
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate if (vflag)
10927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\nreversing %d page%s\n",
10939a70fc3bSMark J. Nelson current.page_count, current.page_count > 1 ? "s" : "");
10947c478bd9Sstevel@tonic-gate for (i = current.page_count - 1; i >= 0; i--) {
10957c478bd9Sstevel@tonic-gate copypage(outfile, page_map[i], page_map[i+1]);
10967c478bd9Sstevel@tonic-gate }
10977c478bd9Sstevel@tonic-gate }
10987c478bd9Sstevel@tonic-gate
10997c478bd9Sstevel@tonic-gate /*
11007c478bd9Sstevel@tonic-gate * copy a page (or more) from tempfile to stdout
11017c478bd9Sstevel@tonic-gate */
11027c478bd9Sstevel@tonic-gate void
copypage(FILE * outfile,long off_beg,long off_end)11037c478bd9Sstevel@tonic-gate copypage(FILE *outfile, long off_beg, long off_end)
11047c478bd9Sstevel@tonic-gate {
11057c478bd9Sstevel@tonic-gate int bytecount, nbytes;
11067c478bd9Sstevel@tonic-gate
11077c478bd9Sstevel@tonic-gate if (fseek(outfile, off_beg, 0) == -1L) {
11087c478bd9Sstevel@tonic-gate fatal("temporary file seek error");
11097c478bd9Sstevel@tonic-gate /* NOTREACHED */
11107c478bd9Sstevel@tonic-gate }
11117c478bd9Sstevel@tonic-gate nbytes = off_end - off_beg;
11127c478bd9Sstevel@tonic-gate while (nbytes > 0) {
11137c478bd9Sstevel@tonic-gate bytecount = nbytes;
11147c478bd9Sstevel@tonic-gate if (bytecount > sizeof (bufout))
11157c478bd9Sstevel@tonic-gate bytecount = sizeof (bufout);
11167c478bd9Sstevel@tonic-gate bytecount = fread(bufout, 1, bytecount, outfile);
11177c478bd9Sstevel@tonic-gate if (bytecount <= 0) {
11187c478bd9Sstevel@tonic-gate fatal("temporary file read error");
11197c478bd9Sstevel@tonic-gate /* NOTREACHED */
11207c478bd9Sstevel@tonic-gate }
11217c478bd9Sstevel@tonic-gate if (fwrite(bufout, 1, bytecount, stdout) != bytecount) {
11227c478bd9Sstevel@tonic-gate fatal("write error during page copy");
11237c478bd9Sstevel@tonic-gate /* NOTREACHED */
11247c478bd9Sstevel@tonic-gate }
11257c478bd9Sstevel@tonic-gate nbytes -= bytecount;
11267c478bd9Sstevel@tonic-gate }
11277c478bd9Sstevel@tonic-gate }
11287c478bd9Sstevel@tonic-gate
11297c478bd9Sstevel@tonic-gate /*
11307c478bd9Sstevel@tonic-gate * Process a line of input, escaping characters when necessary and handling
11317c478bd9Sstevel@tonic-gate * tabs
11327c478bd9Sstevel@tonic-gate *
11337c478bd9Sstevel@tonic-gate * The output is improved somewhat by coalescing consecutive tabs and
11347c478bd9Sstevel@tonic-gate * backspaces and eliminating tabs at the end of a line
11357c478bd9Sstevel@tonic-gate *
11367c478bd9Sstevel@tonic-gate * Overprinting (presumably most often used in underlining) can be far from
11377c478bd9Sstevel@tonic-gate * optimal; in particular the way nroff underlines by sequences like
11387c478bd9Sstevel@tonic-gate * "_\ba_\bb_\bc" creates a large volume of PostScript. This isn't too
11397c478bd9Sstevel@tonic-gate * serious since a lot of nroff underlining is unlikely.
11407c478bd9Sstevel@tonic-gate *
11417c478bd9Sstevel@tonic-gate * Since a newline is generated for each call there will be more
11427c478bd9Sstevel@tonic-gate * newlines in the output than is necessary
11437c478bd9Sstevel@tonic-gate */
11447c478bd9Sstevel@tonic-gate void
proc(char * in,FILE * outfile)11457c478bd9Sstevel@tonic-gate proc(char *in, FILE *outfile)
11467c478bd9Sstevel@tonic-gate {
11477c478bd9Sstevel@tonic-gate int i;
11487c478bd9Sstevel@tonic-gate char *last, *p, *q;
11497c478bd9Sstevel@tonic-gate int currentp, instr, tabc, tabto, grayed;
11507c478bd9Sstevel@tonic-gate char *altfont;
11517c478bd9Sstevel@tonic-gate
11527c478bd9Sstevel@tonic-gate currentp = 0;
11537c478bd9Sstevel@tonic-gate instr = 0;
11547c478bd9Sstevel@tonic-gate tabto = 0;
11557c478bd9Sstevel@tonic-gate if (iscodereview) {
11567c478bd9Sstevel@tonic-gate grayed = makegray;
11577c478bd9Sstevel@tonic-gate altfont = current.font;
11587c478bd9Sstevel@tonic-gate } else {
11597c478bd9Sstevel@tonic-gate grayed = 0;
11607c478bd9Sstevel@tonic-gate altfont = DEFAULT_FONT;
11617c478bd9Sstevel@tonic-gate }
11627c478bd9Sstevel@tonic-gate /* subtract slop factor */
11637c478bd9Sstevel@tonic-gate last = bufout + MAX_OUTPUT_LINE_LENGTH - 20;
11647c478bd9Sstevel@tonic-gate for (;;) { /* check for any special line treatment */
11657c478bd9Sstevel@tonic-gate if (graylength && strncmp(in, graystring, graylength) == 0) {
11667c478bd9Sstevel@tonic-gate grayed++;
11677c478bd9Sstevel@tonic-gate in += graylength;
11687c478bd9Sstevel@tonic-gate } else if (boldlength &&
11697c478bd9Sstevel@tonic-gate strncmp(in, boldstring, boldlength) == 0) {
11707c478bd9Sstevel@tonic-gate altfont = DEFAULT_FONT_BOLD;
11717c478bd9Sstevel@tonic-gate in += boldlength;
11727c478bd9Sstevel@tonic-gate } else if (itlclength &&
11737c478bd9Sstevel@tonic-gate strncmp(in, itlcstring, itlclength) == 0) {
11747c478bd9Sstevel@tonic-gate altfont = DEFAULT_FONT_ITALIC;
11757c478bd9Sstevel@tonic-gate in += itlclength;
11767c478bd9Sstevel@tonic-gate } else if (bitclength &&
11777c478bd9Sstevel@tonic-gate strncmp(in, bitcstring, bitclength) == 0) {
11787c478bd9Sstevel@tonic-gate altfont = DEFAULT_FONT_BOLD_ITALIC;
11797c478bd9Sstevel@tonic-gate in += bitclength;
11807c478bd9Sstevel@tonic-gate } else
11817c478bd9Sstevel@tonic-gate break;
11827c478bd9Sstevel@tonic-gate }
11837c478bd9Sstevel@tonic-gate if (grayed) {
11847c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %d %.2f %s\n",
11859a70fc3bSMark J. Nelson start_x,
11869a70fc3bSMark J. Nelson current.row - DEFAULT_DESCENDER_FRACTION * point_size,
11879a70fc3bSMark J. Nelson end_x,
11889a70fc3bSMark J. Nelson current.row +
11897c478bd9Sstevel@tonic-gate (1.0 - DEFAULT_DESCENDER_FRACTION) * point_size,
11907c478bd9Sstevel@tonic-gate SHADE);
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate
11937c478bd9Sstevel@tonic-gate linenumber++;
11947c478bd9Sstevel@tonic-gate if (!in_change)
11957c478bd9Sstevel@tonic-gate altlinenumber++;
11967c478bd9Sstevel@tonic-gate if (*in == '\0')
11977c478bd9Sstevel@tonic-gate return;
11987c478bd9Sstevel@tonic-gate
11997c478bd9Sstevel@tonic-gate if (start_x != 0) {
12007c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n",
12017c478bd9Sstevel@tonic-gate start_x, current.row, MOVETO);
12027c478bd9Sstevel@tonic-gate }
12037c478bd9Sstevel@tonic-gate else
12047c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%.2f %s\n",
12057c478bd9Sstevel@tonic-gate current.row, ZEROMOVETO);
12067c478bd9Sstevel@tonic-gate if (numberwidth) {
12077c478bd9Sstevel@tonic-gate setcurrentfont(DEFAULT_FONT, outfile);
12087c478bd9Sstevel@tonic-gate (void) sprintf(bufout, "%*d", numberwidth, linenumber);
12097c478bd9Sstevel@tonic-gate for (q = bufout, i = 0; *q == ' '; q++, i++)
12107c478bd9Sstevel@tonic-gate ;
12117c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %s (%s)%s %d %s ",
12127c478bd9Sstevel@tonic-gate i, TAB, q, SHOW, DEFAULT_SPACES_AFTER_NUMBER, TAB);
12137c478bd9Sstevel@tonic-gate }
12147c478bd9Sstevel@tonic-gate setcurrentfont(altfont, outfile);
12157c478bd9Sstevel@tonic-gate
12167c478bd9Sstevel@tonic-gate q = bufout;
12177c478bd9Sstevel@tonic-gate *q = '\0';
12187c478bd9Sstevel@tonic-gate for (p = in; *p != '\0'; p++) {
12197c478bd9Sstevel@tonic-gate switch (*p) {
12207c478bd9Sstevel@tonic-gate case '\t':
12217c478bd9Sstevel@tonic-gate /*
12227c478bd9Sstevel@tonic-gate * Count the number of tabs that immediately follow
12237c478bd9Sstevel@tonic-gate * the one we're looking at
12247c478bd9Sstevel@tonic-gate */
12257c478bd9Sstevel@tonic-gate tabc = 0;
12267c478bd9Sstevel@tonic-gate while (*(p + 1) == '\t') {
12277c478bd9Sstevel@tonic-gate p++;
12287c478bd9Sstevel@tonic-gate tabc++;
12297c478bd9Sstevel@tonic-gate }
12307c478bd9Sstevel@tonic-gate if (currentp > 0) { /* not beginning of line */
12317c478bd9Sstevel@tonic-gate i = tabstop - (currentp % tabstop) +
12327c478bd9Sstevel@tonic-gate tabc * tabstop;
12337c478bd9Sstevel@tonic-gate if (instr) {
12347c478bd9Sstevel@tonic-gate (void) snprintf(q,
12357c478bd9Sstevel@tonic-gate BUFOUT - (q - bufout), ")%s ",
12367c478bd9Sstevel@tonic-gate SHOW);
12377c478bd9Sstevel@tonic-gate q += strlen(q);
12387c478bd9Sstevel@tonic-gate instr = 0;
12397c478bd9Sstevel@tonic-gate }
12407c478bd9Sstevel@tonic-gate }
12417c478bd9Sstevel@tonic-gate else
12427c478bd9Sstevel@tonic-gate i = (tabc + 1) * tabstop;
12437c478bd9Sstevel@tonic-gate tabto += i;
12447c478bd9Sstevel@tonic-gate currentp += i;
12457c478bd9Sstevel@tonic-gate break;
12467c478bd9Sstevel@tonic-gate case '\b':
12477c478bd9Sstevel@tonic-gate /* backspacing over tabs doesn't work... */
12487c478bd9Sstevel@tonic-gate if (tabto != 0) {
12497c478bd9Sstevel@tonic-gate fatal("attempt to backspace over a tab");
12507c478bd9Sstevel@tonic-gate /*NOTREACHED*/
12517c478bd9Sstevel@tonic-gate }
12527c478bd9Sstevel@tonic-gate p++;
12537c478bd9Sstevel@tonic-gate for (i = 1; *p == '\b'; p++)
12547c478bd9Sstevel@tonic-gate i++;
12557c478bd9Sstevel@tonic-gate p--;
12567c478bd9Sstevel@tonic-gate if (currentp - i < 0) {
12577c478bd9Sstevel@tonic-gate fatal("too many backspaces");
12587c478bd9Sstevel@tonic-gate /*NOTREACHED*/
12597c478bd9Sstevel@tonic-gate }
12607c478bd9Sstevel@tonic-gate if (instr) {
12617c478bd9Sstevel@tonic-gate *q = '\0';
12627c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s)%s\n",
12637c478bd9Sstevel@tonic-gate bufout, SHOW);
12647c478bd9Sstevel@tonic-gate }
12657c478bd9Sstevel@tonic-gate instr = 0;
12667c478bd9Sstevel@tonic-gate if (currentp >= columns)
12677c478bd9Sstevel@tonic-gate i -= currentp-columns;
12687c478bd9Sstevel@tonic-gate if (i <= 0) {
12697c478bd9Sstevel@tonic-gate /* backspace in truncated line */
12707c478bd9Sstevel@tonic-gate bufout[0] = '\0';
12717c478bd9Sstevel@tonic-gate } else if (i == 1) {
12727c478bd9Sstevel@tonic-gate /* frequent case gets special attention */
12737c478bd9Sstevel@tonic-gate (void) snprintf(bufout, BUFOUT, "%s ",
12747c478bd9Sstevel@tonic-gate BACKSPACE);
12757c478bd9Sstevel@tonic-gate } else
12767c478bd9Sstevel@tonic-gate (void) snprintf(bufout, BUFOUT, "-%d %s ", i,
12777c478bd9Sstevel@tonic-gate TAB);
12787c478bd9Sstevel@tonic-gate q = bufout + strlen(bufout);
12797c478bd9Sstevel@tonic-gate currentp -= i;
12807c478bd9Sstevel@tonic-gate break;
12817c478bd9Sstevel@tonic-gate case '\f':
12827c478bd9Sstevel@tonic-gate tabto = 0; /* optimizes */
12837c478bd9Sstevel@tonic-gate *q = '\0';
12847c478bd9Sstevel@tonic-gate if (instr)
12857c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s)%s\n",
12867c478bd9Sstevel@tonic-gate bufout, SHOW);
12877c478bd9Sstevel@tonic-gate else
12887c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", bufout);
12897c478bd9Sstevel@tonic-gate endpage(outfile);
12907c478bd9Sstevel@tonic-gate (void) startpage(outfile);
12917c478bd9Sstevel@tonic-gate current.row = start_y;
12927c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n",
12937c478bd9Sstevel@tonic-gate start_x, current.row, MOVETO);
12947c478bd9Sstevel@tonic-gate if (numberwidth)
12957c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %s\n", numberwidth +
12967c478bd9Sstevel@tonic-gate DEFAULT_SPACES_AFTER_NUMBER, TAB);
12977c478bd9Sstevel@tonic-gate q = bufout;
12987c478bd9Sstevel@tonic-gate currentp = 0;
12997c478bd9Sstevel@tonic-gate instr = 0;
13007c478bd9Sstevel@tonic-gate break;
13017c478bd9Sstevel@tonic-gate case '\r':
13027c478bd9Sstevel@tonic-gate tabto = 0; /* optimizes */
13037c478bd9Sstevel@tonic-gate if (instr) {
13047c478bd9Sstevel@tonic-gate *q = '\0';
13057c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s)%s\n",
13067c478bd9Sstevel@tonic-gate bufout, SHOW);
13077c478bd9Sstevel@tonic-gate instr = 0;
13087c478bd9Sstevel@tonic-gate q = bufout;
13097c478bd9Sstevel@tonic-gate }
13107c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %.2f %s\n",
13117c478bd9Sstevel@tonic-gate start_x, current.row, MOVETO);
13127c478bd9Sstevel@tonic-gate if (numberwidth)
13137c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%d %s\n", numberwidth +
13147c478bd9Sstevel@tonic-gate DEFAULT_SPACES_AFTER_NUMBER, TAB);
13157c478bd9Sstevel@tonic-gate currentp = 0;
13167c478bd9Sstevel@tonic-gate break;
13177c478bd9Sstevel@tonic-gate case '\\':
13187c478bd9Sstevel@tonic-gate case '(':
13197c478bd9Sstevel@tonic-gate case ')':
13207c478bd9Sstevel@tonic-gate if (currentp < columns) {
13217c478bd9Sstevel@tonic-gate if (!instr) {
13227c478bd9Sstevel@tonic-gate if (tabto) {
13237c478bd9Sstevel@tonic-gate (void) snprintf(q,
13247c478bd9Sstevel@tonic-gate BUFOUT - (q - bufout),
13257c478bd9Sstevel@tonic-gate "%d %s ", tabto, TAB);
13267c478bd9Sstevel@tonic-gate q += strlen(q);
13277c478bd9Sstevel@tonic-gate tabto = 0;
13287c478bd9Sstevel@tonic-gate }
13297c478bd9Sstevel@tonic-gate *q++ = '(';
13307c478bd9Sstevel@tonic-gate instr = 1;
13317c478bd9Sstevel@tonic-gate }
13327c478bd9Sstevel@tonic-gate *q++ = '\\';
13337c478bd9Sstevel@tonic-gate *q++ = *p;
13347c478bd9Sstevel@tonic-gate }
13357c478bd9Sstevel@tonic-gate currentp++;
13367c478bd9Sstevel@tonic-gate break;
13377c478bd9Sstevel@tonic-gate default: {
13387c478bd9Sstevel@tonic-gate /*
13397c478bd9Sstevel@tonic-gate * According to the PostScript Language Manual,
13407c478bd9Sstevel@tonic-gate * PostScript files can contain only "the printable
13417c478bd9Sstevel@tonic-gate * subset of the ASCII character set (plus the
13427c478bd9Sstevel@tonic-gate * newline marker)".
13437c478bd9Sstevel@tonic-gate */
13447c478bd9Sstevel@tonic-gate char pchar;
13457c478bd9Sstevel@tonic-gate
13467c478bd9Sstevel@tonic-gate pchar = *p;
13477c478bd9Sstevel@tonic-gate if (currentp < columns) {
13487c478bd9Sstevel@tonic-gate if (!instr) {
13497c478bd9Sstevel@tonic-gate if (tabto) {
13507c478bd9Sstevel@tonic-gate (void) snprintf(q,
13517c478bd9Sstevel@tonic-gate BUFOUT - (q - bufout),
13527c478bd9Sstevel@tonic-gate "%d %s ", tabto, TAB);
13537c478bd9Sstevel@tonic-gate q += strlen(q);
13547c478bd9Sstevel@tonic-gate tabto = 0;
13557c478bd9Sstevel@tonic-gate }
13567c478bd9Sstevel@tonic-gate *q++ = '(';
13577c478bd9Sstevel@tonic-gate instr = 1;
13587c478bd9Sstevel@tonic-gate }
13597c478bd9Sstevel@tonic-gate if (!isascii(pchar) || !isprint(pchar)) {
13607c478bd9Sstevel@tonic-gate if (iscntrl(pchar)) {
13617c478bd9Sstevel@tonic-gate if (pchar == '\177')
13627c478bd9Sstevel@tonic-gate pchar = '_';
13637c478bd9Sstevel@tonic-gate else
13647c478bd9Sstevel@tonic-gate pchar += '@';
13657c478bd9Sstevel@tonic-gate *q++ = '^';
13667c478bd9Sstevel@tonic-gate } else {
13677c478bd9Sstevel@tonic-gate *q++ = '\\';
13687c478bd9Sstevel@tonic-gate *q++ = '0' + ((pchar>>6) & 7);
13697c478bd9Sstevel@tonic-gate *q++ = '0' + ((pchar>>3) & 7);
13707c478bd9Sstevel@tonic-gate pchar = '0' + (pchar & 7);
13717c478bd9Sstevel@tonic-gate }
13727c478bd9Sstevel@tonic-gate }
13737c478bd9Sstevel@tonic-gate *q++ = pchar;
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate currentp++;
13767c478bd9Sstevel@tonic-gate break;
13777c478bd9Sstevel@tonic-gate }
13787c478bd9Sstevel@tonic-gate }
13797c478bd9Sstevel@tonic-gate if (q >= last) {
13807c478bd9Sstevel@tonic-gate *q = '\0';
13817c478bd9Sstevel@tonic-gate if (instr)
13827c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s)%s\n", bufout,
13837c478bd9Sstevel@tonic-gate SHOW);
13847c478bd9Sstevel@tonic-gate else
13857c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", bufout);
13867c478bd9Sstevel@tonic-gate q = bufout;
13877c478bd9Sstevel@tonic-gate instr = 0;
13887c478bd9Sstevel@tonic-gate }
13897c478bd9Sstevel@tonic-gate }
13907c478bd9Sstevel@tonic-gate if (instr) {
13917c478bd9Sstevel@tonic-gate (void) snprintf(q, BUFOUT - (q - bufout), ")%s", SHOW);
13927c478bd9Sstevel@tonic-gate q += strlen(q);
13937c478bd9Sstevel@tonic-gate }
13947c478bd9Sstevel@tonic-gate else
13957c478bd9Sstevel@tonic-gate *q = '\0';
13967c478bd9Sstevel@tonic-gate if (q >= last) {
13977c478bd9Sstevel@tonic-gate fatal("bufout overflow");
13987c478bd9Sstevel@tonic-gate /*NOTREACHED*/
13997c478bd9Sstevel@tonic-gate }
14007c478bd9Sstevel@tonic-gate if (bufout[0] != '\0')
14017c478bd9Sstevel@tonic-gate (void) fprintf(outfile, "%s\n", bufout);
14027c478bd9Sstevel@tonic-gate }
14037c478bd9Sstevel@tonic-gate
14047c478bd9Sstevel@tonic-gate /*
14057c478bd9Sstevel@tonic-gate * Initialize globals:
14067c478bd9Sstevel@tonic-gate * username - login name of user
14077c478bd9Sstevel@tonic-gate * hostname - name of machine on which lwlp is run
14087c478bd9Sstevel@tonic-gate * currentdate - what it says
14097c478bd9Sstevel@tonic-gate * Possible system dependencies here...
14107c478bd9Sstevel@tonic-gate */
14117c478bd9Sstevel@tonic-gate void
setup(void)14127c478bd9Sstevel@tonic-gate setup(void)
14137c478bd9Sstevel@tonic-gate {
14147c478bd9Sstevel@tonic-gate int len;
14157c478bd9Sstevel@tonic-gate char *p;
14167c478bd9Sstevel@tonic-gate long t;
14177c478bd9Sstevel@tonic-gate struct utsname utsname;
14187c478bd9Sstevel@tonic-gate struct passwd *pw;
14197c478bd9Sstevel@tonic-gate
14207c478bd9Sstevel@tonic-gate if ((p = getlogin()) == (char *)NULL) {
14217c478bd9Sstevel@tonic-gate if ((pw = getpwuid(getuid())) == (struct passwd *)NULL)
14227c478bd9Sstevel@tonic-gate p = "Whoknows";
14237c478bd9Sstevel@tonic-gate else
14247c478bd9Sstevel@tonic-gate p = pw->pw_name;
14257c478bd9Sstevel@tonic-gate endpwent();
14267c478bd9Sstevel@tonic-gate }
14277c478bd9Sstevel@tonic-gate username = strdup(p);
14287c478bd9Sstevel@tonic-gate
14297c478bd9Sstevel@tonic-gate (void) uname(&utsname);
14307c478bd9Sstevel@tonic-gate hostname = strdup(utsname.nodename);
14317c478bd9Sstevel@tonic-gate
14327c478bd9Sstevel@tonic-gate t = time((long *)0);
14337c478bd9Sstevel@tonic-gate p = ctime(&t);
14347c478bd9Sstevel@tonic-gate len = strlen(p);
14357c478bd9Sstevel@tonic-gate *(p + len - 1) = '\0'; /* zap the newline character */
14367c478bd9Sstevel@tonic-gate currentdate = strdup(p);
14377c478bd9Sstevel@tonic-gate current.font = DEFAULT_FONT;
14387c478bd9Sstevel@tonic-gate }
14397c478bd9Sstevel@tonic-gate
14407c478bd9Sstevel@tonic-gate /*
14417c478bd9Sstevel@tonic-gate * Special version of fgets
14427c478bd9Sstevel@tonic-gate * Read until a formfeed, newline, or overflow
14437c478bd9Sstevel@tonic-gate * If a formfeed is the first character, return it immediately
14447c478bd9Sstevel@tonic-gate * If a formfeed is found after the first character, replace it by a newline
14457c478bd9Sstevel@tonic-gate * and push the formfeed back onto the input stream
14467c478bd9Sstevel@tonic-gate * A special case is a formfeed followed by a newline in which case the
14477c478bd9Sstevel@tonic-gate * newline is ignored
14487c478bd9Sstevel@tonic-gate * The input buffer will be null-terminated and will *not* end with a newline
14497c478bd9Sstevel@tonic-gate * The buffer size n includes the null
14507c478bd9Sstevel@tonic-gate */
14517c478bd9Sstevel@tonic-gate char *
fgetline(char * s,int n,FILE * iop)14527c478bd9Sstevel@tonic-gate fgetline(char *s, int n, FILE *iop)
14537c478bd9Sstevel@tonic-gate {
14547c478bd9Sstevel@tonic-gate int ch;
14557c478bd9Sstevel@tonic-gate char *cs;
14567c478bd9Sstevel@tonic-gate
14577c478bd9Sstevel@tonic-gate if (n < 2) {
14587c478bd9Sstevel@tonic-gate fatal("fgetline called with bad buffer size!?");
14597c478bd9Sstevel@tonic-gate /*NOTREACHED*/
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate
14627c478bd9Sstevel@tonic-gate cs = s;
14637c478bd9Sstevel@tonic-gate n--; /* the null */
14647c478bd9Sstevel@tonic-gate
14657c478bd9Sstevel@tonic-gate /*
14667c478bd9Sstevel@tonic-gate * Check out the special cases
14677c478bd9Sstevel@tonic-gate */
14687c478bd9Sstevel@tonic-gate if ((ch = getc(iop)) == EOF)
14697c478bd9Sstevel@tonic-gate return ((char *)NULL);
14707c478bd9Sstevel@tonic-gate if (ch == '\f') {
14717c478bd9Sstevel@tonic-gate if ((ch = getc(iop)) != '\n') {
14727c478bd9Sstevel@tonic-gate /*
14737c478bd9Sstevel@tonic-gate * If EOF was just read it will be noticed
14747c478bd9Sstevel@tonic-gate * next time through
14757c478bd9Sstevel@tonic-gate */
14767c478bd9Sstevel@tonic-gate if (ungetc(ch, iop) == EOF && !feof(iop)) {
14777c478bd9Sstevel@tonic-gate /*
14787c478bd9Sstevel@tonic-gate * Shouldn't happen since a getc()
14797c478bd9Sstevel@tonic-gate * was just done
14807c478bd9Sstevel@tonic-gate */
14817c478bd9Sstevel@tonic-gate fatal("fgetline - ungetc failed");
14827c478bd9Sstevel@tonic-gate /*NOTREACHED*/
14837c478bd9Sstevel@tonic-gate }
14847c478bd9Sstevel@tonic-gate }
14857c478bd9Sstevel@tonic-gate *cs++ = '\f';
14867c478bd9Sstevel@tonic-gate *cs = '\0';
14877c478bd9Sstevel@tonic-gate return (s);
14887c478bd9Sstevel@tonic-gate }
14897c478bd9Sstevel@tonic-gate
14907c478bd9Sstevel@tonic-gate /*
14917c478bd9Sstevel@tonic-gate * Check for "weird" input characters is made in proc()
14927c478bd9Sstevel@tonic-gate */
14937c478bd9Sstevel@tonic-gate while (n-- > 0) {
14947c478bd9Sstevel@tonic-gate if (ch == '\f' || ch == '\n')
14957c478bd9Sstevel@tonic-gate break;
14967c478bd9Sstevel@tonic-gate *cs++ = ch;
14977c478bd9Sstevel@tonic-gate if ((ch = getc(iop)) == EOF)
14987c478bd9Sstevel@tonic-gate break;
14997c478bd9Sstevel@tonic-gate }
15007c478bd9Sstevel@tonic-gate
15017c478bd9Sstevel@tonic-gate if (ch == EOF && cs == s) /* Nothing was read */
15027c478bd9Sstevel@tonic-gate return ((char *)NULL);
15037c478bd9Sstevel@tonic-gate if (ch == '\f') {
15047c478bd9Sstevel@tonic-gate if (ungetc(ch, iop) == EOF)
15057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "fgetline - can't ungetc??\n");
15067c478bd9Sstevel@tonic-gate } else if (ch != '\n' && ch != EOF) {
15077c478bd9Sstevel@tonic-gate fatal("fgetline - input line too long");
15087c478bd9Sstevel@tonic-gate /*NOTREACHED*/
15097c478bd9Sstevel@tonic-gate }
15107c478bd9Sstevel@tonic-gate *cs = '\0';
15117c478bd9Sstevel@tonic-gate return (s);
15127c478bd9Sstevel@tonic-gate }
15137c478bd9Sstevel@tonic-gate
15147c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
15157c478bd9Sstevel@tonic-gate void
fatal(char * fmt,...)15167c478bd9Sstevel@tonic-gate fatal(char *fmt, ...)
15177c478bd9Sstevel@tonic-gate {
15187c478bd9Sstevel@tonic-gate va_list ap;
15197c478bd9Sstevel@tonic-gate
15207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", progname);
15217c478bd9Sstevel@tonic-gate va_start(ap, fmt);
15227c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, fmt, ap);
15237c478bd9Sstevel@tonic-gate va_end(ap);
15247c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
15257c478bd9Sstevel@tonic-gate exit(1);
15267c478bd9Sstevel@tonic-gate /*NOTREACHED*/
15277c478bd9Sstevel@tonic-gate }
1528