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