aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-09-10 14:47:27 +0100
committerRon Yorston <rmy@pobox.com>2021-09-10 14:47:27 +0100
commit3eb1d088e09db204f456ad7b76eced21e429f001 (patch)
treea81b5bb422db5ee97475a8f1a4b5236442ed6f14 /coreutils
parent12bc40da28f85cbe97673671f315f847f1dbbabf (diff)
parent40f2dd7dd2e50c9d81dda4d72bf9c85c4c479a89 (diff)
downloadbusybox-w32-3eb1d088e09db204f456ad7b76eced21e429f001.tar.gz
busybox-w32-3eb1d088e09db204f456ad7b76eced21e429f001.tar.bz2
busybox-w32-3eb1d088e09db204f456ad7b76eced21e429f001.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/basename.c62
-rw-r--r--coreutils/shuf.c69
2 files changed, 71 insertions, 60 deletions
diff --git a/coreutils/basename.c b/coreutils/basename.c
index 0dd2c43c7..0b721c03c 100644
--- a/coreutils/basename.c
+++ b/coreutils/basename.c
@@ -29,9 +29,11 @@
29/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ 29/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */
30 30
31//usage:#define basename_trivial_usage 31//usage:#define basename_trivial_usage
32//usage: "FILE [SUFFIX]" 32//usage: "FILE [SUFFIX] | -a FILE... | -s SUFFIX FILE..."
33//usage:#define basename_full_usage "\n\n" 33//usage:#define basename_full_usage "\n\n"
34//usage: "Strip directory path and .SUFFIX from FILE" 34//usage: "Strip directory path and SUFFIX from FILE\n"
35//usage: "\n -a All arguments are FILEs"
36//usage: "\n -s SUFFIX Remove SUFFIX (implies -a)"
35//usage: 37//usage:
36//usage:#define basename_example_usage 38//usage:#define basename_example_usage
37//usage: "$ basename /usr/local/bin/foo\n" 39//usage: "$ basename /usr/local/bin/foo\n"
@@ -48,31 +50,43 @@
48int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 50int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
49int basename_main(int argc UNUSED_PARAM, char **argv) 51int basename_main(int argc UNUSED_PARAM, char **argv)
50{ 52{
51 size_t m, n; 53 unsigned opts;
52 char *s; 54 const char *suffix = NULL;
53 55
54 if (argv[1] && strcmp(argv[1], "--") == 0) { 56 /* '+': stop at first non-option */
55 argv++; 57 opts = getopt32(argv, "^+" "as:"
56 } 58 "\0" "-1" /* At least one argument */
57 if (!argv[1]) 59 , &suffix
58 bb_show_usage(); 60 );
61 argv += optind;
59 62
60 /* It should strip slash: /abc/def/ -> def */ 63 do {
61 s = bb_get_last_path_component_strip(*++argv); 64 char *s;
65 size_t m;
62 66
63 m = strlen(s); 67 /* It should strip slash: /abc/def/ -> def */
64 if (*++argv) { 68 s = bb_get_last_path_component_strip(*argv++);
65 if (argv[1]) 69 m = strlen(s);
66 bb_show_usage(); 70 if (!opts) {
67 n = strlen(*argv); 71 if (*argv) {
68 if ((m > n) && (strcmp(s+m-n, *argv) == 0)) { 72 suffix = *argv;
69 m -= n; 73 if (argv[1])
70 /*s[m] = '\0'; - redundant */ 74 bb_show_usage();
75 }
71 } 76 }
72 } 77 if (suffix) {
78 size_t n = strlen(suffix);
79 if ((m > n) && (strcmp(s + m - n, suffix) == 0)) {
80 m -= n;
81 /*s[m] = '\0'; - redundant */
82 }
83 }
84 /* puts(s) will do, but we can do without stdio this way: */
85 s[m++] = '\n';
86 /* NB: != is correct here: */
87 if (full_write(STDOUT_FILENO, s, m) != (ssize_t)m)
88 return EXIT_FAILURE;
89 } while (opts && *argv);
73 90
74 /* puts(s) will do, but we can do without stdio this way: */ 91 return EXIT_SUCCESS;
75 s[m++] = '\n';
76 /* NB: != is correct here: */
77 return full_write(STDOUT_FILENO, s, m) != (ssize_t)m;
78} 92}
diff --git a/coreutils/shuf.c b/coreutils/shuf.c
index 71b27f497..81b0df453 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -44,21 +44,25 @@
44 */ 44 */
45static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) 45static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines)
46{ 46{
47 unsigned i;
48 unsigned r;
49 char *tmp;
50
51 srand(monotonic_us()); 47 srand(monotonic_us());
52 48
53 for (i = numlines - 1; outlines > 0; i--, outlines--) { 49 while (outlines != 0) {
54 r = rand(); 50 char *tmp;
51 unsigned r = rand();
55 /* RAND_MAX can be as small as 32767 */ 52 /* RAND_MAX can be as small as 32767 */
56 if (i > RAND_MAX) 53 if (numlines > RAND_MAX)
57 r ^= rand() << 15; 54 r ^= rand() << 15;
58 r %= i + 1; 55 r %= numlines;
59 tmp = lines[i]; 56//TODO: the above method is seriously non-uniform when numlines is very large.
60 lines[i] = lines[r]; 57//For example, with numlines of 0xf0000000,
58//values of (r % numlines) in [0, 0x0fffffff] range
59//are more likely: e.g. r=1 and r=0xf0000001 both map to 1,
60//whereas only one value, r=0xefffffff, maps to 0xefffffff.
61 numlines--;
62 tmp = lines[numlines];
63 lines[numlines] = lines[r];
61 lines[r] = tmp; 64 lines[r] = tmp;
65 outlines--;
62 } 66 }
63} 67}
64 68
@@ -67,9 +71,10 @@ int shuf_main(int argc, char **argv)
67{ 71{
68 unsigned opts; 72 unsigned opts;
69 char *opt_i_str, *opt_n_str, *opt_o_str; 73 char *opt_i_str, *opt_n_str, *opt_o_str;
70 unsigned i;
71 char **lines; 74 char **lines;
75 unsigned long long lo = lo;
72 unsigned numlines, outlines; 76 unsigned numlines, outlines;
77 unsigned i;
73 char eol; 78 char eol;
74 79
75 opts = getopt32(argv, "^" 80 opts = getopt32(argv, "^"
@@ -89,8 +94,8 @@ int shuf_main(int argc, char **argv)
89 } else 94 } else
90 if (opts & OPT_i) { 95 if (opts & OPT_i) {
91 /* create a range of numbers */ 96 /* create a range of numbers */
97 unsigned long long hi;
92 char *dash; 98 char *dash;
93 uintptr_t lo, hi;
94 99
95 if (argv[0]) 100 if (argv[0])
96 bb_show_usage(); 101 bb_show_usage();
@@ -100,27 +105,24 @@ int shuf_main(int argc, char **argv)
100 bb_error_msg_and_die("bad range '%s'", opt_i_str); 105 bb_error_msg_and_die("bad range '%s'", opt_i_str);
101 } 106 }
102 *dash = '\0'; 107 *dash = '\0';
103 if (sizeof(lo) == sizeof(int)) { 108 lo = xatoull(opt_i_str);
104 lo = xatou(opt_i_str); 109 hi = xatoull(dash + 1);
105 hi = xatou(dash + 1);
106 } else
107 if (sizeof(lo) == sizeof(long)) {
108 lo = xatoul(opt_i_str);
109 hi = xatoul(dash + 1);
110 } else {
111 lo = xatoull(opt_i_str);
112 hi = xatoull(dash + 1);
113 }
114 *dash = '-'; 110 *dash = '-';
115 if (hi < lo) { 111 if (hi < lo)
116 bb_error_msg_and_die("bad range '%s'", opt_i_str); 112 bb_error_msg_and_die("bad range '%s'", opt_i_str);
113 hi -= lo;
114 if (sizeof(size_t) > sizeof(numlines)) {
115 if (hi >= UINT_MAX)
116 bb_error_msg_and_die("bad range '%s'", opt_i_str);
117 } else {
118 if (hi >= UINT_MAX / sizeof(lines[0]))
119 bb_error_msg_and_die("bad range '%s'", opt_i_str);
117 } 120 }
118 121
119 numlines = (hi+1) - lo; 122 numlines = hi + 1;
120 lines = xmalloc(numlines * sizeof(lines[0])); 123 lines = xmalloc((size_t)numlines * sizeof(lines[0]));
121 for (i = 0; i < numlines; i++) { 124 for (i = 0; i < numlines; i++) {
122 lines[i] = (char*)lo; 125 lines[i] = (char*)(uintptr_t)i;
123 lo++;
124 } 126 }
125 } else { 127 } else {
126 /* default - read lines from stdin or the input file */ 128 /* default - read lines from stdin or the input file */
@@ -163,14 +165,9 @@ int shuf_main(int argc, char **argv)
163 eol = '\0'; 165 eol = '\0';
164 166
165 for (i = numlines - outlines; i < numlines; i++) { 167 for (i = numlines - outlines; i < numlines; i++) {
166 if (opts & OPT_i) { 168 if (opts & OPT_i)
167 if (sizeof(lines[0]) == sizeof(int)) 169 printf("%"LL_FMT"u%c", lo + (uintptr_t)lines[i], eol);
168 printf("%u%c", (unsigned)(uintptr_t)lines[i], eol); 170 else
169 else if (sizeof(lines[0]) == sizeof(long))
170 printf("%lu%c", (unsigned long)(uintptr_t)lines[i], eol);
171 else
172 printf("%"LL_FMT"u%c", (unsigned long long)(uintptr_t)lines[i], eol);
173 } else
174 printf("%s%c", lines[i], eol); 171 printf("%s%c", lines[i], eol);
175 } 172 }
176 173