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