5 |
Copyright (C) 91, 1995-2002 Free Software Foundation, Inc. |
Copyright (C) 91, 1995-2002 Free Software Foundation, Inc. |
6 |
|
|
7 |
Modified for busybox based on coreutils v 5.0 |
Modified for busybox based on coreutils v 5.0 |
8 |
Copyright (C) 2003 Glenn McGrath <bug1@iinet.net.au> |
Copyright (C) 2003 Glenn McGrath |
9 |
|
|
10 |
Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
11 |
*/ |
*/ |
12 |
|
|
13 |
#include "busybox.h" |
#include "libbb.h" |
14 |
|
|
15 |
static unsigned long flags; |
/* Must match getopt32 call */ |
16 |
#define FLAG_COUNT_BYTES 1 |
#define FLAG_COUNT_BYTES 1 |
17 |
#define FLAG_BREAK_SPACES 2 |
#define FLAG_BREAK_SPACES 2 |
18 |
#define FLAG_WIDTH 4 |
#define FLAG_WIDTH 4 |
19 |
|
|
20 |
/* Assuming the current column is COLUMN, return the column that |
/* Assuming the current column is COLUMN, return the column that |
21 |
printing C will move the cursor to. |
printing C will move the cursor to. |
22 |
The first column is 0. */ |
The first column is 0. */ |
|
|
|
23 |
static int adjust_column(int column, char c) |
static int adjust_column(int column, char c) |
24 |
{ |
{ |
25 |
if (!(flags & FLAG_COUNT_BYTES)) { |
if (!(option_mask32 & FLAG_COUNT_BYTES)) { |
26 |
if (c == '\b') { |
if (c == '\b') { |
27 |
if (column > 0) |
if (column > 0) |
28 |
column--; |
column--; |
37 |
return column; |
return column; |
38 |
} |
} |
39 |
|
|
40 |
|
int fold_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
41 |
int fold_main(int argc, char **argv) |
int fold_main(int argc, char **argv) |
42 |
{ |
{ |
43 |
|
char *line_out = NULL; |
44 |
|
int allocated_out = 0; |
45 |
char *w_opt; |
char *w_opt; |
46 |
int width = 80; |
int width = 80; |
47 |
int i; |
int i; |
53 |
char const *a = argv[i]; |
char const *a = argv[i]; |
54 |
|
|
55 |
if (*a++ == '-') { |
if (*a++ == '-') { |
56 |
if (*a == '-' && !a[1]) |
if (*a == '-' && !a[1]) /* "--" */ |
57 |
break; |
break; |
58 |
if (isdigit(*a)) { |
if (isdigit(*a)) |
59 |
argv[i] = xasprintf("-w%s", a); |
argv[i] = xasprintf("-w%s", a); |
|
} |
|
60 |
} |
} |
61 |
} |
} |
62 |
} |
} |
63 |
|
|
64 |
flags = getopt32(argc, argv, "bsw:", &w_opt); |
getopt32(argv, "bsw:", &w_opt); |
65 |
if (flags & FLAG_WIDTH) |
if (option_mask32 & FLAG_WIDTH) |
66 |
width = xatoul_range(w_opt, 1, 10000); |
width = xatoul_range(w_opt, 1, 10000); |
67 |
|
|
68 |
argv += optind; |
argv += optind; |
69 |
if (!*argv) { |
if (!*argv) |
70 |
*--argv = "-"; |
*--argv = (char*)"-"; |
|
} |
|
71 |
|
|
72 |
do { |
do { |
73 |
FILE *istream = fopen_or_warn_stdin(*argv); |
FILE *istream = fopen_or_warn_stdin(*argv); |
74 |
int c; |
int c; |
75 |
int column = 0; /* Screen column where next char will go. */ |
int column = 0; /* Screen column where next char will go. */ |
76 |
int offset_out = 0; /* Index in `line_out' for next char. */ |
int offset_out = 0; /* Index in 'line_out' for next char. */ |
|
static char *line_out = NULL; |
|
|
static int allocated_out = 0; |
|
77 |
|
|
78 |
if (istream == NULL) { |
if (istream == NULL) { |
79 |
errs |= EXIT_FAILURE; |
errs |= EXIT_FAILURE; |
92 |
column = offset_out = 0; |
column = offset_out = 0; |
93 |
continue; |
continue; |
94 |
} |
} |
95 |
|
rescan: |
|
rescan: |
|
96 |
column = adjust_column(column, c); |
column = adjust_column(column, c); |
97 |
|
|
98 |
if (column > width) { |
if (column > width) { |
99 |
/* This character would make the line too long. |
/* This character would make the line too long. |
100 |
Print the line plus a newline, and make this character |
Print the line plus a newline, and make this character |
101 |
start the next line. */ |
start the next line. */ |
102 |
if (flags & FLAG_BREAK_SPACES) { |
if (option_mask32 & FLAG_BREAK_SPACES) { |
103 |
/* Look for the last blank. */ |
/* Look for the last blank. */ |
104 |
int logical_end; |
int logical_end; |
105 |
|
|
112 |
/* Found a blank. Don't output the part after it. */ |
/* Found a blank. Don't output the part after it. */ |
113 |
logical_end++; |
logical_end++; |
114 |
fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); |
fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); |
115 |
putchar('\n'); |
bb_putchar('\n'); |
116 |
/* Move the remainder to the beginning of the next line. |
/* Move the remainder to the beginning of the next line. |
117 |
The areas being copied here might overlap. */ |
The areas being copied here might overlap. */ |
118 |
memmove(line_out, line_out + logical_end, offset_out - logical_end); |
memmove(line_out, line_out + logical_end, offset_out - logical_end); |
141 |
fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); |
fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); |
142 |
} |
} |
143 |
|
|
144 |
if (ferror(istream) || fclose_if_not_stdin(istream)) { |
if (fclose_if_not_stdin(istream)) { |
145 |
bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ |
bb_simple_perror_msg(*argv); /* Avoid multibyte problems. */ |
146 |
errs |= EXIT_FAILURE; |
errs |= EXIT_FAILURE; |
147 |
} |
} |
148 |
} while (*++argv); |
} while (*++argv); |