--- trunk/mkinitrd-magellan/busybox/coreutils/seq.c 2010/04/29 20:38:48 983 +++ trunk/mkinitrd-magellan/busybox/coreutils/seq.c 2010/05/30 11:32:42 984 @@ -6,35 +6,94 @@ * * Licensed under the GPL v2, see the file LICENSE in this tarball. */ - #include "libbb.h" /* This is a NOFORK applet. Be very careful! */ - int seq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int seq_main(int argc, char **argv) { - double last, increment, i; - - i = increment = 1; + enum { + OPT_w = (1 << 0), + OPT_s = (1 << 1), + }; + double first, last, increment, v; + unsigned n; + unsigned width; + unsigned frac_part; + const char *sep, *opt_s = "\n"; + unsigned opt; + +#if ENABLE_LOCALE_SUPPORT + /* Undo busybox.c: on input, we want to use dot + * as fractional separator, regardless of current locale */ + setlocale(LC_NUMERIC, "C"); +#endif + + opt = getopt32(argv, "+ws:", &opt_s); + argc -= optind; + argv += optind; + first = increment = 1; + errno = 0; switch (argc) { - case 4: - increment = atof(argv[2]); + char *pp; case 3: - i = atof(argv[1]); + increment = strtod(argv[1], &pp); + errno |= *pp; case 2: - last = atof(argv[argc-1]); - break; + first = strtod(argv[0], &pp); + errno |= *pp; + case 1: + last = strtod(argv[argc-1], &pp); + if (!errno && *pp == '\0') + break; default: bb_show_usage(); } - /* You should note that this is pos-5.0.91 semantics, -- FK. */ - while ((increment > 0 && i <= last) || (increment < 0 && i >= last)) { - printf("%g\n", i); - i += increment; +#if ENABLE_LOCALE_SUPPORT + setlocale(LC_NUMERIC, ""); +#endif + + /* Last checked to be compatible with: coreutils-6.10 */ + width = 0; + frac_part = 0; + while (1) { + char *dot = strchrnul(*argv, '.'); + int w = (dot - *argv); + int f = strlen(dot); + if (width < w) + width = w; + argv++; + if (!*argv) + break; + /* Why do the above _before_ frac check below? + * Try "seq 1 2.0" and "seq 1.0 2.0": + * coreutils never pay attention to the number + * of fractional digits in last arg. */ + if (frac_part < f) + frac_part = f; + } + if (frac_part) { + frac_part--; + if (frac_part) + width += frac_part + 1; + } + if (!(opt & OPT_w)) + width = 0; + + sep = ""; + v = first; + n = 0; + while (increment >= 0 ? v <= last : v >= last) { + printf("%s%0*.*f", sep, width, frac_part, v); + sep = opt_s; + /* v += increment; - would accumulate floating point errors */ + n++; + v = first + n * increment; } + if (n) /* if while loop executed at least once */ + bb_putchar('\n'); - return fflush(stdout); + return fflush_all(); }