diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-15 09:16:27 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-15 09:16:27 +0200 |
| commit | cd3dd42c28832da92ee0d4d3afe7cf722e38f80c (patch) | |
| tree | 6c97c10fb539f2d8cb8d3f34eff73ac6bcecf70b /coreutils | |
| parent | 82a6fb3ea6b49bcf1ef21ab589179ee2d6ffdc09 (diff) | |
| download | busybox-w32-cd3dd42c28832da92ee0d4d3afe7cf722e38f80c.tar.gz busybox-w32-cd3dd42c28832da92ee0d4d3afe7cf722e38f80c.tar.bz2 busybox-w32-cd3dd42c28832da92ee0d4d3afe7cf722e38f80c.zip | |
seq: fix testsuite failures
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/seq.c | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/coreutils/seq.c b/coreutils/seq.c index 4b853c698..bb39a5b54 100644 --- a/coreutils/seq.c +++ b/coreutils/seq.c | |||
| @@ -6,12 +6,10 @@ | |||
| 6 | * | 6 | * |
| 7 | * Licensed under the GPL v2, see the file LICENSE in this tarball. | 7 | * Licensed under the GPL v2, see the file LICENSE in this tarball. |
| 8 | */ | 8 | */ |
| 9 | |||
| 10 | #include "libbb.h" | 9 | #include "libbb.h" |
| 11 | 10 | ||
| 12 | /* This is a NOFORK applet. Be very careful! */ | 11 | /* This is a NOFORK applet. Be very careful! */ |
| 13 | 12 | ||
| 14 | |||
| 15 | int seq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 13 | int seq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 16 | int seq_main(int argc, char **argv) | 14 | int seq_main(int argc, char **argv) |
| 17 | { | 15 | { |
| @@ -19,35 +17,72 @@ int seq_main(int argc, char **argv) | |||
| 19 | OPT_w = (1 << 0), | 17 | OPT_w = (1 << 0), |
| 20 | OPT_s = (1 << 1), | 18 | OPT_s = (1 << 1), |
| 21 | }; | 19 | }; |
| 22 | double last, increment, i; | 20 | double first, last, increment, v; |
| 21 | unsigned n; | ||
| 22 | unsigned width; | ||
| 23 | unsigned frac_part; | ||
| 23 | const char *sep, *opt_s = "\n"; | 24 | const char *sep, *opt_s = "\n"; |
| 24 | unsigned opt = getopt32(argv, "+ws:", &opt_s); | 25 | unsigned opt = getopt32(argv, "+ws:", &opt_s); |
| 25 | unsigned width = 0; | ||
| 26 | 26 | ||
| 27 | argc -= optind; | 27 | argc -= optind; |
| 28 | argv += optind; | 28 | argv += optind; |
| 29 | i = increment = 1; | 29 | first = increment = 1; |
| 30 | errno = 0; | ||
| 30 | switch (argc) { | 31 | switch (argc) { |
| 32 | char *pp; | ||
| 31 | case 3: | 33 | case 3: |
| 32 | increment = atof(argv[1]); | 34 | increment = strtod(argv[1], &pp); |
| 35 | errno |= *pp; | ||
| 33 | case 2: | 36 | case 2: |
| 34 | i = atof(*argv); | 37 | first = strtod(argv[0], &pp); |
| 38 | errno |= *pp; | ||
| 35 | case 1: | 39 | case 1: |
| 36 | last = atof(argv[argc-1]); | 40 | last = strtod(argv[argc-1], &pp); |
| 37 | break; | 41 | if (!errno && *pp == '\0') |
| 42 | break; | ||
| 38 | default: | 43 | default: |
| 39 | bb_show_usage(); | 44 | bb_show_usage(); |
| 40 | } | 45 | } |
| 41 | if (opt & OPT_w) /* Pad to length of start or last */ | ||
| 42 | width = MAX(strlen(*argv), strlen(argv[argc-1])); | ||
| 43 | 46 | ||
| 44 | /* You should note that this is pos-5.0.91 semantics, -- FK. */ | 47 | /* Last checked to be compatible with: coreutils-6.10 */ |
| 48 | width = 0; | ||
| 49 | frac_part = 0; | ||
| 50 | while (1) { | ||
| 51 | char *dot = strchrnul(*argv, '.'); | ||
| 52 | int w = (dot - *argv); | ||
| 53 | int f = strlen(dot); | ||
| 54 | if (width < w) | ||
| 55 | width = w; | ||
| 56 | argv++; | ||
| 57 | if (!*argv) | ||
| 58 | break; | ||
| 59 | /* Why do the above _before_ frac check below? | ||
| 60 | * Try "seq 1 2.0" and "seq 1.0 2.0": | ||
| 61 | * coreutils never pay attention to the number | ||
| 62 | * of fractional digits in last arg. */ | ||
| 63 | if (frac_part < f) | ||
| 64 | frac_part = f; | ||
| 65 | } | ||
| 66 | if (frac_part) { | ||
| 67 | frac_part--; | ||
| 68 | if (frac_part) | ||
| 69 | width += frac_part + 1; | ||
| 70 | } | ||
| 71 | if (!(opt & OPT_w)) | ||
| 72 | width = 0; | ||
| 73 | |||
| 45 | sep = ""; | 74 | sep = ""; |
| 46 | while ((increment > 0 && i <= last) || (increment < 0 && i >= last)) { | 75 | v = first; |
| 47 | printf("%s%0*g", sep, width, i); | 76 | n = 0; |
| 77 | while (increment >= 0 ? v <= last : v >= last) { | ||
| 78 | printf("%s%0*.*f", sep, width, frac_part, v); | ||
| 48 | sep = opt_s; | 79 | sep = opt_s; |
| 49 | i += increment; | 80 | /* v += increment; - would accumulate floating point errors */ |
| 81 | n++; | ||
| 82 | v = first + n * increment; | ||
| 50 | } | 83 | } |
| 51 | bb_putchar('\n'); | 84 | if (n) /* if while loop executed at least once */ |
| 85 | bb_putchar('\n'); | ||
| 86 | |||
| 52 | return fflush(stdout); | 87 | return fflush(stdout); |
| 53 | } | 88 | } |
