From: Paul Eggert Date: Wed, 9 Jul 2025 17:36:04 +0000 (-0700) Subject: factor: speed up converting strings to uuint X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bbca1c106ce5728cfabff04d32055c2122489457;p=thirdparty%2Fcoreutils.git factor: speed up converting strings to uuint * src/factor.c: Do not include c-ctype.h. (strtouuint): Don’t bother generating a number on error; just return a strtol_error value other than LONGINT_OK. Speed up overflow checking. --- diff --git a/src/factor.c b/src/factor.c index 6fe900af31..134c092f84 100644 --- a/src/factor.c +++ b/src/factor.c @@ -84,7 +84,6 @@ #include "system.h" #include "assure.h" -#include "c-ctype.h" #include "full-write.h" #include "quote.h" #include "readtokens.h" @@ -1626,61 +1625,35 @@ mp_factor (mpz_t t) return factors; } -/* Convert to *U the value represnted by S. - Return an error indicator. */ +/* Convert to *U the value represented by S, and return LONGINT_OK. + However, on error simply return a value other than LONGINT_OK. */ static strtol_error strtouuint (uuint *u, char const *s) { - int lo_carry; - mp_limb_t hi = 0, lo = 0; + mp_limb_t hi = 0, lo = *s++ - '0'; - strtol_error err = LONGINT_INVALID; + if (UNLIKELY (9 < lo)) + return LONGINT_INVALID; - /* Initial scan for invalid digits. */ - char const *p = s; - for (;;) - { - unsigned char c = *p++; - if (c == 0) - break; - - if (UNLIKELY (!c_isdigit (c))) - { - err = LONGINT_INVALID; - break; - } - - err = LONGINT_OK; /* we've seen at least one valid digit */ - } - - while (err == LONGINT_OK) + for (; LIKELY (0 <= *s - '0' && *s - '0' <= 9); s++) { - unsigned char c = *s++; - if (c == 0) - break; - - c -= '0'; - if (UNLIKELY (ckd_mul (&hi, hi, 10))) - { - err = LONGINT_OVERFLOW; - break; - } + return LONGINT_OVERFLOW; - lo_carry = (lo >> (W_TYPE_SIZE - 3)) + (lo >> (W_TYPE_SIZE - 1)); + int lo_carry = (lo >> (W_TYPE_SIZE - 3)) + (lo >> (W_TYPE_SIZE - 1)); lo_carry += 10 * lo < 2 * lo; lo = 10 * lo; - lo_carry += ckd_add (&lo, lo, c); + lo_carry += ckd_add (&lo, lo, *s - '0'); if (UNLIKELY (ckd_add (&hi, hi, lo_carry))) - { - err = LONGINT_OVERFLOW; - break; - } + return LONGINT_OVERFLOW; } + if (UNLIKELY (*s)) + return LONGINT_INVALID; + *u = make_uuint (hi, lo); - return err; + return LONGINT_OK; } /* FACTOR_PIPE_BUF is chosen to give good performance,