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