|
|
1.1 ! root 1: ! 2: #include <stdio.h> ! 3: ! 4: #define BLANK ' ' ! 5: #define TAB '\t' ! 6: #define NUL '\000' ! 7: #define FF '\f' ! 8: #define BS '\b' ! 9: #define CR '\r' ! 10: #define VTAB '\013' ! 11: #define EOL '\n' ! 12: ! 13: #define TRUE 1 ! 14: #define FALSE 0 ! 15: ! 16: #define MAXCOL 170 ! 17: #define TABSIZE 8 ! 18: #define INITWIDTH 8 ! 19: ! 20: typedef ! 21: struct column ! 22: { ! 23: int count; ! 24: int width; ! 25: char *str; ! 26: } ! 27: COLUMN; ! 28: ! 29: char cc; ! 30: char saved; ! 31: int length; ! 32: char *text; ! 33: int highcol; ! 34: COLUMN *line; ! 35: int maxpos; ! 36: int maxcol; ! 37: ! 38: extern char *malloc(); ! 39: extern char *calloc(); ! 40: extern char *realloc(); ! 41: ! 42: ! 43: ! 44: main() ! 45: { ! 46: register int ch; ! 47: register char ateof; ! 48: register int i; ! 49: register int errorcount; ! 50: ! 51: ! 52: init(); ! 53: errorcount = 0; ! 54: ateof = FALSE; ! 55: ! 56: ch = getchar(); ! 57: if (ch == EOF) ! 58: exit(0); ! 59: ! 60: if (ch == EOL) ! 61: { ! 62: cc = NUL; ! 63: ungetc((int) EOL, stdin); ! 64: } ! 65: else if (ch == BLANK) ! 66: cc = NUL; ! 67: else if (ch == '1') ! 68: cc = FF; ! 69: else if (ch == '0') ! 70: cc = EOL; ! 71: else if (ch == '+') ! 72: cc = CR; ! 73: else ! 74: { ! 75: errorcount = 1; ! 76: cc = NUL; ! 77: ungetc(ch, stdin); ! 78: } ! 79: ! 80: while ( ! ateof) ! 81: { ! 82: gettext(); ! 83: ch = getchar(); ! 84: if (ch == EOF) ! 85: { ! 86: flush(); ! 87: ateof = TRUE; ! 88: } ! 89: else if (ch == EOL) ! 90: { ! 91: flush(); ! 92: cc = NUL; ! 93: ungetc((int) EOL, stdin); ! 94: } ! 95: else if (ch == BLANK) ! 96: { ! 97: flush(); ! 98: cc = NUL; ! 99: } ! 100: else if (ch == '1') ! 101: { ! 102: flush(); ! 103: cc = FF; ! 104: } ! 105: else if (ch == '0') ! 106: { ! 107: flush(); ! 108: cc = EOL; ! 109: } ! 110: else if (ch == '+') ! 111: { ! 112: for (i = 0; i < length; i++) ! 113: savech(i); ! 114: } ! 115: else ! 116: { ! 117: errorcount++; ! 118: flush(); ! 119: cc = NUL; ! 120: ungetc(ch, stdin); ! 121: } ! 122: } ! 123: ! 124: if (errorcount == 1) ! 125: fprintf(stderr, "Illegal carriage control - 1 line.\n"); ! 126: else if (errorcount > 1) ! 127: fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount); ! 128: ! 129: exit(0); ! 130: } ! 131: ! 132: ! 133: ! 134: init() ! 135: { ! 136: register COLUMN *cp; ! 137: register COLUMN *cend; ! 138: register char *sp; ! 139: ! 140: ! 141: length = 0; ! 142: maxpos = MAXCOL; ! 143: sp = malloc((unsigned) maxpos); ! 144: if (sp == NULL) ! 145: nospace(); ! 146: text = sp; ! 147: ! 148: highcol = -1; ! 149: maxcol = MAXCOL; ! 150: line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN)); ! 151: if (line == NULL) ! 152: nospace(); ! 153: cp = line; ! 154: cend = line + (maxcol-1); ! 155: while (cp <= cend) ! 156: { ! 157: cp->width = INITWIDTH; ! 158: sp = calloc(INITWIDTH, (unsigned) sizeof(char)); ! 159: if (sp == NULL) ! 160: nospace(); ! 161: cp->str = sp; ! 162: cp++; ! 163: } ! 164: } ! 165: ! 166: ! 167: ! 168: gettext() ! 169: { ! 170: register int i; ! 171: register char ateol; ! 172: register int ch; ! 173: register int pos; ! 174: ! 175: ! 176: i = 0; ! 177: ateol = FALSE; ! 178: ! 179: while ( ! ateol) ! 180: { ! 181: ch = getchar(); ! 182: if (ch == EOL || ch == EOF) ! 183: ateol = TRUE; ! 184: else if (ch == TAB) ! 185: { ! 186: pos = (1 + i/TABSIZE) * TABSIZE; ! 187: if (pos > maxpos) ! 188: { ! 189: maxpos = pos + 10; ! 190: text = realloc(text, (unsigned) maxpos); ! 191: if (text == NULL) ! 192: nospace(); ! 193: } ! 194: while (i < pos) ! 195: { ! 196: text[i] = BLANK; ! 197: i++; ! 198: } ! 199: } ! 200: else if (ch == BS) ! 201: { ! 202: if (i > 0) ! 203: { ! 204: i--; ! 205: savech(i); ! 206: } ! 207: } ! 208: else if (ch == CR) ! 209: { ! 210: while (i > 0) ! 211: { ! 212: i--; ! 213: savech(i); ! 214: } ! 215: } ! 216: else if (ch == FF || ch == VTAB) ! 217: { ! 218: flush(); ! 219: cc = ch; ! 220: i = 0; ! 221: } ! 222: else ! 223: { ! 224: if (i >= maxpos) ! 225: { ! 226: maxpos = i + 10; ! 227: text = realloc(text, (unsigned) maxpos); ! 228: if (text == NULL) ! 229: nospace(); ! 230: } ! 231: text[i] = ch; ! 232: i++; ! 233: } ! 234: } ! 235: ! 236: length = i; ! 237: } ! 238: ! 239: ! 240: ! 241: savech(col) ! 242: int col; ! 243: { ! 244: register char ch; ! 245: register int oldmax; ! 246: register COLUMN *cp; ! 247: register COLUMN *cend; ! 248: register char *sp; ! 249: register int newcount; ! 250: ! 251: ! 252: ch = text[col]; ! 253: if (ch == BLANK) ! 254: return; ! 255: ! 256: saved = TRUE; ! 257: ! 258: if (col >= highcol) ! 259: highcol = col; ! 260: ! 261: if (col >= maxcol) ! 262: { ! 263: oldmax = maxcol; ! 264: maxcol = col + 10; ! 265: line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN)); ! 266: if (line == NULL) ! 267: nospace(); ! 268: cp = line + oldmax; ! 269: cend = line + (maxcol - 1); ! 270: while (cp <= cend) ! 271: { ! 272: cp->width = INITWIDTH; ! 273: cp->count = 0; ! 274: sp = calloc(INITWIDTH, (unsigned) sizeof(char)); ! 275: if (sp == NULL) ! 276: nospace(); ! 277: cp->str = sp; ! 278: cp++; ! 279: } ! 280: } ! 281: ! 282: cp = line + col; ! 283: newcount = cp->count + 1; ! 284: if (newcount > cp->width) ! 285: { ! 286: cp->width = newcount; ! 287: sp = realloc(cp->str, (unsigned) newcount*sizeof(char)); ! 288: if (sp == NULL) ! 289: nospace(); ! 290: cp->str = sp; ! 291: } ! 292: cp->count = newcount; ! 293: cp->str[newcount-1] = ch; ! 294: } ! 295: ! 296: ! 297: ! 298: flush() ! 299: { ! 300: register int i; ! 301: register int anchor; ! 302: register int height; ! 303: register int j; ! 304: ! 305: ! 306: if (cc != NUL) ! 307: putchar(cc); ! 308: ! 309: if ( ! saved) ! 310: { ! 311: i = length; ! 312: while (i > 0 && text[i-1] == BLANK) ! 313: i--; ! 314: length == i; ! 315: for (i = 0; i < length; i++) ! 316: putchar(text[i]); ! 317: putchar(EOL); ! 318: return; ! 319: } ! 320: ! 321: for (i =0; i < length; i++) ! 322: savech(i); ! 323: ! 324: anchor = 0; ! 325: while (anchor <= highcol) ! 326: { ! 327: height = line[anchor].count; ! 328: if (height == 0) ! 329: { ! 330: putchar(BLANK); ! 331: anchor++; ! 332: } ! 333: else if (height == 1) ! 334: { ! 335: putchar( *(line[anchor].str) ); ! 336: line[anchor].count = 0; ! 337: anchor++; ! 338: } ! 339: else ! 340: { ! 341: i = anchor; ! 342: while (i < highcol && line[i+1].count > 1) ! 343: i++; ! 344: for (j = anchor; j <= i; j++) ! 345: { ! 346: height = line[j].count - 1; ! 347: putchar(line[j].str[height]); ! 348: line[j].count = height; ! 349: } ! 350: for (j = anchor; j <= i; j++) ! 351: putchar(BS); ! 352: } ! 353: } ! 354: ! 355: putchar(EOL); ! 356: highcol = -1; ! 357: } ! 358: ! 359: ! 360: ! 361: nospace() ! 362: { ! 363: fputs("Storage limit exceeded.\n", stderr); ! 364: exit(1); ! 365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.