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