xref: /original-bsd/usr.bin/fpr/fpr.c (revision 7b7e71b4)
1a5a93be1Sbostic /*
2*7b7e71b4Sbostic  * Copyright (c) 1989, 1993
3*7b7e71b4Sbostic  *	The Regents of the University of California.  All rights reserved.
4a5a93be1Sbostic  *
5a5a93be1Sbostic  * This code is derived from software contributed to Berkeley by
6a5a93be1Sbostic  * Robert Corbett.
7a5a93be1Sbostic  *
81808f06cSbostic  * %sccs.include.redist.c%
9a5a93be1Sbostic  */
10a5a93be1Sbostic 
11a5a93be1Sbostic #ifndef lint
12*7b7e71b4Sbostic static char copyright[] =
13*7b7e71b4Sbostic "@(#) Copyright (c) 1989, 1993\n\
14*7b7e71b4Sbostic 	The Regents of the University of California.  All rights reserved.\n";
15a5a93be1Sbostic #endif /* not lint */
16a5a93be1Sbostic 
17a5a93be1Sbostic #ifndef lint
18*7b7e71b4Sbostic static char sccsid[] = "@(#)fpr.c	8.1 (Berkeley) 06/06/93";
19a5a93be1Sbostic #endif /* not lint */
20d95cfb93Sbostic 
21d95cfb93Sbostic #include <stdio.h>
22d95cfb93Sbostic 
23d95cfb93Sbostic #define BLANK ' '
24d95cfb93Sbostic #define TAB '\t'
25d95cfb93Sbostic #define NUL '\000'
26d95cfb93Sbostic #define FF '\f'
27d95cfb93Sbostic #define BS '\b'
28d95cfb93Sbostic #define CR '\r'
29d95cfb93Sbostic #define VTAB '\013'
30d95cfb93Sbostic #define EOL '\n'
31d95cfb93Sbostic 
32d95cfb93Sbostic #define TRUE 1
33d95cfb93Sbostic #define FALSE 0
34d95cfb93Sbostic 
35d95cfb93Sbostic #define MAXCOL 170
36d95cfb93Sbostic #define TABSIZE 8
37d95cfb93Sbostic #define INITWIDTH 8
38d95cfb93Sbostic 
39d95cfb93Sbostic typedef
40d95cfb93Sbostic   struct column
41d95cfb93Sbostic     {
42d95cfb93Sbostic       int count;
43d95cfb93Sbostic       int width;
44d95cfb93Sbostic       char *str;
45d95cfb93Sbostic     }
46d95cfb93Sbostic   COLUMN;
47d95cfb93Sbostic 
48d95cfb93Sbostic char cc;
49d95cfb93Sbostic char saved;
50d95cfb93Sbostic int length;
51d95cfb93Sbostic char *text;
52d95cfb93Sbostic int highcol;
53d95cfb93Sbostic COLUMN *line;
54d95cfb93Sbostic int maxpos;
55d95cfb93Sbostic int maxcol;
56d95cfb93Sbostic 
57d95cfb93Sbostic extern char *malloc();
58d95cfb93Sbostic extern char *calloc();
59d95cfb93Sbostic extern char *realloc();
60d95cfb93Sbostic 
61d95cfb93Sbostic 
62d95cfb93Sbostic 
main()63d95cfb93Sbostic main()
64d95cfb93Sbostic {
65d95cfb93Sbostic   register int ch;
66d95cfb93Sbostic   register char ateof;
67d95cfb93Sbostic   register int i;
68d95cfb93Sbostic   register int errorcount;
69d95cfb93Sbostic 
70d95cfb93Sbostic 
71d95cfb93Sbostic   init();
72d95cfb93Sbostic   errorcount = 0;
73d95cfb93Sbostic   ateof = FALSE;
74d95cfb93Sbostic 
75d95cfb93Sbostic   ch = getchar();
76d95cfb93Sbostic   if (ch == EOF)
77d95cfb93Sbostic     exit(0);
78d95cfb93Sbostic 
79d95cfb93Sbostic   if (ch == EOL)
80d95cfb93Sbostic     {
81d95cfb93Sbostic       cc = NUL;
82d95cfb93Sbostic       ungetc((int) EOL, stdin);
83d95cfb93Sbostic     }
84d95cfb93Sbostic   else if (ch == BLANK)
85d95cfb93Sbostic     cc = NUL;
86d95cfb93Sbostic   else if (ch == '1')
87d95cfb93Sbostic     cc = FF;
88d95cfb93Sbostic   else if (ch == '0')
89d95cfb93Sbostic     cc = EOL;
90d95cfb93Sbostic   else if (ch == '+')
91d95cfb93Sbostic     cc = CR;
92d95cfb93Sbostic   else
93d95cfb93Sbostic     {
94d95cfb93Sbostic       errorcount = 1;
95d95cfb93Sbostic       cc = NUL;
96d95cfb93Sbostic       ungetc(ch, stdin);
97d95cfb93Sbostic     }
98d95cfb93Sbostic 
99d95cfb93Sbostic   while ( ! ateof)
100d95cfb93Sbostic     {
101d95cfb93Sbostic       gettext();
102d95cfb93Sbostic       ch = getchar();
103d95cfb93Sbostic       if (ch == EOF)
104d95cfb93Sbostic 	{
105d95cfb93Sbostic 	  flush();
106d95cfb93Sbostic 	  ateof = TRUE;
107d95cfb93Sbostic 	}
108d95cfb93Sbostic       else if (ch == EOL)
109d95cfb93Sbostic 	{
110d95cfb93Sbostic 	  flush();
111d95cfb93Sbostic 	  cc = NUL;
112d95cfb93Sbostic 	  ungetc((int) EOL, stdin);
113d95cfb93Sbostic 	}
114d95cfb93Sbostic       else if (ch == BLANK)
115d95cfb93Sbostic 	{
116d95cfb93Sbostic 	  flush();
117d95cfb93Sbostic 	  cc = NUL;
118d95cfb93Sbostic 	}
119d95cfb93Sbostic       else if (ch == '1')
120d95cfb93Sbostic 	{
121d95cfb93Sbostic 	  flush();
122d95cfb93Sbostic 	  cc = FF;
123d95cfb93Sbostic 	}
124d95cfb93Sbostic       else if (ch == '0')
125d95cfb93Sbostic 	{
126d95cfb93Sbostic 	  flush();
127d95cfb93Sbostic 	  cc = EOL;
128d95cfb93Sbostic 	}
129d95cfb93Sbostic       else if (ch == '+')
130d95cfb93Sbostic 	{
131d95cfb93Sbostic 	  for (i = 0; i < length; i++)
132d95cfb93Sbostic 	    savech(i);
133d95cfb93Sbostic 	}
134d95cfb93Sbostic       else
135d95cfb93Sbostic 	{
136d95cfb93Sbostic 	  errorcount++;
137d95cfb93Sbostic 	  flush();
138d95cfb93Sbostic 	  cc = NUL;
139d95cfb93Sbostic 	  ungetc(ch, stdin);
140d95cfb93Sbostic 	}
141d95cfb93Sbostic     }
142d95cfb93Sbostic 
143d95cfb93Sbostic   if (errorcount == 1)
144d95cfb93Sbostic     fprintf(stderr, "Illegal carriage control - 1 line.\n");
145d95cfb93Sbostic   else if (errorcount > 1)
146d95cfb93Sbostic     fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount);
147d95cfb93Sbostic 
148d95cfb93Sbostic   exit(0);
149d95cfb93Sbostic }
150d95cfb93Sbostic 
151d95cfb93Sbostic 
152d95cfb93Sbostic 
init()153d95cfb93Sbostic init()
154d95cfb93Sbostic {
155d95cfb93Sbostic   register COLUMN *cp;
156d95cfb93Sbostic   register COLUMN *cend;
157d95cfb93Sbostic   register char *sp;
158d95cfb93Sbostic 
159d95cfb93Sbostic 
160d95cfb93Sbostic   length = 0;
161d95cfb93Sbostic   maxpos = MAXCOL;
162d95cfb93Sbostic   sp = malloc((unsigned) maxpos);
163d95cfb93Sbostic   if (sp == NULL)
164d95cfb93Sbostic     nospace();
165d95cfb93Sbostic   text = sp;
166d95cfb93Sbostic 
167d95cfb93Sbostic   highcol = -1;
168d95cfb93Sbostic   maxcol = MAXCOL;
169d95cfb93Sbostic   line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN));
170d95cfb93Sbostic   if (line == NULL)
171d95cfb93Sbostic     nospace();
172d95cfb93Sbostic   cp = line;
173d95cfb93Sbostic   cend = line + (maxcol-1);
174d95cfb93Sbostic   while (cp <= cend)
175d95cfb93Sbostic     {
176d95cfb93Sbostic       cp->width = INITWIDTH;
177d95cfb93Sbostic       sp = calloc(INITWIDTH, (unsigned) sizeof(char));
178d95cfb93Sbostic       if (sp == NULL)
179d95cfb93Sbostic 	nospace();
180d95cfb93Sbostic       cp->str = sp;
181d95cfb93Sbostic       cp++;
182d95cfb93Sbostic     }
183d95cfb93Sbostic }
184d95cfb93Sbostic 
185d95cfb93Sbostic 
186d95cfb93Sbostic 
gettext()187d95cfb93Sbostic gettext()
188d95cfb93Sbostic {
189d95cfb93Sbostic   register int i;
190d95cfb93Sbostic   register char ateol;
191d95cfb93Sbostic   register int ch;
192d95cfb93Sbostic   register int pos;
193d95cfb93Sbostic 
194d95cfb93Sbostic 
195d95cfb93Sbostic   i = 0;
196d95cfb93Sbostic   ateol = FALSE;
197d95cfb93Sbostic 
198d95cfb93Sbostic   while ( ! ateol)
199d95cfb93Sbostic     {
200d95cfb93Sbostic       ch = getchar();
201d95cfb93Sbostic       if (ch == EOL || ch == EOF)
202d95cfb93Sbostic 	ateol = TRUE;
203d95cfb93Sbostic       else if (ch == TAB)
204d95cfb93Sbostic 	{
205d95cfb93Sbostic 	  pos = (1 + i/TABSIZE) * TABSIZE;
206d95cfb93Sbostic 	  if (pos > maxpos)
207d95cfb93Sbostic 	    {
208d95cfb93Sbostic 	      maxpos = pos + 10;
209d95cfb93Sbostic 	      text = realloc(text, (unsigned) maxpos);
210d95cfb93Sbostic 	      if (text == NULL)
211d95cfb93Sbostic 		nospace();
212d95cfb93Sbostic 	    }
213d95cfb93Sbostic 	  while (i < pos)
214d95cfb93Sbostic 	    {
215d95cfb93Sbostic 	      text[i] = BLANK;
216d95cfb93Sbostic 	      i++;
217d95cfb93Sbostic 	    }
218d95cfb93Sbostic 	}
219d95cfb93Sbostic       else if (ch == BS)
220d95cfb93Sbostic 	{
221d95cfb93Sbostic 	  if (i > 0)
222d95cfb93Sbostic 	    {
223d95cfb93Sbostic 	      i--;
224d95cfb93Sbostic 	      savech(i);
225d95cfb93Sbostic 	    }
226d95cfb93Sbostic 	}
227d95cfb93Sbostic       else if (ch == CR)
228d95cfb93Sbostic 	{
229d95cfb93Sbostic 	  while (i > 0)
230d95cfb93Sbostic 	    {
231d95cfb93Sbostic 	      i--;
232d95cfb93Sbostic 	      savech(i);
233d95cfb93Sbostic 	    }
234d95cfb93Sbostic 	}
235d95cfb93Sbostic       else if (ch == FF || ch == VTAB)
236d95cfb93Sbostic 	{
237d95cfb93Sbostic 	  flush();
238d95cfb93Sbostic 	  cc = ch;
239d95cfb93Sbostic 	  i = 0;
240d95cfb93Sbostic 	}
241d95cfb93Sbostic       else
242d95cfb93Sbostic 	{
243d95cfb93Sbostic 	  if (i >= maxpos)
244d95cfb93Sbostic 	    {
245d95cfb93Sbostic 	      maxpos = i + 10;
246d95cfb93Sbostic 	      text = realloc(text, (unsigned) maxpos);
247d95cfb93Sbostic 	      if (text == NULL)
248d95cfb93Sbostic 		nospace();
249d95cfb93Sbostic 	    }
250d95cfb93Sbostic 	  text[i] = ch;
251d95cfb93Sbostic 	  i++;
252d95cfb93Sbostic 	}
253d95cfb93Sbostic     }
254d95cfb93Sbostic 
255d95cfb93Sbostic   length = i;
256d95cfb93Sbostic }
257d95cfb93Sbostic 
258d95cfb93Sbostic 
259d95cfb93Sbostic 
savech(col)260d95cfb93Sbostic savech(col)
261d95cfb93Sbostic int col;
262d95cfb93Sbostic {
263d95cfb93Sbostic   register char ch;
264d95cfb93Sbostic   register int oldmax;
265d95cfb93Sbostic   register COLUMN *cp;
266d95cfb93Sbostic   register COLUMN *cend;
267d95cfb93Sbostic   register char *sp;
268d95cfb93Sbostic   register int newcount;
269d95cfb93Sbostic 
270d95cfb93Sbostic 
271d95cfb93Sbostic   ch = text[col];
272d95cfb93Sbostic   if (ch == BLANK)
273d95cfb93Sbostic     return;
274d95cfb93Sbostic 
275d95cfb93Sbostic   saved = TRUE;
276d95cfb93Sbostic 
277d95cfb93Sbostic   if (col >= highcol)
278d95cfb93Sbostic     highcol = col;
279d95cfb93Sbostic 
280d95cfb93Sbostic   if (col >= maxcol)
281d95cfb93Sbostic     {
282d95cfb93Sbostic       oldmax = maxcol;
283d95cfb93Sbostic       maxcol = col + 10;
284d95cfb93Sbostic       line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN));
285d95cfb93Sbostic       if (line == NULL)
286d95cfb93Sbostic 	nospace();
287d95cfb93Sbostic       cp = line + oldmax;
288d95cfb93Sbostic       cend = line + (maxcol - 1);
289d95cfb93Sbostic       while (cp <= cend)
290d95cfb93Sbostic 	{
291d95cfb93Sbostic 	  cp->width = INITWIDTH;
292d95cfb93Sbostic 	  cp->count = 0;
293d95cfb93Sbostic 	  sp = calloc(INITWIDTH, (unsigned) sizeof(char));
294d95cfb93Sbostic 	  if (sp == NULL)
295d95cfb93Sbostic 	    nospace();
296d95cfb93Sbostic 	  cp->str = sp;
297d95cfb93Sbostic 	  cp++;
298d95cfb93Sbostic 	}
299d95cfb93Sbostic     }
300d95cfb93Sbostic 
301d95cfb93Sbostic   cp = line + col;
302d95cfb93Sbostic   newcount = cp->count + 1;
303d95cfb93Sbostic   if (newcount > cp->width)
304d95cfb93Sbostic     {
305d95cfb93Sbostic       cp->width = newcount;
306d95cfb93Sbostic       sp = realloc(cp->str, (unsigned) newcount*sizeof(char));
307d95cfb93Sbostic       if (sp == NULL)
308d95cfb93Sbostic 	nospace();
309d95cfb93Sbostic       cp->str = sp;
310d95cfb93Sbostic     }
311d95cfb93Sbostic   cp->count = newcount;
312d95cfb93Sbostic   cp->str[newcount-1] = ch;
313d95cfb93Sbostic }
314d95cfb93Sbostic 
315d95cfb93Sbostic 
316d95cfb93Sbostic 
flush()317d95cfb93Sbostic flush()
318d95cfb93Sbostic {
319d95cfb93Sbostic   register int i;
320d95cfb93Sbostic   register int anchor;
321d95cfb93Sbostic   register int height;
322d95cfb93Sbostic   register int j;
323d95cfb93Sbostic 
324d95cfb93Sbostic 
325d95cfb93Sbostic   if (cc != NUL)
326d95cfb93Sbostic     putchar(cc);
327d95cfb93Sbostic 
328d95cfb93Sbostic   if ( ! saved)
329d95cfb93Sbostic     {
330d95cfb93Sbostic       i = length;
331d95cfb93Sbostic       while (i > 0 && text[i-1] == BLANK)
332d95cfb93Sbostic 	i--;
3335171fc64Storek       length = i;
334d95cfb93Sbostic       for (i = 0; i < length; i++)
335d95cfb93Sbostic 	putchar(text[i]);
336d95cfb93Sbostic       putchar(EOL);
337d95cfb93Sbostic       return;
338d95cfb93Sbostic     }
339d95cfb93Sbostic 
340d95cfb93Sbostic   for (i =0; i < length; i++)
341d95cfb93Sbostic     savech(i);
342d95cfb93Sbostic 
343d95cfb93Sbostic   anchor = 0;
344d95cfb93Sbostic   while (anchor <= highcol)
345d95cfb93Sbostic     {
346d95cfb93Sbostic       height = line[anchor].count;
347d95cfb93Sbostic       if (height == 0)
348d95cfb93Sbostic 	{
349d95cfb93Sbostic 	  putchar(BLANK);
350d95cfb93Sbostic 	  anchor++;
351d95cfb93Sbostic 	}
352d95cfb93Sbostic       else if (height == 1)
353d95cfb93Sbostic 	{
354d95cfb93Sbostic 	  putchar( *(line[anchor].str) );
355d95cfb93Sbostic 	  line[anchor].count = 0;
356d95cfb93Sbostic 	  anchor++;
357d95cfb93Sbostic 	}
358d95cfb93Sbostic       else
359d95cfb93Sbostic 	{
360d95cfb93Sbostic 	  i = anchor;
361d95cfb93Sbostic 	  while (i < highcol && line[i+1].count > 1)
362d95cfb93Sbostic 	    i++;
363d95cfb93Sbostic 	  for (j = anchor; j <= i; j++)
364d95cfb93Sbostic 	    {
365d95cfb93Sbostic 	      height = line[j].count - 1;
366d95cfb93Sbostic 	      putchar(line[j].str[height]);
367d95cfb93Sbostic 	      line[j].count = height;
368d95cfb93Sbostic 	    }
369d95cfb93Sbostic 	  for (j = anchor; j <= i; j++)
370d95cfb93Sbostic 	    putchar(BS);
371d95cfb93Sbostic 	}
372d95cfb93Sbostic     }
373d95cfb93Sbostic 
374d95cfb93Sbostic   putchar(EOL);
375d95cfb93Sbostic   highcol = -1;
376d95cfb93Sbostic }
377d95cfb93Sbostic 
378d95cfb93Sbostic 
379d95cfb93Sbostic 
nospace()380d95cfb93Sbostic nospace()
381d95cfb93Sbostic {
382d95cfb93Sbostic   fputs("Storage limit exceeded.\n", stderr);
383d95cfb93Sbostic   exit(1);
384d95cfb93Sbostic }
385