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
main(argc,argv)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
set_up()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
process()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
outchar(c)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
oflush()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
clear(cp,i)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
cutmark(o)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
putline(n)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