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