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