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