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