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