1*39855Sbostic /* 2*39855Sbostic * Copyright (c) 1989 The Regents of the University of California. 3*39855Sbostic * All rights reserved. 4*39855Sbostic * 5*39855Sbostic * This code is derived from software contributed to Berkeley by 6*39855Sbostic * Robert Corbett. 7*39855Sbostic * 8*39855Sbostic * Redistribution and use in source and binary forms are permitted 9*39855Sbostic * provided that the above copyright notice and this paragraph are 10*39855Sbostic * duplicated in all such forms and that any documentation, 11*39855Sbostic * advertising materials, and other materials related to such 12*39855Sbostic * distribution and use acknowledge that the software was developed 13*39855Sbostic * by the University of California, Berkeley. The name of the 14*39855Sbostic * University may not be used to endorse or promote products derived 15*39855Sbostic * from this software without specific prior written permission. 16*39855Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*39855Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*39855Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*39855Sbostic */ 2039851Sbostic 21*39855Sbostic #ifndef lint 22*39855Sbostic char copyright[] = 23*39855Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 24*39855Sbostic All rights reserved.\n"; 25*39855Sbostic #endif /* not lint */ 26*39855Sbostic 27*39855Sbostic #ifndef lint 28*39855Sbostic static char sccsid[] = "@(#)fpr.c 5.2 (Berkeley) 01/03/90"; 29*39855Sbostic #endif /* not lint */ 30*39855Sbostic 3139851Sbostic #include <stdio.h> 3239851Sbostic 3339851Sbostic #define BLANK ' ' 3439851Sbostic #define TAB '\t' 3539851Sbostic #define NUL '\000' 3639851Sbostic #define FF '\f' 3739851Sbostic #define BS '\b' 3839851Sbostic #define CR '\r' 3939851Sbostic #define VTAB '\013' 4039851Sbostic #define EOL '\n' 4139851Sbostic 4239851Sbostic #define TRUE 1 4339851Sbostic #define FALSE 0 4439851Sbostic 4539851Sbostic #define MAXCOL 170 4639851Sbostic #define TABSIZE 8 4739851Sbostic #define INITWIDTH 8 4839851Sbostic 4939851Sbostic typedef 5039851Sbostic struct column 5139851Sbostic { 5239851Sbostic int count; 5339851Sbostic int width; 5439851Sbostic char *str; 5539851Sbostic } 5639851Sbostic COLUMN; 5739851Sbostic 5839851Sbostic char cc; 5939851Sbostic char saved; 6039851Sbostic int length; 6139851Sbostic char *text; 6239851Sbostic int highcol; 6339851Sbostic COLUMN *line; 6439851Sbostic int maxpos; 6539851Sbostic int maxcol; 6639851Sbostic 6739851Sbostic extern char *malloc(); 6839851Sbostic extern char *calloc(); 6939851Sbostic extern char *realloc(); 7039851Sbostic 7139851Sbostic 7239851Sbostic 7339851Sbostic main() 7439851Sbostic { 7539851Sbostic register int ch; 7639851Sbostic register char ateof; 7739851Sbostic register int i; 7839851Sbostic register int errorcount; 7939851Sbostic 8039851Sbostic 8139851Sbostic init(); 8239851Sbostic errorcount = 0; 8339851Sbostic ateof = FALSE; 8439851Sbostic 8539851Sbostic ch = getchar(); 8639851Sbostic if (ch == EOF) 8739851Sbostic exit(0); 8839851Sbostic 8939851Sbostic if (ch == EOL) 9039851Sbostic { 9139851Sbostic cc = NUL; 9239851Sbostic ungetc((int) EOL, stdin); 9339851Sbostic } 9439851Sbostic else if (ch == BLANK) 9539851Sbostic cc = NUL; 9639851Sbostic else if (ch == '1') 9739851Sbostic cc = FF; 9839851Sbostic else if (ch == '0') 9939851Sbostic cc = EOL; 10039851Sbostic else if (ch == '+') 10139851Sbostic cc = CR; 10239851Sbostic else 10339851Sbostic { 10439851Sbostic errorcount = 1; 10539851Sbostic cc = NUL; 10639851Sbostic ungetc(ch, stdin); 10739851Sbostic } 10839851Sbostic 10939851Sbostic while ( ! ateof) 11039851Sbostic { 11139851Sbostic gettext(); 11239851Sbostic ch = getchar(); 11339851Sbostic if (ch == EOF) 11439851Sbostic { 11539851Sbostic flush(); 11639851Sbostic ateof = TRUE; 11739851Sbostic } 11839851Sbostic else if (ch == EOL) 11939851Sbostic { 12039851Sbostic flush(); 12139851Sbostic cc = NUL; 12239851Sbostic ungetc((int) EOL, stdin); 12339851Sbostic } 12439851Sbostic else if (ch == BLANK) 12539851Sbostic { 12639851Sbostic flush(); 12739851Sbostic cc = NUL; 12839851Sbostic } 12939851Sbostic else if (ch == '1') 13039851Sbostic { 13139851Sbostic flush(); 13239851Sbostic cc = FF; 13339851Sbostic } 13439851Sbostic else if (ch == '0') 13539851Sbostic { 13639851Sbostic flush(); 13739851Sbostic cc = EOL; 13839851Sbostic } 13939851Sbostic else if (ch == '+') 14039851Sbostic { 14139851Sbostic for (i = 0; i < length; i++) 14239851Sbostic savech(i); 14339851Sbostic } 14439851Sbostic else 14539851Sbostic { 14639851Sbostic errorcount++; 14739851Sbostic flush(); 14839851Sbostic cc = NUL; 14939851Sbostic ungetc(ch, stdin); 15039851Sbostic } 15139851Sbostic } 15239851Sbostic 15339851Sbostic if (errorcount == 1) 15439851Sbostic fprintf(stderr, "Illegal carriage control - 1 line.\n"); 15539851Sbostic else if (errorcount > 1) 15639851Sbostic fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount); 15739851Sbostic 15839851Sbostic exit(0); 15939851Sbostic } 16039851Sbostic 16139851Sbostic 16239851Sbostic 16339851Sbostic init() 16439851Sbostic { 16539851Sbostic register COLUMN *cp; 16639851Sbostic register COLUMN *cend; 16739851Sbostic register char *sp; 16839851Sbostic 16939851Sbostic 17039851Sbostic length = 0; 17139851Sbostic maxpos = MAXCOL; 17239851Sbostic sp = malloc((unsigned) maxpos); 17339851Sbostic if (sp == NULL) 17439851Sbostic nospace(); 17539851Sbostic text = sp; 17639851Sbostic 17739851Sbostic highcol = -1; 17839851Sbostic maxcol = MAXCOL; 17939851Sbostic line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN)); 18039851Sbostic if (line == NULL) 18139851Sbostic nospace(); 18239851Sbostic cp = line; 18339851Sbostic cend = line + (maxcol-1); 18439851Sbostic while (cp <= cend) 18539851Sbostic { 18639851Sbostic cp->width = INITWIDTH; 18739851Sbostic sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 18839851Sbostic if (sp == NULL) 18939851Sbostic nospace(); 19039851Sbostic cp->str = sp; 19139851Sbostic cp++; 19239851Sbostic } 19339851Sbostic } 19439851Sbostic 19539851Sbostic 19639851Sbostic 19739851Sbostic gettext() 19839851Sbostic { 19939851Sbostic register int i; 20039851Sbostic register char ateol; 20139851Sbostic register int ch; 20239851Sbostic register int pos; 20339851Sbostic 20439851Sbostic 20539851Sbostic i = 0; 20639851Sbostic ateol = FALSE; 20739851Sbostic 20839851Sbostic while ( ! ateol) 20939851Sbostic { 21039851Sbostic ch = getchar(); 21139851Sbostic if (ch == EOL || ch == EOF) 21239851Sbostic ateol = TRUE; 21339851Sbostic else if (ch == TAB) 21439851Sbostic { 21539851Sbostic pos = (1 + i/TABSIZE) * TABSIZE; 21639851Sbostic if (pos > maxpos) 21739851Sbostic { 21839851Sbostic maxpos = pos + 10; 21939851Sbostic text = realloc(text, (unsigned) maxpos); 22039851Sbostic if (text == NULL) 22139851Sbostic nospace(); 22239851Sbostic } 22339851Sbostic while (i < pos) 22439851Sbostic { 22539851Sbostic text[i] = BLANK; 22639851Sbostic i++; 22739851Sbostic } 22839851Sbostic } 22939851Sbostic else if (ch == BS) 23039851Sbostic { 23139851Sbostic if (i > 0) 23239851Sbostic { 23339851Sbostic i--; 23439851Sbostic savech(i); 23539851Sbostic } 23639851Sbostic } 23739851Sbostic else if (ch == CR) 23839851Sbostic { 23939851Sbostic while (i > 0) 24039851Sbostic { 24139851Sbostic i--; 24239851Sbostic savech(i); 24339851Sbostic } 24439851Sbostic } 24539851Sbostic else if (ch == FF || ch == VTAB) 24639851Sbostic { 24739851Sbostic flush(); 24839851Sbostic cc = ch; 24939851Sbostic i = 0; 25039851Sbostic } 25139851Sbostic else 25239851Sbostic { 25339851Sbostic if (i >= maxpos) 25439851Sbostic { 25539851Sbostic maxpos = i + 10; 25639851Sbostic text = realloc(text, (unsigned) maxpos); 25739851Sbostic if (text == NULL) 25839851Sbostic nospace(); 25939851Sbostic } 26039851Sbostic text[i] = ch; 26139851Sbostic i++; 26239851Sbostic } 26339851Sbostic } 26439851Sbostic 26539851Sbostic length = i; 26639851Sbostic } 26739851Sbostic 26839851Sbostic 26939851Sbostic 27039851Sbostic savech(col) 27139851Sbostic int col; 27239851Sbostic { 27339851Sbostic register char ch; 27439851Sbostic register int oldmax; 27539851Sbostic register COLUMN *cp; 27639851Sbostic register COLUMN *cend; 27739851Sbostic register char *sp; 27839851Sbostic register int newcount; 27939851Sbostic 28039851Sbostic 28139851Sbostic ch = text[col]; 28239851Sbostic if (ch == BLANK) 28339851Sbostic return; 28439851Sbostic 28539851Sbostic saved = TRUE; 28639851Sbostic 28739851Sbostic if (col >= highcol) 28839851Sbostic highcol = col; 28939851Sbostic 29039851Sbostic if (col >= maxcol) 29139851Sbostic { 29239851Sbostic oldmax = maxcol; 29339851Sbostic maxcol = col + 10; 29439851Sbostic line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN)); 29539851Sbostic if (line == NULL) 29639851Sbostic nospace(); 29739851Sbostic cp = line + oldmax; 29839851Sbostic cend = line + (maxcol - 1); 29939851Sbostic while (cp <= cend) 30039851Sbostic { 30139851Sbostic cp->width = INITWIDTH; 30239851Sbostic cp->count = 0; 30339851Sbostic sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 30439851Sbostic if (sp == NULL) 30539851Sbostic nospace(); 30639851Sbostic cp->str = sp; 30739851Sbostic cp++; 30839851Sbostic } 30939851Sbostic } 31039851Sbostic 31139851Sbostic cp = line + col; 31239851Sbostic newcount = cp->count + 1; 31339851Sbostic if (newcount > cp->width) 31439851Sbostic { 31539851Sbostic cp->width = newcount; 31639851Sbostic sp = realloc(cp->str, (unsigned) newcount*sizeof(char)); 31739851Sbostic if (sp == NULL) 31839851Sbostic nospace(); 31939851Sbostic cp->str = sp; 32039851Sbostic } 32139851Sbostic cp->count = newcount; 32239851Sbostic cp->str[newcount-1] = ch; 32339851Sbostic } 32439851Sbostic 32539851Sbostic 32639851Sbostic 32739851Sbostic flush() 32839851Sbostic { 32939851Sbostic register int i; 33039851Sbostic register int anchor; 33139851Sbostic register int height; 33239851Sbostic register int j; 33339851Sbostic 33439851Sbostic 33539851Sbostic if (cc != NUL) 33639851Sbostic putchar(cc); 33739851Sbostic 33839851Sbostic if ( ! saved) 33939851Sbostic { 34039851Sbostic i = length; 34139851Sbostic while (i > 0 && text[i-1] == BLANK) 34239851Sbostic i--; 34339851Sbostic length == i; 34439851Sbostic for (i = 0; i < length; i++) 34539851Sbostic putchar(text[i]); 34639851Sbostic putchar(EOL); 34739851Sbostic return; 34839851Sbostic } 34939851Sbostic 35039851Sbostic for (i =0; i < length; i++) 35139851Sbostic savech(i); 35239851Sbostic 35339851Sbostic anchor = 0; 35439851Sbostic while (anchor <= highcol) 35539851Sbostic { 35639851Sbostic height = line[anchor].count; 35739851Sbostic if (height == 0) 35839851Sbostic { 35939851Sbostic putchar(BLANK); 36039851Sbostic anchor++; 36139851Sbostic } 36239851Sbostic else if (height == 1) 36339851Sbostic { 36439851Sbostic putchar( *(line[anchor].str) ); 36539851Sbostic line[anchor].count = 0; 36639851Sbostic anchor++; 36739851Sbostic } 36839851Sbostic else 36939851Sbostic { 37039851Sbostic i = anchor; 37139851Sbostic while (i < highcol && line[i+1].count > 1) 37239851Sbostic i++; 37339851Sbostic for (j = anchor; j <= i; j++) 37439851Sbostic { 37539851Sbostic height = line[j].count - 1; 37639851Sbostic putchar(line[j].str[height]); 37739851Sbostic line[j].count = height; 37839851Sbostic } 37939851Sbostic for (j = anchor; j <= i; j++) 38039851Sbostic putchar(BS); 38139851Sbostic } 38239851Sbostic } 38339851Sbostic 38439851Sbostic putchar(EOL); 38539851Sbostic highcol = -1; 38639851Sbostic } 38739851Sbostic 38839851Sbostic 38939851Sbostic 39039851Sbostic nospace() 39139851Sbostic { 39239851Sbostic fputs("Storage limit exceeded.\n", stderr); 39339851Sbostic exit(1); 39439851Sbostic } 395