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