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