Hi, This seems like a textbook case for strtonum(3).
Change in behavior: when the start value is read from stdin, trailing whitespace is now an error instead of being ignored. I can revise the diff to stub out the trailing whitespace before strtonum(3) sees it, though, if that's preferable. Any takers? -- Scott Cheloha Index: games/primes/primes.c =================================================================== RCS file: /cvs/src/games/primes/primes.c,v retrieving revision 1.23 diff -u -p -r1.23 primes.c --- games/primes/primes.c 31 Aug 2016 04:48:43 -0000 1.23 +++ games/primes/primes.c 30 Oct 2017 01:17:06 -0000 @@ -52,7 +52,6 @@ #include <ctype.h> #include <err.h> -#include <errno.h> #include <math.h> #include <stdio.h> #include <stdlib.h> @@ -96,10 +95,10 @@ __dead void usage(void); int main(int argc, char *argv[]) { + const char *errstr; ubig start; /* where to start generating */ ubig stop; /* don't generate at or above this value */ int ch; - char *p; if (pledge("stdio", NULL) == -1) err(1, "pledge"); @@ -117,43 +116,15 @@ main(int argc, char *argv[]) start = 0; stop = BIG; - /* - * Convert low and high args. Strtoul(3) sets errno to - * ERANGE if the number is too large, but, if there's - * a leading minus sign it returns the negation of the - * result of the conversion, which we'd rather disallow. - */ switch (argc) { case 2: - /* Start and stop supplied on the command line. */ - if (argv[0][0] == '-' || argv[1][0] == '-') - errx(1, "negative numbers aren't permitted."); - - errno = 0; - start = strtoul(argv[0], &p, 10); - if (errno) - err(1, "%s", argv[0]); - if (*p != '\0') - errx(1, "%s: illegal numeric format.", argv[0]); - - errno = 0; - stop = strtoul(argv[1], &p, 10); - if (errno) - err(1, "%s", argv[1]); - if (*p != '\0') - errx(1, "%s: illegal numeric format.", argv[1]); - break; - case 1: - /* Start on the command line. */ - if (argv[0][0] == '-') - errx(1, "negative numbers aren't permitted."); - - errno = 0; - start = strtoul(argv[0], &p, 10); - if (errno) - err(1, "%s", argv[0]); - if (*p != '\0') - errx(1, "%s: illegal numeric format.", argv[0]); + stop = strtonum(argv[1], 0, BIG, &errstr); + if (errstr) + errx(1, "stop is %s: %s", errstr, argv[1]); + case 1: /* FALLTHROUGH */ + start = strtonum(argv[0], 0, BIG, &errstr); + if (errstr) + errx(1, "start is %s: %s", errstr, argv[0]); break; case 0: start = read_num_buf(); @@ -175,6 +146,7 @@ main(int argc, char *argv[]) ubig read_num_buf(void) { + const char *errstr; ubig val; char *p, buf[100]; /* > max number of digits. */ @@ -189,16 +161,9 @@ read_num_buf(void) ; if (*p == '\0') continue; - if (*p == '-') - errx(1, "negative numbers aren't permitted."); - errno = 0; - val = strtoul(buf, &p, 10); - if (errno) - err(1, "%s", buf); - for (; isblank((unsigned char)*p); ++p) - ; - if (*p != '\0') - errx(1, "%s: illegal numeric format.", buf); + val = strtonum(buf, 0, BIG, &errstr); + if (errstr) + errx(1, "start is %s: %s", errstr, buf); return (val); } }