aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-04-17 07:32:52 +0100
committerRon Yorston <rmy@pobox.com>2023-04-17 07:32:52 +0100
commit8cdeb571cfbf3bb6edc44779e46537b072b8cd08 (patch)
tree9f3ad1d205418197bc53348b61f702602229a90d /coreutils
parent41827dd448c001b52b4f0e591ea605cb5de1d230 (diff)
parentd2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a (diff)
downloadbusybox-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.c29
-rw-r--r--coreutils/seq.c27
-rw-r--r--coreutils/shuf.c58
-rw-r--r--coreutils/sleep.c3
-rw-r--r--coreutils/tr.c2
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
69int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 75int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
70int shuf_main(int argc, char **argv) 76int 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);