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); |
