factor: support "no-argvs" usage
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 14 Apr 2017 12:23:49 +0000 (14:23 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 14 Apr 2017 12:23:49 +0000 (14:23 +0200)
function                                             old     new   delta
factorize_numstr                                       -      72     +72
packed_usage                                       31562   31566      +4
factor_main                                          109     101      -8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 76/-8)              Total: 68 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
coreutils/factor.c

index 28175343991c0e395c5089869c82646be14ea888..81841477535af8a13db3068a80ecf7a7c54e2273 100644 (file)
@@ -14,7 +14,7 @@
 //kbuild:lib-$(CONFIG_FACTOR) += factor.o
 
 //usage:#define factor_trivial_usage
-//usage:       "NUMBER..."
+//usage:       "[NUMBER]..."
 //usage:#define factor_full_usage "\n\n"
 //usage:       "Print prime factors"
 
@@ -165,6 +165,20 @@ static NOINLINE void factorize(wide_t N)
        bb_putchar('\n');
 }
 
+static void factorize_numstr(const char *numstr)
+{
+       wide_t N;
+
+       /* Leading + is ok (coreutils compat) */
+       if (*numstr == '+')
+               numstr++;
+       N = bb_strtoull(numstr, NULL, 10);
+       if (errno)
+               bb_show_usage();
+       printf("%llu:", N);
+       factorize(N);
+}
+
 int factor_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int factor_main(int argc UNUSED_PARAM, char **argv)
 {
@@ -173,24 +187,32 @@ int factor_main(int argc UNUSED_PARAM, char **argv)
        //argv += optind;
        argv++;
 
-       if (!*argv)
-               //TODO: read from stdin
-               bb_show_usage();
+       if (!*argv) {
+               /* Read from stdin, several numbers per line are accepted */
+               for (;;) {
+                       char *numstr, *line;
+                       line = xmalloc_fgetline(stdin);
+                       if (!line)
+                               return EXIT_SUCCESS;
+                       numstr = line;
+                       for (;;) {
+                               char *end;
+                               numstr = skip_whitespace(numstr);
+                               if (!numstr[0])
+                                       break;
+                               end = skip_non_whitespace(numstr);
+                               if (*end != '\0');
+                                       *end++ = '\0';
+                               factorize_numstr(numstr);
+                               numstr = end;
+                       }
+                       free(line);
+               }
+       }
 
        do {
-               wide_t N;
-               const char *numstr;
-
-               /* Coreutils compat */
-               numstr = skip_whitespace(*argv);
-               if (*numstr == '+')
-                       numstr++;
-
-               N = bb_strtoull(numstr, NULL, 10);
-               if (errno)
-                       bb_show_usage();
-               printf("%llu:", N);
-               factorize(N);
+               /* Leading spaces are ok (coreutils compat) */
+               factorize_numstr(skip_whitespace(*argv));
        } while (*++argv);
 
        return EXIT_SUCCESS;