From 529fe97a4bd5fc067ff549fc3d29c753b7387778 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 4 May 2022 19:34:58 -0500 Subject: [PATCH] Add the two options netbsd has for this command. --- tests/factor.test | 5 +++++ toys/other/factor.c | 38 ++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/factor.test b/tests/factor.test index b556c3a7..90151851 100755 --- a/tests/factor.test +++ b/tests/factor.test @@ -20,3 +20,8 @@ testing "10000000019" "factor 10000000019" \ testing "3 6 from stdin" "factor" "3: 3\n6: 2 3\n" "" "3 6" testing "stdin newline" "factor" "3: 3\n6: 2 3\n" "" "3\n6\n" +testing "-h" "factor -h $(((1<<63)-26))" \ + "9223372036854775782: 2 3^4 17 23 319279 456065899\n" "" "" +testing "-x" "factor -x $(((1<<63)-20))" \ + "7fffffffffffffec: 2 2 3 283 43f2ba978e663\n" "" "" + diff --git a/toys/other/factor.c b/toys/other/factor.c index 47e1267b..4e893a07 100644 --- a/toys/other/factor.c +++ b/toys/other/factor.c @@ -3,8 +3,10 @@ * Copyright 2014 Rob Landley * * See https://man7.org/linux/man-pages/man1/factor.1.html + * + * -h and -x options come from https://man.netbsd.org/factor.6 -USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN)) +USE_FACTOR(NEWTOY(factor, "?hx", TOYFLAG_USR|TOYFLAG_BIN)) config FACTOR bool "factor" @@ -13,17 +15,22 @@ config FACTOR usage: factor NUMBER... Factor integers. + + -h Human readable: show repeated factors as x^n + -x Hexadecimal output */ +#define FOR_factor #include "toys.h" static void factor(char *s) { unsigned long long l, ll, lll; + char *pat1 = FLAG(x) ? " %llx" : " %llu", *pat2 = FLAG(x) ? "^%x" : "^%u"; for (;;) { char *err = s; - int dash = 0; + int dash = 0, ii; while(isspace(*s)) s++; if (*s=='-') dash = *s++; @@ -37,34 +44,25 @@ static void factor(char *s) continue; } - printf("-%llu:"+!dash, l); + if (dash) xputc('-'); + printf(pat1+1, l); + xputc(':'); // Negative numbers have -1 as a factor if (dash) printf(" -1"); - // Nothing below 4 has factors - if (l < 4) { - printf(" %llu\n", l); - continue; - } - - // Special case factors of 2 - while (l && !(l&1)) { - printf(" 2"); - l >>= 1; - } - - // test odd numbers until square is > remainder or integer wrap. - for (ll = 3;; ll += 2) { + // test 2 and odd numbers until square is > remainder or integer wrap. + for (ll = 2;; ll += 1+(ll!=2)) { lll = ll*ll; if (lll>l || lll1) printf(" %llu", l); + if (l>1 || ll==2) printf(pat1, l); break; } - while (!(l%ll)) { - printf(" %llu", ll); + for (ii = 0; !(l%ll); ii++) { + if (!ii || !FLAG(h)) printf(pat1, ll); l /= ll; } + if (ii>1 && FLAG(h)) printf(pat2, ii); } xputc('\n'); } -- 2.39.2