diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-04-12 14:47:24 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-04-12 14:47:24 +0200 |
commit | 238dab322a630b493843a6bdf3203e93db87469a (patch) | |
tree | ce17e0be8dd7a4e3d016384c920b60f8b9942563 | |
parent | 853cfe927fd656a2688ac2bfc81c69e1004c44df (diff) | |
download | busybox-w32-238dab322a630b493843a6bdf3203e93db87469a.tar.gz busybox-w32-238dab322a630b493843a6bdf3203e93db87469a.tar.bz2 busybox-w32-238dab322a630b493843a6bdf3203e93db87469a.zip |
shuf: add (disabled) code to support very long numbers in -i LO-HI
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/shuf.c | 64 |
1 files changed, 58 insertions, 6 deletions
diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 337366b45..fe0358e07 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 3333333333333333333333333333333333333333333333333333333333333123456789001-3333333333333333333333333333333333333333333333333333333333333123456789019 | ||
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,46 @@ 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++; | ||
133 | b++; | ||
134 | } | ||
135 | if (*a == '\0') { | ||
136 | /* "123456-123456", and we 'ate' all of them */ | ||
137 | /* prevent trying to xatoull("") */ | ||
138 | a--; | ||
139 | b--; | ||
140 | } | ||
141 | pfx_len = a - opt_i_str; /* can end up being 0 */ | ||
142 | padding_width -= pfx_len; | ||
143 | lo = xatoull(a); | ||
144 | hi = xatoull(b); | ||
145 | } else { | ||
146 | /* Undo leading zero 'eating' (think "0-9") */ | ||
147 | a = opt_i_str; | ||
148 | b = dash; | ||
149 | } | ||
150 | lo = xatoull(a); | ||
151 | hi = xatoull(b); | ||
152 | } | ||
153 | #else | ||
108 | lo = xatoull(opt_i_str); | 154 | lo = xatoull(opt_i_str); |
109 | hi = xatoull(dash + 1); | 155 | hi = xatoull(dash); |
110 | *dash = '-'; | 156 | #endif |
157 | dash[-1] = '-'; | ||
111 | if (hi < lo) | 158 | if (hi < lo) |
112 | bb_error_msg_and_die("bad range '%s'", opt_i_str); | 159 | bb_error_msg_and_die("bad range '%s'", opt_i_str); |
113 | hi -= lo; | 160 | hi -= lo; |
@@ -165,9 +212,14 @@ int shuf_main(int argc, char **argv) | |||
165 | eol = '\0'; | 212 | eol = '\0'; |
166 | 213 | ||
167 | for (i = numlines - outlines; i < numlines; i++) { | 214 | for (i = numlines - outlines; i < numlines; i++) { |
168 | if (opts & OPT_i) | 215 | if (opts & OPT_i) { |
169 | printf("%llu%c", lo + (uintptr_t)lines[i], eol); | 216 | #if COMMON_PREFIX_HACK |
170 | else | 217 | if (pfx_len != 0) |
218 | printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol); | ||
219 | else | ||
220 | #endif | ||
221 | printf("%llu%c", lo + (uintptr_t)lines[i], eol); | ||
222 | } else | ||
171 | printf("%s%c", lines[i], eol); | 223 | printf("%s%c", lines[i], eol); |
172 | } | 224 | } |
173 | 225 | ||