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