|
|
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.