fpr.c revision 1.2 1 /*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Corbett.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 char copyright[] =
39 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
40 All rights reserved.\n";
41 #endif /* not lint */
42
43 #ifndef lint
44 /*static char sccsid[] = "from: @(#)fpr.c 5.4 (Berkeley) 2/6/91";*/
45 static char rcsid[] = "$Id: fpr.c,v 1.2 1993/08/01 18:15:47 mycroft Exp $";
46 #endif /* not lint */
47
48 #include <stdio.h>
49
50 #define BLANK ' '
51 #define TAB '\t'
52 #define NUL '\000'
53 #define FF '\f'
54 #define BS '\b'
55 #define CR '\r'
56 #define VTAB '\013'
57 #define EOL '\n'
58
59 #define TRUE 1
60 #define FALSE 0
61
62 #define MAXCOL 170
63 #define TABSIZE 8
64 #define INITWIDTH 8
65
66 typedef
67 struct column
68 {
69 int count;
70 int width;
71 char *str;
72 }
73 COLUMN;
74
75 char cc;
76 char saved;
77 int length;
78 char *text;
79 int highcol;
80 COLUMN *line;
81 int maxpos;
82 int maxcol;
83
84 extern char *malloc();
85 extern char *calloc();
86 extern char *realloc();
87
88
89
91 main()
92 {
93 register int ch;
94 register char ateof;
95 register int i;
96 register int errorcount;
97
98
99 init();
100 errorcount = 0;
101 ateof = FALSE;
102
103 ch = getchar();
104 if (ch == EOF)
105 exit(0);
106
107 if (ch == EOL)
108 {
109 cc = NUL;
110 ungetc((int) EOL, stdin);
111 }
112 else if (ch == BLANK)
113 cc = NUL;
114 else if (ch == '1')
115 cc = FF;
116 else if (ch == '0')
117 cc = EOL;
118 else if (ch == '+')
119 cc = CR;
120 else
121 {
122 errorcount = 1;
123 cc = NUL;
124 ungetc(ch, stdin);
125 }
126
127 while ( ! ateof)
128 {
129 gettext();
130 ch = getchar();
131 if (ch == EOF)
132 {
133 flush();
134 ateof = TRUE;
135 }
136 else if (ch == EOL)
137 {
138 flush();
139 cc = NUL;
140 ungetc((int) EOL, stdin);
141 }
142 else if (ch == BLANK)
143 {
144 flush();
145 cc = NUL;
146 }
147 else if (ch == '1')
148 {
149 flush();
150 cc = FF;
151 }
152 else if (ch == '0')
153 {
154 flush();
155 cc = EOL;
156 }
157 else if (ch == '+')
158 {
159 for (i = 0; i < length; i++)
160 savech(i);
161 }
162 else
163 {
164 errorcount++;
165 flush();
166 cc = NUL;
167 ungetc(ch, stdin);
168 }
169 }
170
171 if (errorcount == 1)
172 fprintf(stderr, "Illegal carriage control - 1 line.\n");
173 else if (errorcount > 1)
174 fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount);
175
176 exit(0);
177 }
178
179
180
182 init()
183 {
184 register COLUMN *cp;
185 register COLUMN *cend;
186 register char *sp;
187
188
189 length = 0;
190 maxpos = MAXCOL;
191 sp = malloc((unsigned) maxpos);
192 if (sp == NULL)
193 nospace();
194 text = sp;
195
196 highcol = -1;
197 maxcol = MAXCOL;
198 line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN));
199 if (line == NULL)
200 nospace();
201 cp = line;
202 cend = line + (maxcol-1);
203 while (cp <= cend)
204 {
205 cp->width = INITWIDTH;
206 sp = calloc(INITWIDTH, (unsigned) sizeof(char));
207 if (sp == NULL)
208 nospace();
209 cp->str = sp;
210 cp++;
211 }
212 }
213
214
215
217 gettext()
218 {
219 register int i;
220 register char ateol;
221 register int ch;
222 register int pos;
223
224
225 i = 0;
226 ateol = FALSE;
227
228 while ( ! ateol)
229 {
230 ch = getchar();
231 if (ch == EOL || ch == EOF)
232 ateol = TRUE;
233 else if (ch == TAB)
234 {
235 pos = (1 + i/TABSIZE) * TABSIZE;
236 if (pos > maxpos)
237 {
238 maxpos = pos + 10;
239 text = realloc(text, (unsigned) maxpos);
240 if (text == NULL)
241 nospace();
242 }
243 while (i < pos)
244 {
245 text[i] = BLANK;
246 i++;
247 }
248 }
249 else if (ch == BS)
250 {
251 if (i > 0)
252 {
253 i--;
254 savech(i);
255 }
256 }
257 else if (ch == CR)
258 {
259 while (i > 0)
260 {
261 i--;
262 savech(i);
263 }
264 }
265 else if (ch == FF || ch == VTAB)
266 {
267 flush();
268 cc = ch;
269 i = 0;
270 }
271 else
272 {
273 if (i >= maxpos)
274 {
275 maxpos = i + 10;
276 text = realloc(text, (unsigned) maxpos);
277 if (text == NULL)
278 nospace();
279 }
280 text[i] = ch;
281 i++;
282 }
283 }
284
285 length = i;
286 }
287
288
289
291 savech(col)
292 int col;
293 {
294 register char ch;
295 register int oldmax;
296 register COLUMN *cp;
297 register COLUMN *cend;
298 register char *sp;
299 register int newcount;
300
301
302 ch = text[col];
303 if (ch == BLANK)
304 return;
305
306 saved = TRUE;
307
308 if (col >= highcol)
309 highcol = col;
310
311 if (col >= maxcol)
312 {
313 oldmax = maxcol;
314 maxcol = col + 10;
315 line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN));
316 if (line == NULL)
317 nospace();
318 cp = line + oldmax;
319 cend = line + (maxcol - 1);
320 while (cp <= cend)
321 {
322 cp->width = INITWIDTH;
323 cp->count = 0;
324 sp = calloc(INITWIDTH, (unsigned) sizeof(char));
325 if (sp == NULL)
326 nospace();
327 cp->str = sp;
328 cp++;
329 }
330 }
331
332 cp = line + col;
333 newcount = cp->count + 1;
334 if (newcount > cp->width)
335 {
336 cp->width = newcount;
337 sp = realloc(cp->str, (unsigned) newcount*sizeof(char));
338 if (sp == NULL)
339 nospace();
340 cp->str = sp;
341 }
342 cp->count = newcount;
343 cp->str[newcount-1] = ch;
344 }
345
346
347
349 flush()
350 {
351 register int i;
352 register int anchor;
353 register int height;
354 register int j;
355
356
357 if (cc != NUL)
358 putchar(cc);
359
360 if ( ! saved)
361 {
362 i = length;
363 while (i > 0 && text[i-1] == BLANK)
364 i--;
365 length = i;
366 for (i = 0; i < length; i++)
367 putchar(text[i]);
368 putchar(EOL);
369 return;
370 }
371
372 for (i =0; i < length; i++)
373 savech(i);
374
375 anchor = 0;
376 while (anchor <= highcol)
377 {
378 height = line[anchor].count;
379 if (height == 0)
380 {
381 putchar(BLANK);
382 anchor++;
383 }
384 else if (height == 1)
385 {
386 putchar( *(line[anchor].str) );
387 line[anchor].count = 0;
388 anchor++;
389 }
390 else
391 {
392 i = anchor;
393 while (i < highcol && line[i+1].count > 1)
394 i++;
395 for (j = anchor; j <= i; j++)
396 {
397 height = line[j].count - 1;
398 putchar(line[j].str[height]);
399 line[j].count = height;
400 }
401 for (j = anchor; j <= i; j++)
402 putchar(BS);
403 }
404 }
405
406 putchar(EOL);
407 highcol = -1;
408 }
409
410
411
413 nospace()
414 {
415 fputs("Storage limit exceeded.\n", stderr);
416 exit(1);
417 }
418