diff options
author | Ron Yorston <rmy@pobox.com> | 2023-04-17 07:32:52 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-04-17 07:32:52 +0100 |
commit | 8cdeb571cfbf3bb6edc44779e46537b072b8cd08 (patch) | |
tree | 9f3ad1d205418197bc53348b61f702602229a90d /coreutils | |
parent | 41827dd448c001b52b4f0e591ea605cb5de1d230 (diff) | |
parent | d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a (diff) | |
download | busybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.tar.gz busybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.tar.bz2 busybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/readlink.c | 29 | ||||
-rw-r--r-- | coreutils/seq.c | 27 | ||||
-rw-r--r-- | coreutils/shuf.c | 58 | ||||
-rw-r--r-- | coreutils/sleep.c | 3 | ||||
-rw-r--r-- | coreutils/tr.c | 2 |
5 files changed, 92 insertions, 27 deletions
diff --git a/coreutils/readlink.c b/coreutils/readlink.c index b2e867883..0a9aa957e 100644 --- a/coreutils/readlink.c +++ b/coreutils/readlink.c | |||
@@ -25,12 +25,14 @@ | |||
25 | //kbuild:lib-$(CONFIG_READLINK) += readlink.o | 25 | //kbuild:lib-$(CONFIG_READLINK) += readlink.o |
26 | 26 | ||
27 | //usage:#define readlink_trivial_usage | 27 | //usage:#define readlink_trivial_usage |
28 | //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE" | 28 | //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") |
29 | //usage: IF_NOT_FEATURE_READLINK_FOLLOW("[-n] ") | ||
30 | //usage: "FILE" | ||
29 | //usage:#define readlink_full_usage "\n\n" | 31 | //usage:#define readlink_full_usage "\n\n" |
30 | //usage: "Display the value of a symlink" | 32 | //usage: "Display the value of a symlink" "\n" |
31 | //usage: IF_FEATURE_READLINK_FOLLOW( "\n" | ||
32 | //usage: "\n -f Canonicalize by following all symlinks" | ||
33 | //usage: "\n -n Don't add newline" | 33 | //usage: "\n -n Don't add newline" |
34 | //usage: IF_FEATURE_READLINK_FOLLOW( | ||
35 | //usage: "\n -f Canonicalize by following all symlinks" | ||
34 | //usage: "\n -v Verbose" | 36 | //usage: "\n -v Verbose" |
35 | //usage: ) | 37 | //usage: ) |
36 | 38 | ||
@@ -67,25 +69,18 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) | |||
67 | { | 69 | { |
68 | char *buf; | 70 | char *buf; |
69 | char *fname; | 71 | char *fname; |
72 | unsigned opt; | ||
70 | 73 | ||
71 | IF_FEATURE_READLINK_FOLLOW( | 74 | opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq") |
72 | unsigned opt; | 75 | "\0" "=1"); |
73 | /* We need exactly one non-option argument. */ | 76 | fname = argv[optind]; |
74 | opt = getopt32(argv, "^" "fnvsq" "\0" "=1"); | ||
75 | fname = argv[optind]; | ||
76 | ) | ||
77 | IF_NOT_FEATURE_READLINK_FOLLOW( | ||
78 | const unsigned opt = 0; | ||
79 | if (argc != 2) bb_show_usage(); | ||
80 | fname = argv[1]; | ||
81 | ) | ||
82 | 77 | ||
83 | /* compat: coreutils readlink reports errors silently via exit code */ | 78 | /* compat: coreutils readlink reports errors silently via exit code */ |
84 | if (!(opt & 4)) /* not -v */ | 79 | if (!(opt & 4)) /* not -v */ |
85 | logmode = LOGMODE_NONE; | 80 | logmode = LOGMODE_NONE; |
86 | 81 | ||
87 | /* NOFORK: only one alloc is allowed; must free */ | 82 | /* NOFORK: only one alloc is allowed; must free */ |
88 | if (opt & 1) { /* -f */ | 83 | if (opt & 2) { /* -f */ |
89 | buf = xmalloc_realpath_coreutils(fname); | 84 | buf = xmalloc_realpath_coreutils(fname); |
90 | } else { | 85 | } else { |
91 | buf = xmalloc_readlink_or_warn(fname); | 86 | buf = xmalloc_readlink_or_warn(fname); |
@@ -93,7 +88,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) | |||
93 | 88 | ||
94 | if (!buf) | 89 | if (!buf) |
95 | return EXIT_FAILURE; | 90 | return EXIT_FAILURE; |
96 | printf((opt & 2) ? "%s" : "%s\n", buf); | 91 | printf((opt & 1) ? "%s" : "%s\n", buf); |
97 | free(buf); | 92 | free(buf); |
98 | 93 | ||
99 | fflush_stdout_and_exit_SUCCESS(); | 94 | fflush_stdout_and_exit_SUCCESS(); |
diff --git a/coreutils/seq.c b/coreutils/seq.c index beb339d1e..77a8aba8a 100644 --- a/coreutils/seq.c +++ b/coreutils/seq.c | |||
@@ -22,7 +22,7 @@ | |||
22 | //usage:#define seq_full_usage "\n\n" | 22 | //usage:#define seq_full_usage "\n\n" |
23 | //usage: "Print numbers from FIRST to LAST, in steps of INC.\n" | 23 | //usage: "Print numbers from FIRST to LAST, in steps of INC.\n" |
24 | //usage: "FIRST, INC default to 1.\n" | 24 | //usage: "FIRST, INC default to 1.\n" |
25 | //usage: "\n -w Pad to last with leading zeros" | 25 | //usage: "\n -w Pad with leading zeros" |
26 | //usage: "\n -s SEP String separator" | 26 | //usage: "\n -s SEP String separator" |
27 | 27 | ||
28 | #include "libbb.h" | 28 | #include "libbb.h" |
@@ -41,6 +41,7 @@ int seq_main(int argc, char **argv) | |||
41 | unsigned width; | 41 | unsigned width; |
42 | unsigned frac_part; | 42 | unsigned frac_part; |
43 | const char *sep, *opt_s = "\n"; | 43 | const char *sep, *opt_s = "\n"; |
44 | char *saved; | ||
44 | unsigned opt; | 45 | unsigned opt; |
45 | 46 | ||
46 | #if ENABLE_LOCALE_SUPPORT | 47 | #if ENABLE_LOCALE_SUPPORT |
@@ -49,7 +50,29 @@ int seq_main(int argc, char **argv) | |||
49 | setlocale(LC_NUMERIC, "C"); | 50 | setlocale(LC_NUMERIC, "C"); |
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | opt = getopt32(argv, "+ws:", &opt_s); | 53 | /* Cater for negative arguments: if we see one, truncate argv[] on it */ |
54 | n = 0; | ||
55 | for (;;) { | ||
56 | char c; | ||
57 | saved = argv[++n]; | ||
58 | if (!saved) | ||
59 | break; | ||
60 | if (saved[0] != '-') { | ||
61 | // break; // "seq -s : -1 1" won't be treated correctly | ||
62 | continue; | ||
63 | } | ||
64 | // "seq -s -1 1 9" is not treated correctly, but such usage | ||
65 | // (delimiter string which looks like negative number) is very unlikely | ||
66 | c = saved[1]; | ||
67 | if (c == '.' || (c >= '0' && c <= '9')) { | ||
68 | argv[n] = NULL; | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | opt = getopt32(argv, "+ws:", &opt_s); /* "+": stop at first non-option */ | ||
73 | /* Restore possibly truncated argv[] */ | ||
74 | argv[n] = saved; | ||
75 | |||
53 | argc -= optind; | 76 | argc -= optind; |
54 | argv += optind; | 77 | argv += optind; |
55 | first = increment = 1; | 78 | first = increment = 1; |
diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 56ba03aad..466969745 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c | |||
@@ -66,6 +66,12 @@ static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) | |||
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | /* We can handle insanity like this: | ||
70 | * shuf -i 333333333333333333333333333333001-333333333333333333333333333333019 | ||
71 | * but do we want to have +200 bytes of code (~40% code growth)? | ||
72 | */ | ||
73 | #define COMMON_PREFIX_HACK 0 | ||
74 | |||
69 | int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 75 | int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
70 | int shuf_main(int argc, char **argv) | 76 | int shuf_main(int argc, char **argv) |
71 | { | 77 | { |
@@ -76,6 +82,11 @@ int shuf_main(int argc, char **argv) | |||
76 | unsigned numlines, outlines; | 82 | unsigned numlines, outlines; |
77 | unsigned i; | 83 | unsigned i; |
78 | char eol; | 84 | char eol; |
85 | #if COMMON_PREFIX_HACK | ||
86 | unsigned pfx_len = 0; | ||
87 | unsigned padding_width = padding_width; | ||
88 | const char *pfx = pfx; | ||
89 | #endif | ||
79 | 90 | ||
80 | opts = getopt32(argv, "^" | 91 | opts = getopt32(argv, "^" |
81 | OPT_STR | 92 | OPT_STR |
@@ -104,10 +115,40 @@ int shuf_main(int argc, char **argv) | |||
104 | if (!dash) { | 115 | if (!dash) { |
105 | bb_error_msg_and_die("bad range '%s'", opt_i_str); | 116 | bb_error_msg_and_die("bad range '%s'", opt_i_str); |
106 | } | 117 | } |
107 | *dash = '\0'; | 118 | *dash++ = '\0'; |
119 | #if COMMON_PREFIX_HACK | ||
120 | { | ||
121 | const char *a = opt_i_str; | ||
122 | const char *b = dash; | ||
123 | /* Skip leading zeros (they may mask that common prefix does exist) */ | ||
124 | while (*a == '0') a++; | ||
125 | while (*b == '0') b++; | ||
126 | /* Do we have a common prefix (long enough to bother)? */ | ||
127 | padding_width = strlen(a); | ||
128 | if (padding_width > 5 && padding_width == strlen(b)) { | ||
129 | /* How long is it? */ | ||
130 | pfx = a; | ||
131 | while (isdigit(*a) && *a == *b | ||
132 | && a[1] /* "111111-111111" case: avoid xatoull("") */ | ||
133 | ) { | ||
134 | a++; | ||
135 | b++; | ||
136 | } | ||
137 | pfx_len = a - pfx; /* can end up being 0 */ | ||
138 | padding_width -= pfx_len; | ||
139 | } else { | ||
140 | /* Undo leading zero 'eating' (think "0-9") */ | ||
141 | a = opt_i_str; | ||
142 | b = dash; | ||
143 | } | ||
144 | lo = xatoull(a); | ||
145 | hi = xatoull(b); | ||
146 | } | ||
147 | #else | ||
108 | lo = xatoull(opt_i_str); | 148 | lo = xatoull(opt_i_str); |
109 | hi = xatoull(dash + 1); | 149 | hi = xatoull(dash); |
110 | *dash = '-'; | 150 | #endif |
151 | dash[-1] = '-'; | ||
111 | if (hi < lo) | 152 | if (hi < lo) |
112 | bb_error_msg_and_die("bad range '%s'", opt_i_str); | 153 | bb_error_msg_and_die("bad range '%s'", opt_i_str); |
113 | hi -= lo; | 154 | hi -= lo; |
@@ -165,9 +206,14 @@ int shuf_main(int argc, char **argv) | |||
165 | eol = '\0'; | 206 | eol = '\0'; |
166 | 207 | ||
167 | for (i = numlines - outlines; i < numlines; i++) { | 208 | for (i = numlines - outlines; i < numlines; i++) { |
168 | if (opts & OPT_i) | 209 | if (opts & OPT_i) { |
169 | printf("%"LL_FMT"u%c", lo + (uintptr_t)lines[i], eol); | 210 | #if COMMON_PREFIX_HACK |
170 | else | 211 | if (pfx_len != 0) |
212 | printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol); | ||
213 | else | ||
214 | #endif | ||
215 | printf("%llu%c", lo + (uintptr_t)lines[i], eol); | ||
216 | } else | ||
171 | printf("%s%c", lines[i], eol); | 217 | printf("%s%c", lines[i], eol); |
172 | } | 218 | } |
173 | 219 | ||
diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 667db558d..a0cee5a4a 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c | |||
@@ -74,7 +74,8 @@ int sleep_main(int argc UNUSED_PARAM, char **argv) | |||
74 | ++argv; | 74 | ++argv; |
75 | if (!*argv) { | 75 | if (!*argv) { |
76 | /* Without this, bare "sleep" in ash shows _ash_ --help */ | 76 | /* Without this, bare "sleep" in ash shows _ash_ --help */ |
77 | if (ENABLE_ASH_SLEEP && applet_name[0] != 's') { | 77 | /* (ash can be the "sh" applet as well, so check 2nd char) */ |
78 | if (ENABLE_ASH_SLEEP && applet_name[1] != 'l') { | ||
78 | bb_simple_error_msg("sleep: missing operand"); | 79 | bb_simple_error_msg("sleep: missing operand"); |
79 | return EXIT_FAILURE; | 80 | return EXIT_FAILURE; |
80 | } | 81 | } |
diff --git a/coreutils/tr.c b/coreutils/tr.c index 1e402dfdb..7fe7f89d5 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -299,7 +299,7 @@ int tr_main(int argc UNUSED_PARAM, char **argv) | |||
299 | */ | 299 | */ |
300 | 300 | ||
301 | /* '+': stop at first non-option */ | 301 | /* '+': stop at first non-option */ |
302 | opts = getopt32(argv, "^+" "Ccds" "\0" "-1"); | 302 | opts = getopt32(argv, "^+" "Ccds" "\0" "-1:?2"); |
303 | argv += optind; | 303 | argv += optind; |
304 | 304 | ||
305 | str1_length = expand(*argv++, &str1); | 305 | str1_length = expand(*argv++, &str1); |