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