Commit | Line | Data |
---|---|---|
c155beb2 | 1 | static char *sccsid = "@(#)col.c 4.2 (Berkeley) %G%"; |
faa0f83d BJ |
2 | # include <stdio.h> |
3 | # define PL 256 | |
4 | # define ESC '\033' | |
5 | # define RLF '\013' | |
6 | # define SI '\017' | |
7 | # define SO '\016' | |
8 | # define GREEK 0200 | |
9 | # define LINELN 800 | |
10 | ||
11 | char *page[PL]; | |
12 | char lbuff [LINELN], *line; | |
13 | int bflag, hflag, fflag; | |
14 | int half; | |
15 | int cp, lp; | |
16 | int ll, llh, mustwr; | |
17 | int pcp = 0; | |
18 | char *pgmname; | |
19 | char *strcpy(); | |
20 | ||
21 | main (argc, argv) | |
22 | int argc; char **argv; | |
23 | { | |
24 | int i; | |
25 | int greek; | |
26 | register int c; | |
faa0f83d | 27 | |
faa0f83d BJ |
28 | pgmname = argv[0]; |
29 | ||
30 | for (i = 1; i < argc; i++) { | |
31 | register char *p; | |
32 | if (*argv[i] != '-') { | |
33 | fprintf (stderr, "%s: bad option %s\n", | |
34 | pgmname, argv[i]); | |
35 | exit (2); | |
36 | } | |
37 | for (p = argv[i]+1; *p; p++) { | |
38 | switch (*p) { | |
39 | case 'b': | |
40 | bflag++; | |
41 | break; | |
42 | ||
43 | case 'h': | |
44 | hflag++; | |
45 | break; | |
46 | ||
47 | case 'f': | |
48 | fflag++; | |
49 | break; | |
50 | ||
51 | default: | |
52 | fprintf (stderr, "%s: bad option letter %c\n", | |
53 | pgmname, *p); | |
54 | exit (2); | |
55 | } | |
56 | } | |
57 | } | |
58 | ||
59 | for (ll=0; ll<PL; ll++) | |
60 | page[ll] = 0; | |
61 | ||
62 | cp = 0; | |
63 | ll = 0; | |
64 | greek = 0; | |
65 | mustwr = PL; | |
66 | line = lbuff; | |
67 | ||
68 | while ((c = getchar()) != EOF) { | |
69 | switch (c) { | |
70 | case '\n': | |
71 | incr(); | |
72 | incr(); | |
73 | cp = 0; | |
74 | continue; | |
75 | ||
76 | case '\0': | |
77 | continue; | |
78 | ||
79 | case ESC: | |
80 | c = getchar(); | |
81 | switch (c) { | |
82 | case '7': /* reverse full line feed */ | |
83 | decr(); | |
84 | decr(); | |
85 | break; | |
86 | ||
87 | case '8': /* reverse half line feed */ | |
88 | if (fflag) | |
89 | decr(); | |
90 | else { | |
91 | if (--half < -1) { | |
92 | decr(); | |
93 | decr(); | |
94 | half += 2; | |
95 | } | |
96 | } | |
97 | break; | |
98 | ||
99 | case '9': /* forward half line feed */ | |
100 | if (fflag) | |
101 | incr(); | |
102 | else { | |
103 | if (++half > 0) { | |
104 | incr(); | |
105 | incr(); | |
106 | half -= 2; | |
107 | } | |
108 | } | |
109 | break; | |
110 | } | |
111 | continue; | |
112 | ||
113 | case SO: | |
114 | greek = GREEK; | |
115 | continue; | |
116 | ||
117 | case SI: | |
118 | greek = 0; | |
119 | continue; | |
120 | ||
121 | case RLF: | |
122 | decr(); | |
123 | decr(); | |
124 | continue; | |
125 | ||
126 | case '\r': | |
127 | cp = 0; | |
128 | continue; | |
129 | ||
130 | case '\t': | |
131 | cp = (cp + 8) & -8; | |
132 | continue; | |
133 | ||
134 | case '\b': | |
135 | if (cp > 0) | |
136 | cp--; | |
137 | continue; | |
138 | ||
139 | case ' ': | |
140 | cp++; | |
141 | continue; | |
142 | ||
143 | default: | |
144 | c &= 0177; | |
145 | if (c > 040 && c < 0177) { /* if printable */ | |
146 | outc(c | greek); | |
147 | cp++; | |
148 | } | |
149 | continue; | |
150 | } | |
151 | } | |
152 | ||
153 | for (i=0; i<PL; i++) | |
154 | if (page[(mustwr+i)%PL] != 0) | |
155 | emit (page[(mustwr+i) % PL], mustwr+i-PL); | |
156 | emit (" ", (llh + 1) & -2); | |
157 | exit(0); | |
158 | } | |
159 | ||
160 | outc (c) | |
161 | register char c; | |
162 | { | |
163 | if (lp > cp) { | |
164 | line = lbuff; | |
165 | lp = 0; | |
166 | } | |
167 | ||
168 | while (lp < cp) { | |
169 | switch (*line) { | |
170 | case '\0': | |
171 | *line = ' '; | |
172 | lp++; | |
173 | break; | |
174 | ||
175 | case '\b': | |
176 | lp--; | |
177 | break; | |
178 | ||
179 | default: | |
180 | lp++; | |
181 | } | |
182 | line++; | |
183 | } | |
184 | while (*line == '\b') { | |
185 | line += 2; | |
186 | } | |
187 | if (bflag || *line == '\0' || *line == ' ') | |
188 | *line = c; | |
189 | else { | |
190 | register char c1, c2, c3; | |
191 | c1 = *++line; | |
192 | *line++ = '\b'; | |
193 | c2 = *line; | |
194 | *line++ = c; | |
195 | while (c1) { | |
196 | c3 = *line; | |
197 | *line++ = c1; | |
198 | c1 = c2; | |
199 | c2 = c3; | |
200 | } | |
201 | lp = 0; | |
202 | line = lbuff; | |
203 | } | |
204 | } | |
205 | ||
206 | store (lno) | |
207 | { | |
208 | char *malloc(); | |
209 | ||
210 | lno %= PL; | |
211 | if (page[lno] != 0) | |
212 | free (page[lno]); | |
213 | page[lno] = malloc((unsigned)strlen(lbuff) + 2); | |
214 | if (page[lno] == 0) { | |
215 | fprintf (stderr, "%s: no storage\n", pgmname); | |
216 | exit (2); | |
217 | } | |
218 | strcpy (page[lno],lbuff); | |
219 | } | |
220 | ||
221 | fetch(lno) | |
222 | { | |
223 | register char *p; | |
224 | ||
225 | lno %= PL; | |
226 | p = lbuff; | |
227 | while (*p) | |
228 | *p++ = '\0'; | |
229 | line = lbuff; | |
230 | lp = 0; | |
231 | if (page[lno]) | |
232 | strcpy (line, page[lno]); | |
233 | } | |
234 | emit (s, lineno) | |
235 | char *s; | |
236 | int lineno; | |
237 | { | |
238 | static int cline = 0; | |
239 | register int ncp; | |
240 | register char *p; | |
241 | static int gflag = 0; | |
242 | ||
243 | if (*s) { | |
244 | while (cline < lineno - 1) { | |
245 | putchar ('\n'); | |
246 | pcp = 0; | |
247 | cline += 2; | |
248 | } | |
249 | if (cline != lineno) { | |
250 | putchar (ESC); | |
251 | putchar ('9'); | |
252 | cline++; | |
253 | } | |
254 | if (pcp) | |
255 | putchar ('\r'); | |
256 | pcp = 0; | |
257 | p = s; | |
258 | while (*p) { | |
259 | ncp = pcp; | |
260 | while (*p++ == ' ') { | |
261 | if ((++ncp & 7) == 0 && hflag) { | |
262 | pcp = ncp; | |
263 | putchar ('\t'); | |
264 | } | |
265 | } | |
266 | if (!*--p) | |
267 | break; | |
268 | while (pcp < ncp) { | |
269 | putchar (' '); | |
270 | pcp++; | |
271 | } | |
272 | if (gflag != (*p & GREEK) && *p != '\b') { | |
273 | if (gflag) | |
274 | putchar (SI); | |
275 | else | |
276 | putchar (SO); | |
277 | gflag ^= GREEK; | |
278 | } | |
279 | putchar (*p & ~GREEK); | |
280 | if (*p++ == '\b') | |
281 | pcp--; | |
282 | else | |
283 | pcp++; | |
284 | } | |
285 | } | |
286 | } | |
287 | ||
288 | incr() | |
289 | { | |
290 | store (ll++); | |
291 | if (ll > llh) | |
292 | llh = ll; | |
293 | if (ll >= mustwr && page[ll%PL]) { | |
294 | emit (page[ll%PL], ll - PL); | |
295 | mustwr++; | |
296 | free (page[ll%PL]); | |
297 | page[ll%PL] = 0; | |
298 | } | |
299 | fetch (ll); | |
300 | } | |
301 | ||
302 | decr() | |
303 | { | |
304 | if (ll > mustwr - PL) { | |
305 | store (ll--); | |
306 | fetch (ll); | |
307 | } | |
308 | } |