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