4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
46 #include <stdlib.h> /* XCU4 */
57 * fold - fold long lines for finite output devices
68 static wchar_t line
[LINE_MAX
];
69 static wchar_t *lastout
= line
;
70 static wchar_t *curc
= line
;
71 static wchar_t *lastsp
= NULL
;
72 #define MAXARG _POSIX_ARG_MAX
80 static void newline_init();
81 static int chr_width();
83 static int get_foldw();
87 main(int argc
, char *argv
[])
91 char *cmdline
[MAXARG
];
97 (void) setlocale(LC_ALL
, "");
98 #if !defined(TEXT_DOMAIN)
99 #define TEXT_DOMAIN "SYS_TEST"
101 (void) textdomain(TEXT_DOMAIN
);
104 * Parse -width separately and build
105 * the new command line without -width.
106 * Next, use getopt() to parse this
110 for (narg
= new_argc
= 0; narg
< argc
; narg
++) {
111 if (argv
[narg
][0] == '-' &&
112 isdigit(argv
[narg
][1])) {
114 if (get_foldw((char *)&argv
[narg
][1], &w
) < 0)
117 fold
= w
; /* Update with new width */
119 /* Build the new command line */
120 cmdline
[new_argc
++] = argv
[narg
];
123 * Check to make sure the option with
124 * required arg should have arg.
125 * This would check errors introduced in
126 * mixing non-getopt() options and that of
127 * getopt()'s due to stripping non-getopt
130 if ((argv
[narg
][0] == '-') && (argv
[narg
][1] == 'w')) {
131 if (((narg
+1) < argc
) &&
132 (argv
[narg
+1][0] == '-')) {
133 (void) fprintf(stderr
, "fold");
134 (void) fprintf(stderr
, gettext(
135 ": option requires an argument -- w\n"));
143 while ((ch
= getopt(new_argc
, cmdline
, "w:bs")) != EOF
) {
153 /* No required arg ? */
154 if ((optarg
== (char *)NULL
) ||
155 ((optarg
!= (char *)NULL
) &&
157 (void) fprintf(stderr
, "fold");
158 (void) fprintf(stderr
, gettext(
159 ": option requires an argument -- w\n"));
164 if (get_foldw(optarg
, &w
) < 0)
171 * Errors should be filtered in previous
180 if (new_argc
> optind
) {
181 if (freopen(cmdline
[optind
], "r", stdin
) == NULL
) {
182 perror(cmdline
[optind
]);
196 if (col
!= 0) newline_init();
197 } while (new_argc
> optind
);
205 wchar_t tline
[LINE_MAX
];
213 ncol
= col
+ chr_width(c
);
215 ncol
= (col
+ 8) &~ 7;
219 ncol
= col
+ chr_width(c
);
221 ncol
= col
? col
- 1 : 0;
225 ncol
= col
+ chr_width(c
);
232 ncol
= col
+ chr_width(c
);
234 ncol
= col
+ wcwidth(c
);
239 * Special processing when -b is not specified
240 * for backspace, and carriage return.
241 * No newline is inseted before or after the
242 * special character: backspace, or cr.
243 * See man page for the handling of backspace
244 * and CR when there is no -b.
246 if ((ncol
> fold
) && (bflg
||
247 (!bflg
&& (lastc
!= '\b') && (c
!= '\b') &&
248 (lastc
!= '\n') && (c
!= '\n')))) {
250 * Need to check the last position for blank
252 if (sflg
&& lastsp
) {
254 * Save the output buffer
255 * as NULL has to be insert into the last
258 (void) wscpy(tline
, line
);
259 *lastsp
= (wchar_t)NULL
;
260 (void) fputws(lastout
, stdout
);
261 (void) putwchar('\n');
263 * Restore the output buffer to stuff
264 * NULL into the last sp position
267 (void) wscpy(line
, tline
);
269 lastsp
= NULL
; /* Reset the last sp */
270 ncol
-= spcol
; /* Reset column positions */
273 (void) newline_init();
274 (void) putwchar('\n');
278 /* Output buffer is full ? */
279 if ((curc
+ 1) >= (line
+ LINE_MAX
)) {
280 /* Reach buffer limit */
282 *curc
= (wchar_t)NULL
;
283 (void) fputws(lastout
, stdout
);
286 curc
= lastout
= line
;
290 /* Store in output buffer */
291 *curc
++ = (wchar_t)c
;
295 (void) newline_init();
296 curc
= lastout
= line
;
300 col
= col
+ chr_width(c
);
302 col
= (col
+ 8) &~ 7;
303 if (sflg
&& iswspace(c
)) {
321 if (sflg
&& iswspace(c
)) {
338 (void) fprintf(stderr
, gettext(
339 "Usage: fold [-bs] [-w width | -width ] [file...]\n"));
346 *curc
= (wchar_t)NULL
;
347 (void) fputws(lastout
, stdout
);
348 ncol
= col
= spcol
= 0;
356 char chr
[MB_LEN_MAX
+1];
359 n
= wctomb(chr
, (wchar_t)c
);
361 return (n
> 0 ? n
: 0);
365 get_foldw(toptarg
, width
)
376 *width
= strtoul(toptarg
, &p
, 10);
389 /* fold error message */
390 (void) fprintf(stderr
, gettext(
391 "Bad number for fold\n"));