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