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