Which of these is more likely to have bugs?
int i;
if (PARSENUM(&i, s, 0, 1000))
err("Invalid input: %s", s);
or int i;
long l; // need a temporary long to avoid overflow
char * ep;
errno = 0;
l = strtol(s, &ep, 0);
if ((ep == s) || (*ep = '\0')) // make sure we parsed a number and don't have trailing garbage
errno = EINVAL;
if ((l < 0) || (l > 1000))
errno = ERANGE;
if (errno)
err("Invalid input: %s", s);
i = l;
You build these esoteric systems that use heaps of unmaintainable, unreadable codeNot at all. The point is to have self-contained routines which Just Work in order to ensure that the rest of the code is easier to read and maintain.