No empty .Rs/.Re
[netbsd-mini2440.git] / usr.bin / fpr / fpr.c
bloba1949895160feece7f484063de216f4ab12ebc28
1 /* $NetBSD: fpr.c,v 1.7 2003/10/16 06:50:17 itojun Exp $ */
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Robert Corbett.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #ifndef lint
37 __COPYRIGHT("@(#) Copyright (c) 1989, 1993\
38 The Regents of the University of California. All rights reserved.");
39 #endif /* not lint */
41 #ifndef lint
42 #if 0
43 static char sccsid[] = "@(#)fpr.c 8.1 (Berkeley) 6/6/93";
44 #endif
45 __RCSID("$NetBSD: fpr.c,v 1.7 2003/10/16 06:50:17 itojun Exp $");
46 #endif /* not lint */
48 #include <err.h>
49 #include <stdio.h>
50 #include <stdlib.h>
52 #define BLANK ' '
53 #define TAB '\t'
54 #define NUL '\000'
55 #define FF '\f'
56 #define BS '\b'
57 #define CR '\r'
58 #define VTAB '\013'
59 #define EOL '\n'
61 #define TRUE 1
62 #define FALSE 0
64 #define MAXCOL 170
65 #define TABSIZE 8
66 #define INITWIDTH 8
68 typedef
69 struct column {
70 int count;
71 int width;
72 char *str;
74 COLUMN;
76 char cc;
77 char saved;
78 int length;
79 char *text;
80 int highcol;
81 COLUMN *line;
82 int maxpos;
83 int maxcol;
85 void flush __P((void));
86 void get_text __P((void));
87 void init __P((void));
88 int main __P((int, char **));
89 void nospace __P((void));
90 void savech __P((int));
92 int
93 main(argc, argv)
94 int argc;
95 char **argv;
97 int ch;
98 char ateof;
99 int i;
100 int errorcount;
103 init();
104 errorcount = 0;
105 ateof = FALSE;
107 ch = getchar();
108 if (ch == EOF)
109 exit(0);
111 if (ch == EOL) {
112 cc = NUL;
113 ungetc((int) EOL, stdin);
114 } else
115 if (ch == BLANK)
116 cc = NUL;
117 else
118 if (ch == '1')
119 cc = FF;
120 else
121 if (ch == '0')
122 cc = EOL;
123 else
124 if (ch == '+')
125 cc = CR;
126 else {
127 errorcount = 1;
128 cc = NUL;
129 ungetc(ch, stdin);
132 while (!ateof) {
133 get_text();
134 ch = getchar();
135 if (ch == EOF) {
136 flush();
137 ateof = TRUE;
138 } else
139 if (ch == EOL) {
140 flush();
141 cc = NUL;
142 ungetc((int) EOL, stdin);
143 } else
144 if (ch == BLANK) {
145 flush();
146 cc = NUL;
147 } else
148 if (ch == '1') {
149 flush();
150 cc = FF;
151 } else
152 if (ch == '0') {
153 flush();
154 cc = EOL;
155 } else
156 if (ch == '+') {
157 for (i = 0; i < length; i++)
158 savech(i);
159 } else {
160 errorcount++;
161 flush();
162 cc = NUL;
163 ungetc(ch, stdin);
167 if (errorcount == 1)
168 fprintf(stderr, "Illegal carriage control - 1 line.\n");
169 else
170 if (errorcount > 1)
171 fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount);
173 exit(0);
176 void
177 init()
179 COLUMN *cp;
180 COLUMN *cend;
181 char *sp;
184 length = 0;
185 maxpos = MAXCOL;
186 sp = malloc((unsigned) maxpos);
187 if (sp == NULL)
188 nospace();
189 text = sp;
191 highcol = -1;
192 maxcol = MAXCOL;
193 line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN));
194 if (line == NULL)
195 nospace();
196 cp = line;
197 cend = line + (maxcol - 1);
198 while (cp <= cend) {
199 cp->width = INITWIDTH;
200 sp = calloc(INITWIDTH, (unsigned) sizeof(char));
201 if (sp == NULL)
202 nospace();
203 cp->str = sp;
204 cp++;
208 void
209 get_text()
211 int i;
212 char ateol;
213 int ch;
214 int pos;
215 char *n;
217 i = 0;
218 ateol = FALSE;
220 while (!ateol) {
221 ch = getchar();
222 if (ch == EOL || ch == EOF)
223 ateol = TRUE;
224 else
225 if (ch == TAB) {
226 pos = (1 + i / TABSIZE) * TABSIZE;
227 if (pos > maxpos) {
228 n = realloc(text, (unsigned)(pos + 10));
229 if (n == NULL)
230 nospace();
231 text = n;
232 maxpos = pos + 10;
234 while (i < pos) {
235 text[i] = BLANK;
236 i++;
238 } else
239 if (ch == BS) {
240 if (i > 0) {
241 i--;
242 savech(i);
244 } else
245 if (ch == CR) {
246 while (i > 0) {
247 i--;
248 savech(i);
250 } else
251 if (ch == FF || ch == VTAB) {
252 flush();
253 cc = ch;
254 i = 0;
255 } else {
256 if (i >= maxpos) {
257 n = realloc(text, (unsigned)(i + 10));
258 if (n == NULL)
259 nospace();
260 maxpos = i + 10;
262 text[i] = ch;
263 i++;
267 length = i;
270 void
271 savech(col)
272 int col;
274 char ch;
275 int oldmax;
276 COLUMN *cp;
277 COLUMN *cend;
278 char *sp;
279 int newcount;
280 COLUMN *newline;
282 ch = text[col];
283 if (ch == BLANK)
284 return;
286 saved = TRUE;
288 if (col >= highcol)
289 highcol = col;
291 if (col >= maxcol) {
292 newline = (COLUMN *) realloc(line,
293 (unsigned) (col + 10) * sizeof(COLUMN));
294 if (newline == NULL)
295 nospace();
296 line = newline;
297 oldmax = maxcol;
298 maxcol = col + 10;
299 cp = line + oldmax;
300 cend = line + (maxcol - 1);
301 while (cp <= cend) {
302 cp->width = INITWIDTH;
303 cp->count = 0;
304 sp = calloc(INITWIDTH, (unsigned) sizeof(char));
305 if (sp == NULL)
306 nospace();
307 cp->str = sp;
308 cp++;
311 cp = line + col;
312 newcount = cp->count + 1;
313 if (newcount > cp->width) {
314 cp->width = newcount;
315 sp = realloc(cp->str, (unsigned) newcount * sizeof(char));
316 if (sp == NULL)
317 nospace();
318 cp->str = sp;
320 cp->count = newcount;
321 cp->str[newcount - 1] = ch;
324 void
325 flush()
327 int i;
328 int anchor;
329 int height;
330 int j;
332 if (cc != NUL)
333 putchar(cc);
335 if (!saved) {
336 i = length;
337 while (i > 0 && text[i - 1] == BLANK)
338 i--;
339 length = i;
340 for (i = 0; i < length; i++)
341 putchar(text[i]);
342 putchar(EOL);
343 return;
345 for (i = 0; i < length; i++)
346 savech(i);
348 anchor = 0;
349 while (anchor <= highcol) {
350 height = line[anchor].count;
351 if (height == 0) {
352 putchar(BLANK);
353 anchor++;
354 } else
355 if (height == 1) {
356 putchar(*(line[anchor].str));
357 line[anchor].count = 0;
358 anchor++;
359 } else {
360 i = anchor;
361 while (i < highcol && line[i + 1].count > 1)
362 i++;
363 for (j = anchor; j <= i; j++) {
364 height = line[j].count - 1;
365 putchar(line[j].str[height]);
366 line[j].count = height;
368 for (j = anchor; j <= i; j++)
369 putchar(BS);
373 putchar(EOL);
374 highcol = -1;
377 void
378 nospace()
380 errx(1, "Storage limit exceeded.");