fold.c revision 27270
1/*-
2 * Copyright (c) 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kevin Ruddy.
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
38static const char copyright[] =
39"@(#) Copyright (c) 1990, 1993\n\
40	The Regents of the University of California.  All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44#if 0
45static char sccsid[] = "@(#)fold.c	8.1 (Berkeley) 6/6/93";
46#endif
47static const char rcsid[] =
48	"$Id$";
49#endif /* not lint */
50
51#include <err.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <unistd.h>
56
57#define	DEFLINEWIDTH	80
58
59void fold __P((int));
60static void usage __P((void));
61
62int
63main(argc, argv)
64	int argc;
65	char **argv;
66{
67	extern int optind;
68	extern char *optarg;
69	register int ch;
70	int width;
71	char *p;
72
73	width = -1;
74	while ((ch = getopt(argc, argv, "0123456789w:")) != -1)
75		switch (ch) {
76		case 'w':
77			if ((width = atoi(optarg)) <= 0) {
78				errx(1, "illegal width value");
79			}
80			break;
81		case '0': case '1': case '2': case '3': case '4':
82		case '5': case '6': case '7': case '8': case '9':
83			if (width == -1) {
84				p = argv[optind - 1];
85				if (p[0] == '-' && p[1] == ch && !p[2])
86					width = atoi(++p);
87				else
88					width = atoi(argv[optind] + 1);
89			}
90			break;
91		default:
92			usage();
93		}
94	argv += optind;
95	argc -= optind;
96
97	if (width == -1)
98		width = DEFLINEWIDTH;
99	if (!*argv)
100		fold(width);
101	else for (; *argv; ++argv)
102		if (!freopen(*argv, "r", stdin)) {
103			err(1, "%s", *argv);
104		} else
105			fold(width);
106	exit(0);
107}
108
109static void
110usage()
111{
112	(void)fprintf(stderr, "usage: fold [-w width] [file ...]\n");
113	exit(1);
114}
115
116void
117fold(width)
118	register int width;
119{
120	register int ch, col, new;
121
122	for (col = 0;;) {
123		switch (ch = getchar()) {
124		case EOF:
125			return;
126		case '\b':
127			new = col ? col - 1 : 0;
128			break;
129		case '\n':
130		case '\r':
131			new = 0;
132			break;
133		case '\t':
134			new = (col + 8) & ~7;
135			break;
136		default:
137			new = col + 1;
138			break;
139		}
140
141		if (new > width) {
142			putchar('\n');
143			col = 0;
144		}
145		putchar(ch);
146
147		switch (ch) {
148		case '\b':
149			if (col > 0)
150				--col;
151			break;
152		case '\n':
153		case '\r':
154			col = 0;
155			break;
156		case '\t':
157			col += 8;
158			col &= ~7;
159			break;
160		default:
161			++col;
162			break;
163		}
164	}
165}
166