1 /*
2  * Copyright (c) 1987 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 the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1987 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)sidebyside.c	1.4 (Berkeley) 06/30/88";
26 #endif /* not lint */
27 
28 #include <stdio.h>
29 /*
30  * sidebyside -- make wide listings by placing pages side by side
31  */
32 int	width = 90;
33 
34 #define	LINELN 440
35 #define	EJLINE	86
36 #define	LMARG	10
37 
38 char	screen[EJLINE][LINELN];
39 char	ul[EJLINE][LINELN];
40 char	anyul[EJLINE];
41 int	frame;
42 int	origin;
43 int	outline;
44 int	outcol;
45 
46 main(argc, argv)
47 	int argc;
48 	char *argv[];
49 {
50 
51 	argc--, argv++;
52 	while (argc > 0 && argv[0][0] == '-') {
53 		switch (argv[0][1]) {
54 
55 		case 'w':
56 			width = atoi(argv[0]+2);
57 			break;
58 
59 		default:
60 			fprintf(stderr, "usage: sidebyside [ -wwidth ] file ...\n");
61 			break;
62 		}
63 		argc--, argv++;
64 	}
65 	clear(screen, EJLINE * LINELN);
66 	origin = LMARG;
67 	outcol = LMARG;
68 	cutmark(LMARG);
69 	do {
70 		if (argc > 0) {
71 			if (freopen(argv[0], "r", stdin) == NULL) {
72 				perror(argv[0]);
73 				argc--, argv++;
74 				continue;
75 			}
76 			argc--, argv++;
77 		}
78 		process();
79 	} while (argc > 0);
80 	exit(0);
81 }
82 
83 process()
84 {
85 	char linebuf[BUFSIZ];
86 	register char *cp;
87 	register int c;
88 
89 	while (fgets(linebuf, sizeof linebuf, stdin)) {
90 		for (cp = linebuf; c = *cp; cp++) switch (c) {
91 
92 		case '\t':
93 			do {
94 				int ooutcol = outcol;
95 				outchar(' ');
96 				if (outcol == ooutcol)
97 					break;
98 			} while ((outcol - origin) % 8 != 0);
99 			break;
100 
101 		case '\b':
102 			if (outcol > origin)
103 				outcol--;
104 			break;
105 
106 		case '\r':
107 			outcol = origin + LMARG;
108 			break;
109 
110 		case '\f':
111 			outline = EJLINE - 1;
112 			/* fall into ... */
113 
114 		case '\n':
115 			outline++;
116 			if (outline == EJLINE) {
117 				origin += width;
118 				if (origin + width > LINELN) {
119 					cutmark(origin);
120 					oflush();
121 					break;
122 				}
123 /*
124 				if (origin * 2 + LMARG < LINELN && origin * 3 > LINELN) {
125 					cutmark(origin);
126 					origin += LMARG;
127 				}
128 */
129 				outline = 0;
130 				cutmark(origin);
131 			}
132 			outcol = origin;
133 			break;
134 
135 		default:
136 			outchar(c);
137 			break;
138 		}
139 	}
140 	if (outline || origin != LMARG) {
141 		cutmark(origin + width);
142 		oflush();
143 	}
144 }
145 
146 outchar(c)
147 	register int c;
148 {
149 	register char *cp = screen[outline];
150 	register char *up;
151 	register int d;
152 
153 	if (c < 040 || c >= 0177)
154 		return;
155 	if (outcol < LINELN) {
156 		cp += outcol;
157 		d = *cp;
158 		if (d == ' ') {
159 			*cp = c;
160 			outcol++;
161 			return;
162 		}
163 		if (d == '_' || c == '_') {
164 			if (c == d) {
165 				outcol++;
166 				return;
167 			}
168 			if (anyul[outline] == 0)
169 				clear(ul[outline], LINELN);
170 			anyul[outline] = 1;
171 			ul[outline][outcol] = '_';
172 			if (c == '_')
173 				c = d;
174 		}
175 		*cp = c;
176 		outcol++;
177 	}
178 }
179 
180 oflush()
181 {
182 	register char *cp, *dp;
183 	register int i, j, oc, dc, c;
184 
185 	frame++;
186 /*
187 	if (frame > 1) {
188 		printf("\n\n\n");
189 		for (j = 0; j < LINELN; j++)
190 			putchar('_');
191 		printf("\n");
192 	}
193 */
194 	printf("\n");
195 	for (i = 0; i < EJLINE; i++) {
196 		putline(screen[i]);
197 		if (anyul[i]) {
198 			putchar('\r');
199 			putline(ul[i]);
200 			anyul[i] = 0;
201 		}
202 		putchar('\n');
203 	}
204 	for (i = 0; i < LINELN; i++)
205 		putchar('_');
206 	putchar('\n');
207 	clear(screen, EJLINE * LINELN);
208 	outline = 0;
209 	outcol = LMARG;
210 	origin = LMARG;
211 	cutmark(LMARG);
212 }
213 
214 clear(cp, i)
215 	register char *cp;
216 	register int i;
217 {
218 
219 	if (i > 0)
220 		do
221 			*cp++ = ' ';
222 		while (--i);
223 }
224 
225 cutmark(o)
226 	register int o;
227 {
228 	register int i;
229 
230 	screen[0][o - LMARG] = '|';
231 	screen[1][o - LMARG] = '|';
232 	screen[EJLINE - 1][o - LMARG] = '|';
233 	screen[EJLINE - 2][o - LMARG] = '|';
234 }
235 
236 putline(cp)
237 	register char *cp;
238 {
239 	register int j = LINELN;
240 	register int c, oc, dc;
241 
242 	oc = dc = 0;
243 	do {
244 		if ((c = *cp++) == ' ') {
245 			dc++;
246 			continue;
247 		}
248 		while (((oc + 8) &~ 7) < dc) {
249 			putchar('\t');
250 			oc = (oc + 8) &~ 7;
251 		}
252 		while (oc < dc) {
253 			putchar(' ');
254 			oc++;
255 		}
256 		putchar(c);
257 		oc++, dc++;
258 	} while (--j != 0);
259 }
260