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