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