139855Sbostic /* 239855Sbostic * Copyright (c) 1989 The Regents of the University of California. 339855Sbostic * All rights reserved. 439855Sbostic * 539855Sbostic * This code is derived from software contributed to Berkeley by 639855Sbostic * Robert Corbett. 739855Sbostic * 8*42683Sbostic * %sccs.include.redist.c% 939855Sbostic */ 1039851Sbostic 1139855Sbostic #ifndef lint 1239855Sbostic char copyright[] = 1339855Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 1439855Sbostic All rights reserved.\n"; 1539855Sbostic #endif /* not lint */ 1639855Sbostic 1739855Sbostic #ifndef lint 18*42683Sbostic static char sccsid[] = "@(#)fpr.c 5.3 (Berkeley) 06/01/90"; 1939855Sbostic #endif /* not lint */ 2039855Sbostic 2139851Sbostic #include <stdio.h> 2239851Sbostic 2339851Sbostic #define BLANK ' ' 2439851Sbostic #define TAB '\t' 2539851Sbostic #define NUL '\000' 2639851Sbostic #define FF '\f' 2739851Sbostic #define BS '\b' 2839851Sbostic #define CR '\r' 2939851Sbostic #define VTAB '\013' 3039851Sbostic #define EOL '\n' 3139851Sbostic 3239851Sbostic #define TRUE 1 3339851Sbostic #define FALSE 0 3439851Sbostic 3539851Sbostic #define MAXCOL 170 3639851Sbostic #define TABSIZE 8 3739851Sbostic #define INITWIDTH 8 3839851Sbostic 3939851Sbostic typedef 4039851Sbostic struct column 4139851Sbostic { 4239851Sbostic int count; 4339851Sbostic int width; 4439851Sbostic char *str; 4539851Sbostic } 4639851Sbostic COLUMN; 4739851Sbostic 4839851Sbostic char cc; 4939851Sbostic char saved; 5039851Sbostic int length; 5139851Sbostic char *text; 5239851Sbostic int highcol; 5339851Sbostic COLUMN *line; 5439851Sbostic int maxpos; 5539851Sbostic int maxcol; 5639851Sbostic 5739851Sbostic extern char *malloc(); 5839851Sbostic extern char *calloc(); 5939851Sbostic extern char *realloc(); 6039851Sbostic 6139851Sbostic 6239851Sbostic 6339851Sbostic main() 6439851Sbostic { 6539851Sbostic register int ch; 6639851Sbostic register char ateof; 6739851Sbostic register int i; 6839851Sbostic register int errorcount; 6939851Sbostic 7039851Sbostic 7139851Sbostic init(); 7239851Sbostic errorcount = 0; 7339851Sbostic ateof = FALSE; 7439851Sbostic 7539851Sbostic ch = getchar(); 7639851Sbostic if (ch == EOF) 7739851Sbostic exit(0); 7839851Sbostic 7939851Sbostic if (ch == EOL) 8039851Sbostic { 8139851Sbostic cc = NUL; 8239851Sbostic ungetc((int) EOL, stdin); 8339851Sbostic } 8439851Sbostic else if (ch == BLANK) 8539851Sbostic cc = NUL; 8639851Sbostic else if (ch == '1') 8739851Sbostic cc = FF; 8839851Sbostic else if (ch == '0') 8939851Sbostic cc = EOL; 9039851Sbostic else if (ch == '+') 9139851Sbostic cc = CR; 9239851Sbostic else 9339851Sbostic { 9439851Sbostic errorcount = 1; 9539851Sbostic cc = NUL; 9639851Sbostic ungetc(ch, stdin); 9739851Sbostic } 9839851Sbostic 9939851Sbostic while ( ! ateof) 10039851Sbostic { 10139851Sbostic gettext(); 10239851Sbostic ch = getchar(); 10339851Sbostic if (ch == EOF) 10439851Sbostic { 10539851Sbostic flush(); 10639851Sbostic ateof = TRUE; 10739851Sbostic } 10839851Sbostic else if (ch == EOL) 10939851Sbostic { 11039851Sbostic flush(); 11139851Sbostic cc = NUL; 11239851Sbostic ungetc((int) EOL, stdin); 11339851Sbostic } 11439851Sbostic else if (ch == BLANK) 11539851Sbostic { 11639851Sbostic flush(); 11739851Sbostic cc = NUL; 11839851Sbostic } 11939851Sbostic else if (ch == '1') 12039851Sbostic { 12139851Sbostic flush(); 12239851Sbostic cc = FF; 12339851Sbostic } 12439851Sbostic else if (ch == '0') 12539851Sbostic { 12639851Sbostic flush(); 12739851Sbostic cc = EOL; 12839851Sbostic } 12939851Sbostic else if (ch == '+') 13039851Sbostic { 13139851Sbostic for (i = 0; i < length; i++) 13239851Sbostic savech(i); 13339851Sbostic } 13439851Sbostic else 13539851Sbostic { 13639851Sbostic errorcount++; 13739851Sbostic flush(); 13839851Sbostic cc = NUL; 13939851Sbostic ungetc(ch, stdin); 14039851Sbostic } 14139851Sbostic } 14239851Sbostic 14339851Sbostic if (errorcount == 1) 14439851Sbostic fprintf(stderr, "Illegal carriage control - 1 line.\n"); 14539851Sbostic else if (errorcount > 1) 14639851Sbostic fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount); 14739851Sbostic 14839851Sbostic exit(0); 14939851Sbostic } 15039851Sbostic 15139851Sbostic 15239851Sbostic 15339851Sbostic init() 15439851Sbostic { 15539851Sbostic register COLUMN *cp; 15639851Sbostic register COLUMN *cend; 15739851Sbostic register char *sp; 15839851Sbostic 15939851Sbostic 16039851Sbostic length = 0; 16139851Sbostic maxpos = MAXCOL; 16239851Sbostic sp = malloc((unsigned) maxpos); 16339851Sbostic if (sp == NULL) 16439851Sbostic nospace(); 16539851Sbostic text = sp; 16639851Sbostic 16739851Sbostic highcol = -1; 16839851Sbostic maxcol = MAXCOL; 16939851Sbostic line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN)); 17039851Sbostic if (line == NULL) 17139851Sbostic nospace(); 17239851Sbostic cp = line; 17339851Sbostic cend = line + (maxcol-1); 17439851Sbostic while (cp <= cend) 17539851Sbostic { 17639851Sbostic cp->width = INITWIDTH; 17739851Sbostic sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 17839851Sbostic if (sp == NULL) 17939851Sbostic nospace(); 18039851Sbostic cp->str = sp; 18139851Sbostic cp++; 18239851Sbostic } 18339851Sbostic } 18439851Sbostic 18539851Sbostic 18639851Sbostic 18739851Sbostic gettext() 18839851Sbostic { 18939851Sbostic register int i; 19039851Sbostic register char ateol; 19139851Sbostic register int ch; 19239851Sbostic register int pos; 19339851Sbostic 19439851Sbostic 19539851Sbostic i = 0; 19639851Sbostic ateol = FALSE; 19739851Sbostic 19839851Sbostic while ( ! ateol) 19939851Sbostic { 20039851Sbostic ch = getchar(); 20139851Sbostic if (ch == EOL || ch == EOF) 20239851Sbostic ateol = TRUE; 20339851Sbostic else if (ch == TAB) 20439851Sbostic { 20539851Sbostic pos = (1 + i/TABSIZE) * TABSIZE; 20639851Sbostic if (pos > maxpos) 20739851Sbostic { 20839851Sbostic maxpos = pos + 10; 20939851Sbostic text = realloc(text, (unsigned) maxpos); 21039851Sbostic if (text == NULL) 21139851Sbostic nospace(); 21239851Sbostic } 21339851Sbostic while (i < pos) 21439851Sbostic { 21539851Sbostic text[i] = BLANK; 21639851Sbostic i++; 21739851Sbostic } 21839851Sbostic } 21939851Sbostic else if (ch == BS) 22039851Sbostic { 22139851Sbostic if (i > 0) 22239851Sbostic { 22339851Sbostic i--; 22439851Sbostic savech(i); 22539851Sbostic } 22639851Sbostic } 22739851Sbostic else if (ch == CR) 22839851Sbostic { 22939851Sbostic while (i > 0) 23039851Sbostic { 23139851Sbostic i--; 23239851Sbostic savech(i); 23339851Sbostic } 23439851Sbostic } 23539851Sbostic else if (ch == FF || ch == VTAB) 23639851Sbostic { 23739851Sbostic flush(); 23839851Sbostic cc = ch; 23939851Sbostic i = 0; 24039851Sbostic } 24139851Sbostic else 24239851Sbostic { 24339851Sbostic if (i >= maxpos) 24439851Sbostic { 24539851Sbostic maxpos = i + 10; 24639851Sbostic text = realloc(text, (unsigned) maxpos); 24739851Sbostic if (text == NULL) 24839851Sbostic nospace(); 24939851Sbostic } 25039851Sbostic text[i] = ch; 25139851Sbostic i++; 25239851Sbostic } 25339851Sbostic } 25439851Sbostic 25539851Sbostic length = i; 25639851Sbostic } 25739851Sbostic 25839851Sbostic 25939851Sbostic 26039851Sbostic savech(col) 26139851Sbostic int col; 26239851Sbostic { 26339851Sbostic register char ch; 26439851Sbostic register int oldmax; 26539851Sbostic register COLUMN *cp; 26639851Sbostic register COLUMN *cend; 26739851Sbostic register char *sp; 26839851Sbostic register int newcount; 26939851Sbostic 27039851Sbostic 27139851Sbostic ch = text[col]; 27239851Sbostic if (ch == BLANK) 27339851Sbostic return; 27439851Sbostic 27539851Sbostic saved = TRUE; 27639851Sbostic 27739851Sbostic if (col >= highcol) 27839851Sbostic highcol = col; 27939851Sbostic 28039851Sbostic if (col >= maxcol) 28139851Sbostic { 28239851Sbostic oldmax = maxcol; 28339851Sbostic maxcol = col + 10; 28439851Sbostic line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN)); 28539851Sbostic if (line == NULL) 28639851Sbostic nospace(); 28739851Sbostic cp = line + oldmax; 28839851Sbostic cend = line + (maxcol - 1); 28939851Sbostic while (cp <= cend) 29039851Sbostic { 29139851Sbostic cp->width = INITWIDTH; 29239851Sbostic cp->count = 0; 29339851Sbostic sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 29439851Sbostic if (sp == NULL) 29539851Sbostic nospace(); 29639851Sbostic cp->str = sp; 29739851Sbostic cp++; 29839851Sbostic } 29939851Sbostic } 30039851Sbostic 30139851Sbostic cp = line + col; 30239851Sbostic newcount = cp->count + 1; 30339851Sbostic if (newcount > cp->width) 30439851Sbostic { 30539851Sbostic cp->width = newcount; 30639851Sbostic sp = realloc(cp->str, (unsigned) newcount*sizeof(char)); 30739851Sbostic if (sp == NULL) 30839851Sbostic nospace(); 30939851Sbostic cp->str = sp; 31039851Sbostic } 31139851Sbostic cp->count = newcount; 31239851Sbostic cp->str[newcount-1] = ch; 31339851Sbostic } 31439851Sbostic 31539851Sbostic 31639851Sbostic 31739851Sbostic flush() 31839851Sbostic { 31939851Sbostic register int i; 32039851Sbostic register int anchor; 32139851Sbostic register int height; 32239851Sbostic register int j; 32339851Sbostic 32439851Sbostic 32539851Sbostic if (cc != NUL) 32639851Sbostic putchar(cc); 32739851Sbostic 32839851Sbostic if ( ! saved) 32939851Sbostic { 33039851Sbostic i = length; 33139851Sbostic while (i > 0 && text[i-1] == BLANK) 33239851Sbostic i--; 33339851Sbostic length == i; 33439851Sbostic for (i = 0; i < length; i++) 33539851Sbostic putchar(text[i]); 33639851Sbostic putchar(EOL); 33739851Sbostic return; 33839851Sbostic } 33939851Sbostic 34039851Sbostic for (i =0; i < length; i++) 34139851Sbostic savech(i); 34239851Sbostic 34339851Sbostic anchor = 0; 34439851Sbostic while (anchor <= highcol) 34539851Sbostic { 34639851Sbostic height = line[anchor].count; 34739851Sbostic if (height == 0) 34839851Sbostic { 34939851Sbostic putchar(BLANK); 35039851Sbostic anchor++; 35139851Sbostic } 35239851Sbostic else if (height == 1) 35339851Sbostic { 35439851Sbostic putchar( *(line[anchor].str) ); 35539851Sbostic line[anchor].count = 0; 35639851Sbostic anchor++; 35739851Sbostic } 35839851Sbostic else 35939851Sbostic { 36039851Sbostic i = anchor; 36139851Sbostic while (i < highcol && line[i+1].count > 1) 36239851Sbostic i++; 36339851Sbostic for (j = anchor; j <= i; j++) 36439851Sbostic { 36539851Sbostic height = line[j].count - 1; 36639851Sbostic putchar(line[j].str[height]); 36739851Sbostic line[j].count = height; 36839851Sbostic } 36939851Sbostic for (j = anchor; j <= i; j++) 37039851Sbostic putchar(BS); 37139851Sbostic } 37239851Sbostic } 37339851Sbostic 37439851Sbostic putchar(EOL); 37539851Sbostic highcol = -1; 37639851Sbostic } 37739851Sbostic 37839851Sbostic 37939851Sbostic 38039851Sbostic nospace() 38139851Sbostic { 38239851Sbostic fputs("Storage limit exceeded.\n", stderr); 38339851Sbostic exit(1); 38439851Sbostic } 385