xref: /original-bsd/usr.bin/fold/fold.c (revision c3e32dec)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char copyright[] =
13 "@(#) Copyright (c) 1990, 1993\n\
14 	The Regents of the University of California.  All rights reserved.\n";
15 #endif /* not lint */
16 
17 #ifndef lint
18 static char sccsid[] = "@(#)fold.c	8.1 (Berkeley) 06/06/93";
19 #endif /* not lint */
20 
21 #include <stdio.h>
22 #include <string.h>
23 
24 #define	DEFLINEWIDTH	80
25 
26 main(argc, argv)
27 	int argc;
28 	char **argv;
29 {
30 	extern int errno, optind;
31 	extern char *optarg;
32 	register int ch;
33 	int width;
34 	char *p;
35 
36 	width = -1;
37 	while ((ch = getopt(argc, argv, "0123456789w:")) != EOF)
38 		switch (ch) {
39 		case 'w':
40 			if ((width = atoi(optarg)) <= 0) {
41 				(void)fprintf(stderr,
42 				    "fold: illegal width value.\n");
43 				exit(1);
44 			}
45 			break;
46 		case '0': case '1': case '2': case '3': case '4':
47 		case '5': case '6': case '7': case '8': case '9':
48 			if (width == -1) {
49 				p = argv[optind - 1];
50 				if (p[0] == '-' && p[1] == ch && !p[2])
51 					width = atoi(++p);
52 				else
53 					width = atoi(argv[optind] + 1);
54 			}
55 			break;
56 		default:
57 			(void)fprintf(stderr,
58 			    "usage: fold [-w width] [file ...]\n");
59 			exit(1);
60 		}
61 	argv += optind;
62 	argc -= optind;
63 
64 	if (width == -1)
65 		width = DEFLINEWIDTH;
66 	if (!*argv)
67 		fold(width);
68 	else for (; *argv; ++argv)
69 		if (!freopen(*argv, "r", stdin)) {
70 			(void)fprintf(stderr,
71 			    "fold: %s: %s\n", *argv, strerror(errno));
72 			exit(1);
73 		} else
74 			fold(width);
75 	exit(0);
76 }
77 
78 fold(width)
79 	register int width;
80 {
81 	register int ch, col, new;
82 
83 	for (col = 0;;) {
84 		switch (ch = getchar()) {
85 		case EOF:
86 			return;
87 		case '\b':
88 			new = col ? col - 1 : 0;
89 			break;
90 		case '\n':
91 		case '\r':
92 			new = 0;
93 			break;
94 		case '\t':
95 			new = (col + 8) & ~7;
96 			break;
97 		default:
98 			new = col + 1;
99 			break;
100 		}
101 
102 		if (new > width) {
103 			putchar('\n');
104 			col = 0;
105 		}
106 		putchar(ch);
107 
108 		switch (ch) {
109 		case '\b':
110 			if (col > 0)
111 				--col;
112 			break;
113 		case '\n':
114 		case '\r':
115 			col = 0;
116 			break;
117 		case '\t':
118 			col += 8;
119 			col &= ~7;
120 			break;
121 		default:
122 			++col;
123 			break;
124 		}
125 	}
126 }
127