Research V7 development
[unix-history] / usr / src / cmd / col.c
CommitLineData
e05e0a37
KT
1# include <stdio.h>
2
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
11char *page[PL];
12char lbuff [LINELN], *line;
13int bflag, xflag, fflag;
14int half;
15int cp, lp;
16int ll, llh, mustwr;
17int pcp = 0;
18char *pgmname;
19char *strcpy();
20
21main (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 'x':
46 xflag++;
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 return 0;
160}
161
162outc (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
208store (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
223fetch(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}
236emit (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 if (gflag) {
247 putchar (SI);
248 gflag = 0;
249 }
250 while (cline < lineno - 1) {
251 putchar ('\n');
252 pcp = 0;
253 cline += 2;
254 }
255 if (cline != lineno) {
256 putchar (ESC);
257 putchar ('9');
258 cline++;
259 }
260 if (pcp)
261 putchar ('\r');
262 pcp = 0;
263 p = s;
264 while (*p) {
265 ncp = pcp;
266 while (*p++ == ' ') {
267 if ((++ncp & 7) == 0 && !xflag) {
268 pcp = ncp;
269 putchar ('\t');
270 }
271 }
272 if (!*--p)
273 break;
274 while (pcp < ncp) {
275 putchar (' ');
276 pcp++;
277 }
278 if (gflag != (*p & GREEK) && *p != '\b') {
279 if (gflag)
280 putchar (SI);
281 else
282 putchar (SO);
283 gflag ^= GREEK;
284 }
285 putchar (*p & ~GREEK);
286 if (*p++ == '\b')
287 pcp--;
288 else
289 pcp++;
290 }
291 }
292}
293
294incr()
295{
296 store (ll++);
297 if (ll > llh)
298 llh = ll;
299 if (ll >= mustwr && page[ll%PL]) {
300 emit (page[ll%PL], ll - PL);
301 mustwr++;
302 free (page[ll%PL]);
303 page[ll%PL] = 0;
304 }
305 fetch (ll);
306}
307
308decr()
309{
310 if (ll > mustwr - PL) {
311 store (ll--);
312 fetch (ll);
313 }
314}