xref: /original-bsd/old/vfilters/vpsf/vpsf.c (revision abe165e9)
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