xref: /original-bsd/usr.bin/fold/fold.c (revision da7c76f1)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * 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 are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #ifndef lint
22 char copyright[] =
23 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
24  All rights reserved.\n";
25 #endif /* not lint */
26 
27 #ifndef lint
28 static char sccsid[] = "@(#)fold.c	5.4 (Berkeley) 05/15/90";
29 #endif /* not lint */
30 
31 #include <stdio.h>
32 #include <string.h>
33 
34 #define	DEFLINEWIDTH	80
35 
36 main(argc, argv)
37 	int argc;
38 	char **argv;
39 {
40 	extern int errno, optind;
41 	extern char *optarg;
42 	register int ch;
43 	int width;
44 	char *p;
45 
46 	width = -1;
47 	while ((ch = getopt(argc, argv, "0123456789w:")) != EOF)
48 		switch (ch) {
49 		case 'w':
50 			if ((width = atoi(optarg)) <= 0) {
51 				(void)fprintf(stderr,
52 				    "fold: illegal width value.\n");
53 				exit(1);
54 			}
55 			break;
56 		case '0': case '1': case '2': case '3': case '4':
57 		case '5': case '6': case '7': case '8': case '9':
58 			if (width == -1) {
59 				p = argv[optind - 1];
60 				if (p[0] == '-' && p[1] == ch && !p[2])
61 					width = atoi(++p);
62 				else
63 					width = atoi(argv[optind] + 1);
64 			}
65 			break;
66 		default:
67 			(void)fprintf(stderr,
68 			    "usage: fold [-w width] [file ...]\n");
69 			exit(1);
70 		}
71 	argv += optind;
72 	argc -= optind;
73 
74 	if (width == -1)
75 		width = DEFLINEWIDTH;
76 	if (!*argv)
77 		fold(width);
78 	else for (; *argv; ++argv)
79 		if (!freopen(*argv, "r", stdin)) {
80 			(void)fprintf(stderr,
81 			    "fold: %s: %s\n", *argv, strerror(errno));
82 			exit(1);
83 		} else
84 			fold(width);
85 	exit(0);
86 }
87 
88 fold(width)
89 	register int width;
90 {
91 	register int ch, col, new;
92 
93 	for (col = 0;;) {
94 		switch (ch = getchar()) {
95 		case EOF:
96 			return;
97 		case '\b':
98 			new = col ? col - 1 : 0;
99 			break;
100 		case '\n':
101 		case '\r':
102 			new = 0;
103 			break;
104 		case '\t':
105 			new = (col + 8) & ~7;
106 			break;
107 		default:
108 			new = col + 1;
109 			break;
110 		}
111 
112 		if (new > width) {
113 			putchar('\n');
114 			col = 0;
115 		}
116 		putchar(ch);
117 
118 		switch (ch) {
119 		case '\b':
120 			if (col > 0)
121 				--col;
122 			break;
123 		case '\n':
124 		case '\r':
125 			col = 0;
126 			break;
127 		case '\t':
128 			col += 8;
129 			col &= ~7;
130 			break;
131 		default:
132 			++col;
133 			break;
134 		}
135 	}
136 }
137