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