bc: convert to "G trick" - this returns bc to zero bss increase
[oweals/busybox.git] / coreutils / seq.c
index bb39a5b54ad3a52a7e8804a651cabac30aa615fb..c26ff06b9a575f1e1d1dedf0d5aa9acee36482b7 100644 (file)
@@ -4,11 +4,30 @@
  *
  * Copyright (C) 2004, Glenn McGrath
  *
- * Licensed under the GPL v2, see the file LICENSE in this tarball.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
+//config:config SEQ
+//config:      bool "seq (3.6 kb)"
+//config:      default y
+//config:      help
+//config:      print a sequence of numbers
+
+//applet:IF_SEQ(APPLET_NOEXEC(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq))
+/* was NOFORK, but then "seq 1 999999999" can't be ^C'ed if run by hush */
+
+//kbuild:lib-$(CONFIG_SEQ) += seq.o
+
+//usage:#define seq_trivial_usage
+//usage:       "[-w] [-s SEP] [FIRST [INC]] LAST"
+//usage:#define seq_full_usage "\n\n"
+//usage:       "Print numbers from FIRST to LAST, in steps of INC.\n"
+//usage:       "FIRST, INC default to 1.\n"
+//usage:     "\n       -w      Pad to last with leading zeros"
+//usage:     "\n       -s SEP  String separator"
+
 #include "libbb.h"
 
-/* This is a NOFORK applet. Be very careful! */
+/* This is a NOEXEC applet. Be very careful! */
 
 int seq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int seq_main(int argc, char **argv)
@@ -22,8 +41,15 @@ int seq_main(int argc, char **argv)
        unsigned width;
        unsigned frac_part;
        const char *sep, *opt_s = "\n";
-       unsigned opt = getopt32(argv, "+ws:", &opt_s);
+       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;
@@ -44,6 +70,10 @@ int seq_main(int argc, char **argv)
                        bb_show_usage();
        }
 
+#if ENABLE_LOCALE_SUPPORT
+       setlocale(LC_NUMERIC, "");
+#endif
+
        /* Last checked to be compatible with: coreutils-6.10 */
        width = 0;
        frac_part = 0;
@@ -75,7 +105,8 @@ int seq_main(int argc, char **argv)
        v = first;
        n = 0;
        while (increment >= 0 ? v <= last : v >= last) {
-               printf("%s%0*.*f", sep, width, frac_part, v);
+               if (printf("%s%0*.*f", sep, width, frac_part, v) < 0)
+                       break; /* I/O error, bail out (yes, this really happens) */
                sep = opt_s;
                /* v += increment; - would accumulate floating point errors */
                n++;
@@ -84,5 +115,5 @@ int seq_main(int argc, char **argv)
        if (n) /* if while loop executed at least once */
                bb_putchar('\n');
 
-       return fflush(stdout);
+       return fflush_all();
 }