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