139855Sbostic /*
2*62001Sbostic * Copyright (c) 1989, 1993
3*62001Sbostic * The Regents of the University of California. All rights reserved.
439855Sbostic *
539855Sbostic * This code is derived from software contributed to Berkeley by
639855Sbostic * Robert Corbett.
739855Sbostic *
842683Sbostic * %sccs.include.redist.c%
939855Sbostic */
1039851Sbostic
1139855Sbostic #ifndef lint
12*62001Sbostic static char copyright[] =
13*62001Sbostic "@(#) Copyright (c) 1989, 1993\n\
14*62001Sbostic The Regents of the University of California. All rights reserved.\n";
1539855Sbostic #endif /* not lint */
1639855Sbostic
1739855Sbostic #ifndef lint
18*62001Sbostic static char sccsid[] = "@(#)fpr.c 8.1 (Berkeley) 06/06/93";
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
main()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
init()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
gettext()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
savech(col)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
flush()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--;
33346315Storek 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
nospace()38039851Sbostic nospace()
38139851Sbostic {
38239851Sbostic fputs("Storage limit exceeded.\n", stderr);
38339851Sbostic exit(1);
38439851Sbostic }
385