1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 char copyright[] = 15 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 16 All rights reserved.\n"; 17 #endif /* not lint */ 18 19 #ifndef lint 20 static char sccsid[] = "@(#)vpsf.c 5.2 (Berkeley) 03/08/88"; 21 #endif /* not lint */ 22 23 /* 24 * Versatec printer filter 25 * make wide listings by placing pages side by side 26 */ 27 28 #include <stdio.h> 29 #include <sys/vcmd.h> 30 31 #define LINELN 440 32 #define PAGELN 86 33 #define LMARG 10 34 35 int pltmode[] = {VPLOT}; 36 int prtmode[] = {VPRINT}; 37 38 char screen[PAGELN][LINELN]; 39 char ul[PAGELN][LINELN]; 40 char anyul[PAGELN]; 41 int origin; /* first column of a page */ 42 int origin_ind; /* origin plus indent */ 43 int outline; /* current line number */ 44 int outcol; /* current column number */ 45 int npages; 46 int width = 106; /* default page width */ 47 int length = 86; /* default page length */ 48 int indent = 0; /* default indent */ 49 50 int literal; 51 char *name; /* user's login name */ 52 char *host; /* user's machine name */ 53 char *acctfile; /* accounting information file */ 54 55 main(argc, argv) 56 int argc; 57 char *argv[]; 58 { 59 register int i; 60 61 while (--argc) { 62 if (*(*++argv) == '-') { 63 switch (argv[0][1]) { 64 case 'n': 65 argc--; 66 name = *++argv; 67 break; 68 69 case 'h': 70 argc--; 71 host = *++argv; 72 break; 73 74 case 'w': 75 if ((i = atoi(&argv[0][2])) > 0 && i <= LINELN) 76 width = i; 77 break; 78 79 case 'l': 80 if ((i = atoi(&argv[0][2])) > 0 && i <= PAGELN) 81 length = i; 82 break; 83 84 case 'i': 85 if ((i = atoi(&argv[0][2])) >= 0 && 86 i < LINELN - 1) 87 indent = i; 88 break; 89 90 case 'c': /* Print input without throwing away 91 control chars and without putting 92 in page breaks. */ 93 literal++; 94 break; 95 } 96 } else 97 acctfile = *argv; 98 } 99 indent += literal ? 1 : LMARG; 100 if (indent >= width) 101 indent = width - 1; 102 103 /* 104 * input file is open on file descriptor 0. 105 * vp should be open on file descriptor 1. 106 * The error log file is open on file descriptor 2. 107 */ 108 ioctl(1, VSETSTATE, prtmode); 109 process(); 110 111 /* 112 * Put out an extra null to ensure versatec will get an even 113 * number of good characters. 114 */ 115 putchar('\0'); 116 117 if (ferror(stdout)) 118 exit(1); 119 if (name && acctfile && access(acctfile, 02) >= 0 && 120 freopen(acctfile, "a", stdout) != NULL) { 121 if (host) 122 printf("%7.2f\t%s:%s\n", (float)npages, host, name); 123 else 124 printf("%7.2f\t%s\n", (float)npages, name); 125 } 126 exit(0); 127 } 128 129 set_up() 130 { 131 clear(screen, sizeof(screen)); 132 origin = 0; 133 origin_ind = outcol = origin + indent; 134 outline = 0; 135 cutmark(origin); 136 } 137 138 process() 139 { 140 register int c; 141 142 set_up(); 143 144 while ((c = getchar()) != EOF) 145 switch (c) { 146 case ' ': 147 outcol++; 148 break; 149 150 case '\t': 151 outcol = ((outcol - origin_ind) | 07) + origin_ind + 1; 152 break; 153 154 case '\b': 155 if (outcol > origin_ind) 156 outcol--; 157 break; 158 159 case '\r': 160 outcol = origin_ind; 161 break; 162 163 case '\f': 164 outline = length; 165 /* fall into ... */ 166 167 case '\n': 168 if (++outline >= length) { 169 origin += width + 1; 170 origin_ind += width + 1; 171 cutmark(origin); 172 if (origin + width + 1 >= LINELN) { 173 oflush(); 174 break; 175 } 176 outline = 0; 177 } 178 outcol = origin_ind; 179 break; 180 181 default: 182 outchar(c); 183 break; 184 } 185 186 if (outline || origin) { 187 cutmark(origin + width + 1); 188 oflush(); 189 } 190 printf("\n\n\n\n\n"); 191 } 192 193 outchar(c) 194 register int c; 195 { 196 register char *cp; 197 register int d; 198 199 if (!literal && (c < 040 || c >= 0177)) 200 return; 201 if (outcol >= origin + width + 1) { 202 outcol++; 203 return; 204 } 205 cp = &screen[outline][outcol]; 206 d = *cp; 207 if (d != ' ') { 208 if (d == '_' || c == '_') { 209 if (c == d) { 210 outcol++; 211 return; 212 } 213 if (anyul[outline] == 0) 214 clear(ul[outline], LINELN); 215 anyul[outline] = 1; 216 ul[outline][outcol] = 0377; 217 if (c == '_') 218 c = d; 219 } 220 } 221 *cp = c; 222 outcol++; 223 } 224 225 oflush() 226 { 227 register char *cp, *dp; 228 register int i, j, oc, dc, c; 229 230 npages++; 231 putchar('\n'); 232 for (i = 0; i < length; i++) 233 putline(i); 234 for (i = 0; i < LINELN; i++) 235 putchar('_'); 236 putchar('\n'); 237 238 set_up(); 239 } 240 241 clear(cp, i) 242 register char *cp; 243 register int i; 244 { 245 if (i > 0) 246 do 247 *cp++ = ' '; 248 while (--i); 249 } 250 251 cutmark(o) 252 register int o; 253 { 254 register int i; 255 256 screen[0][o] = '|'; 257 screen[1][o] = '|'; 258 screen[length - 1][o] = '|'; 259 screen[length - 2][o] = '|'; 260 } 261 262 putline(n) 263 register int n; 264 { 265 register char *cp; 266 register int j; 267 268 fwrite(screen[n], sizeof(char), sizeof(screen[0]), stdout); 269 if (anyul[n]) { 270 putchar('\n'); 271 putchar('\0'); 272 fflush(stdout); 273 ioctl(1, VSETSTATE, pltmode); 274 cp = ul[n]; 275 j = LINELN; 276 do { 277 putchar(*cp & 0377); 278 putchar(*cp++ & 0377); 279 } while (--j); 280 fflush(stdout); 281 ioctl(1, VSETSTATE, prtmode); 282 } else 283 putchar('\n'); 284 if (ferror(stdout)) 285 exit(1); 286 } 287