mirror of
https://github.com/mirror/busybox.git
synced 2025-09-10 22:45:25 +02:00
shuf: add (disabled) code to support very long numbers in -i LO-HI
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
@@ -66,6 +66,12 @@ static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines)
|
||||
}
|
||||
}
|
||||
|
||||
/* We can handle insanity like this:
|
||||
* shuf -i 3333333333333333333333333333333333333333333333333333333333333123456789001-3333333333333333333333333333333333333333333333333333333333333123456789019
|
||||
* but do we want to have +200 bytes of code (~40% code growth)?
|
||||
*/
|
||||
#define COMMON_PREFIX_HACK 0
|
||||
|
||||
int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int shuf_main(int argc, char **argv)
|
||||
{
|
||||
@@ -76,6 +82,11 @@ int shuf_main(int argc, char **argv)
|
||||
unsigned numlines, outlines;
|
||||
unsigned i;
|
||||
char eol;
|
||||
#if COMMON_PREFIX_HACK
|
||||
unsigned pfx_len = 0;
|
||||
unsigned padding_width = padding_width;
|
||||
const char *pfx = pfx;
|
||||
#endif
|
||||
|
||||
opts = getopt32(argv, "^"
|
||||
OPT_STR
|
||||
@@ -104,10 +115,46 @@ int shuf_main(int argc, char **argv)
|
||||
if (!dash) {
|
||||
bb_error_msg_and_die("bad range '%s'", opt_i_str);
|
||||
}
|
||||
*dash = '\0';
|
||||
*dash++ = '\0';
|
||||
#if COMMON_PREFIX_HACK
|
||||
{
|
||||
const char *a = opt_i_str;
|
||||
const char *b = dash;
|
||||
/* Skip leading zeros (they may mask that common prefix does exist) */
|
||||
while (*a == '0') a++;
|
||||
while (*b == '0') b++;
|
||||
/* Do we have a common prefix (long enough to bother)? */
|
||||
padding_width = strlen(a);
|
||||
if (padding_width > 5 && padding_width == strlen(b)) {
|
||||
/* How long is it? */
|
||||
pfx = a;
|
||||
while (isdigit(*a) && *a == *b) {
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
if (*a == '\0') {
|
||||
/* "123456-123456", and we 'ate' all of them */
|
||||
/* prevent trying to xatoull("") */
|
||||
a--;
|
||||
b--;
|
||||
}
|
||||
pfx_len = a - opt_i_str; /* can end up being 0 */
|
||||
padding_width -= pfx_len;
|
||||
lo = xatoull(a);
|
||||
hi = xatoull(b);
|
||||
} else {
|
||||
/* Undo leading zero 'eating' (think "0-9") */
|
||||
a = opt_i_str;
|
||||
b = dash;
|
||||
}
|
||||
lo = xatoull(a);
|
||||
hi = xatoull(b);
|
||||
}
|
||||
#else
|
||||
lo = xatoull(opt_i_str);
|
||||
hi = xatoull(dash + 1);
|
||||
*dash = '-';
|
||||
hi = xatoull(dash);
|
||||
#endif
|
||||
dash[-1] = '-';
|
||||
if (hi < lo)
|
||||
bb_error_msg_and_die("bad range '%s'", opt_i_str);
|
||||
hi -= lo;
|
||||
@@ -165,9 +212,14 @@ int shuf_main(int argc, char **argv)
|
||||
eol = '\0';
|
||||
|
||||
for (i = numlines - outlines; i < numlines; i++) {
|
||||
if (opts & OPT_i)
|
||||
printf("%llu%c", lo + (uintptr_t)lines[i], eol);
|
||||
else
|
||||
if (opts & OPT_i) {
|
||||
#if COMMON_PREFIX_HACK
|
||||
if (pfx_len != 0)
|
||||
printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol);
|
||||
else
|
||||
#endif
|
||||
printf("%llu%c", lo + (uintptr_t)lines[i], eol);
|
||||
} else
|
||||
printf("%s%c", lines[i], eol);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user