xref: /csrg-svn/usr.bin/fpr/fpr.c (revision 62001)
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