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