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