diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-04 20:49:58 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-04 20:49:58 +0100 |
commit | 28055028a709020ba7eb44f9e5037d0a952b51d6 (patch) | |
tree | bb5dc7052f04e66ad74bbbcc9917d638cd603b24 /coreutils | |
parent | d2b1ba6fdee59645763e915ade3ec55e67d5839a (diff) | |
download | busybox-w32-28055028a709020ba7eb44f9e5037d0a952b51d6.tar.gz busybox-w32-28055028a709020ba7eb44f9e5037d0a952b51d6.tar.bz2 busybox-w32-28055028a709020ba7eb44f9e5037d0a952b51d6.zip |
fold: unicode support. Based on a patch by Tomas Heinrich <heinrich.tomas@gmail.com>
General Unicode support is tweaked to expose unicode_status.
function old new delta
init_unicode - 77 +77
write2stdout - 19 +19
adjust_column 68 71 +3
unicode_status - 1 +1
unicode_is_enabled 1 - -1
grep_main 780 773 -7
fold_main 619 552 -67
check_unicode_in_env 77 - -77
------------------------------------------------------------------------------
(add/remove: 3/2 grow/shrink: 1/2 up/down: 100/-152) Total: -52 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/df.c | 2 | ||||
-rw-r--r-- | coreutils/expand.c | 2 | ||||
-rw-r--r-- | coreutils/fold.c | 161 | ||||
-rw-r--r-- | coreutils/ls.c | 2 |
4 files changed, 91 insertions, 76 deletions
diff --git a/coreutils/df.c b/coreutils/df.c index 83794ad88..bcde78393 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -58,7 +58,7 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
58 | const char *disp_units_hdr = NULL; | 58 | const char *disp_units_hdr = NULL; |
59 | char *chp; | 59 | char *chp; |
60 | 60 | ||
61 | check_unicode_in_env(); | 61 | init_unicode(); |
62 | 62 | ||
63 | #if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY | 63 | #if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY |
64 | opt_complementary = "k-mB:m-Bk:B-km"; | 64 | opt_complementary = "k-mB:m-Bk:B-km"; |
diff --git a/coreutils/expand.c b/coreutils/expand.c index e08eb1d0a..649b4c175 100644 --- a/coreutils/expand.c +++ b/coreutils/expand.c | |||
@@ -144,7 +144,7 @@ int expand_main(int argc UNUSED_PARAM, char **argv) | |||
144 | "all\0" No_argument "a" | 144 | "all\0" No_argument "a" |
145 | ; | 145 | ; |
146 | #endif | 146 | #endif |
147 | check_unicode_in_env(); | 147 | init_unicode(); |
148 | 148 | ||
149 | if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) { | 149 | if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) { |
150 | IF_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts); | 150 | IF_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts); |
diff --git a/coreutils/fold.c b/coreutils/fold.c index 56a346680..cbea31fad 100644 --- a/coreutils/fold.c +++ b/coreutils/fold.c | |||
@@ -9,8 +9,8 @@ | |||
9 | 9 | ||
10 | Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | 10 | Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
11 | */ | 11 | */ |
12 | |||
13 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | #include "unicode.h" | ||
14 | 14 | ||
15 | /* Must match getopt32 call */ | 15 | /* Must match getopt32 call */ |
16 | #define FLAG_COUNT_BYTES 1 | 16 | #define FLAG_COUNT_BYTES 1 |
@@ -20,39 +20,53 @@ | |||
20 | /* Assuming the current column is COLUMN, return the column that | 20 | /* Assuming the current column is COLUMN, return the column that |
21 | printing C will move the cursor to. | 21 | printing C will move the cursor to. |
22 | The first column is 0. */ | 22 | The first column is 0. */ |
23 | static int adjust_column(int column, char c) | 23 | static int adjust_column(unsigned column, char c) |
24 | { | 24 | { |
25 | if (!(option_mask32 & FLAG_COUNT_BYTES)) { | 25 | if (option_mask32 & FLAG_COUNT_BYTES) |
26 | if (c == '\b') { | 26 | return ++column; |
27 | if (column > 0) | 27 | |
28 | column--; | 28 | if (c == '\t') |
29 | } else if (c == '\r') | 29 | return column + 8 - column % 8; |
30 | |||
31 | if (c == '\b') { | ||
32 | if ((int)--column < 0) | ||
30 | column = 0; | 33 | column = 0; |
31 | else if (c == '\t') | 34 | } |
32 | column = column + 8 - column % 8; | 35 | else if (c == '\r') |
33 | else /* if (isprint(c)) */ | 36 | column = 0; |
37 | else { /* just a printable char */ | ||
38 | if (unicode_status != UNICODE_ON /* every byte is a new char */ | ||
39 | || (c & 0xc0) != 0x80 /* it isn't a 2nd+ byte of a Unicode char */ | ||
40 | ) { | ||
34 | column++; | 41 | column++; |
35 | } else | 42 | } |
36 | column++; | 43 | } |
37 | return column; | 44 | return column; |
38 | } | 45 | } |
39 | 46 | ||
47 | /* Note that this function can write NULs, unlike fputs etc. */ | ||
48 | static void write2stdout(const void *buf, unsigned size) | ||
49 | { | ||
50 | fwrite(buf, 1, size, stdout); | ||
51 | } | ||
52 | |||
40 | int fold_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 53 | int fold_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
41 | int fold_main(int argc UNUSED_PARAM, char **argv) | 54 | int fold_main(int argc UNUSED_PARAM, char **argv) |
42 | { | 55 | { |
43 | char *line_out = NULL; | 56 | char *line_out = NULL; |
44 | int allocated_out = 0; | 57 | const char *w_opt = "80"; |
45 | char *w_opt; | 58 | unsigned width; |
46 | int width = 80; | 59 | smallint exitcode = EXIT_SUCCESS; |
47 | int i; | 60 | |
48 | int errs = 0; | 61 | init_unicode(); |
49 | 62 | ||
50 | if (ENABLE_INCLUDE_SUSv2) { | 63 | if (ENABLE_INCLUDE_SUSv2) { |
51 | /* Turn any numeric options into -w options. */ | 64 | /* Turn any numeric options into -w options. */ |
65 | int i; | ||
52 | for (i = 1; argv[i]; i++) { | 66 | for (i = 1; argv[i]; i++) { |
53 | char const *a = argv[i]; | 67 | const char *a = argv[i]; |
54 | 68 | if (*a == '-') { | |
55 | if (*a++ == '-') { | 69 | a++; |
56 | if (*a == '-' && !a[1]) /* "--" */ | 70 | if (*a == '-' && !a[1]) /* "--" */ |
57 | break; | 71 | break; |
58 | if (isdigit(*a)) | 72 | if (isdigit(*a)) |
@@ -62,8 +76,7 @@ int fold_main(int argc UNUSED_PARAM, char **argv) | |||
62 | } | 76 | } |
63 | 77 | ||
64 | getopt32(argv, "bsw:", &w_opt); | 78 | getopt32(argv, "bsw:", &w_opt); |
65 | if (option_mask32 & FLAG_WIDTH) | 79 | width = xatou_range(w_opt, 1, 10000); |
66 | width = xatoul_range(w_opt, 1, 10000); | ||
67 | 80 | ||
68 | argv += optind; | 81 | argv += optind; |
69 | if (!*argv) | 82 | if (!*argv) |
@@ -72,79 +85,81 @@ int fold_main(int argc UNUSED_PARAM, char **argv) | |||
72 | do { | 85 | do { |
73 | FILE *istream = fopen_or_warn_stdin(*argv); | 86 | FILE *istream = fopen_or_warn_stdin(*argv); |
74 | int c; | 87 | int c; |
75 | int column = 0; /* Screen column where next char will go. */ | 88 | unsigned column = 0; /* Screen column where next char will go */ |
76 | int offset_out = 0; /* Index in 'line_out' for next char. */ | 89 | unsigned offset_out = 0; /* Index in 'line_out' for next char */ |
77 | 90 | ||
78 | if (istream == NULL) { | 91 | if (istream == NULL) { |
79 | errs |= EXIT_FAILURE; | 92 | exitcode = EXIT_FAILURE; |
80 | continue; | 93 | continue; |
81 | } | 94 | } |
82 | 95 | ||
83 | while ((c = getc(istream)) != EOF) { | 96 | while ((c = getc(istream)) != EOF) { |
84 | if (offset_out + 1 >= allocated_out) { | 97 | /* We grow line_out in chunks of 0x1000 bytes */ |
85 | allocated_out += 1024; | 98 | if ((offset_out & 0xfff) == 0) { |
86 | line_out = xrealloc(line_out, allocated_out); | 99 | line_out = xrealloc(line_out, offset_out + 0x1000); |
87 | } | 100 | } |
88 | 101 | rescan: | |
102 | line_out[offset_out] = c; | ||
89 | if (c == '\n') { | 103 | if (c == '\n') { |
90 | line_out[offset_out++] = c; | 104 | write2stdout(line_out, offset_out + 1); |
91 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | ||
92 | column = offset_out = 0; | 105 | column = offset_out = 0; |
93 | continue; | 106 | continue; |
94 | } | 107 | } |
95 | rescan: | ||
96 | column = adjust_column(column, c); | 108 | column = adjust_column(column, c); |
109 | if (column <= width || offset_out == 0) { | ||
110 | /* offset_out == 0 case happens | ||
111 | * with small width (say, 1) and tabs. | ||
112 | * The very first tab already goes to column 8, | ||
113 | * but we must not wrap it */ | ||
114 | offset_out++; | ||
115 | continue; | ||
116 | } | ||
97 | 117 | ||
98 | if (column > width) { | 118 | /* This character would make the line too long. |
99 | /* This character would make the line too long. | 119 | * Print the line plus a newline, and make this character |
100 | Print the line plus a newline, and make this character | 120 | * start the next line */ |
101 | start the next line. */ | 121 | if (option_mask32 & FLAG_BREAK_SPACES) { |
102 | if (option_mask32 & FLAG_BREAK_SPACES) { | 122 | unsigned i; |
103 | /* Look for the last blank. */ | 123 | unsigned logical_end; |
104 | int logical_end; | 124 | |
105 | 125 | /* Look for the last blank. */ | |
106 | for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) { | 126 | for (logical_end = offset_out - 1; (int)logical_end >= 0; logical_end--) { |
107 | if (isblank(line_out[logical_end])) { | 127 | if (!isblank(line_out[logical_end])) |
108 | break; | 128 | continue; |
109 | } | 129 | |
130 | /* Found a space or tab. | ||
131 | * Output up to and including it, and start a new line */ | ||
132 | logical_end++; | ||
133 | /*line_out[logical_end] = '\n'; - NO! this nukes one buffered character */ | ||
134 | write2stdout(line_out, logical_end); | ||
135 | putchar('\n'); | ||
136 | /* Move the remainder to the beginning of the next line. | ||
137 | * The areas being copied here might overlap. */ | ||
138 | memmove(line_out, line_out + logical_end, offset_out - logical_end); | ||
139 | offset_out -= logical_end; | ||
140 | for (column = i = 0; i < offset_out; i++) { | ||
141 | column = adjust_column(column, line_out[i]); | ||
110 | } | 142 | } |
111 | if (logical_end >= 0) { | 143 | goto rescan; |
112 | /* Found a blank. Don't output the part after it. */ | ||
113 | logical_end++; | ||
114 | fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); | ||
115 | bb_putchar('\n'); | ||
116 | /* Move the remainder to the beginning of the next line. | ||
117 | The areas being copied here might overlap. */ | ||
118 | memmove(line_out, line_out + logical_end, offset_out - logical_end); | ||
119 | offset_out -= logical_end; | ||
120 | for (column = i = 0; i < offset_out; i++) { | ||
121 | column = adjust_column(column, line_out[i]); | ||
122 | } | ||
123 | goto rescan; | ||
124 | } | ||
125 | } | ||
126 | if (offset_out == 0) { | ||
127 | line_out[offset_out++] = c; | ||
128 | continue; | ||
129 | } | 144 | } |
130 | line_out[offset_out++] = '\n'; | 145 | /* No blank found, wrap will split the overlong word */ |
131 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | ||
132 | column = offset_out = 0; | ||
133 | goto rescan; | ||
134 | } | 146 | } |
135 | 147 | /* Output what we accumulated up to now, and start a new line */ | |
136 | line_out[offset_out++] = c; | 148 | line_out[offset_out] = '\n'; |
137 | } | 149 | write2stdout(line_out, offset_out + 1); |
150 | column = offset_out = 0; | ||
151 | goto rescan; | ||
152 | } /* while (not EOF) */ | ||
138 | 153 | ||
139 | if (offset_out) { | 154 | if (offset_out) { |
140 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | 155 | write2stdout(line_out, offset_out); |
141 | } | 156 | } |
142 | 157 | ||
143 | if (fclose_if_not_stdin(istream)) { | 158 | if (fclose_if_not_stdin(istream)) { |
144 | bb_simple_perror_msg(*argv); /* Avoid multibyte problems. */ | 159 | bb_simple_perror_msg(*argv); |
145 | errs |= EXIT_FAILURE; | 160 | exitcode = EXIT_FAILURE; |
146 | } | 161 | } |
147 | } while (*++argv); | 162 | } while (*++argv); |
148 | 163 | ||
149 | fflush_stdout_and_exit(errs); | 164 | fflush_stdout_and_exit(exitcode); |
150 | } | 165 | } |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 13c863c6e..5ea3a0b27 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -945,7 +945,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
945 | 945 | ||
946 | INIT_G(); | 946 | INIT_G(); |
947 | 947 | ||
948 | check_unicode_in_env(); | 948 | init_unicode(); |
949 | 949 | ||
950 | all_fmt = LIST_SHORT | | 950 | all_fmt = LIST_SHORT | |
951 | (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD)); | 951 | (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD)); |