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