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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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