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