tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: strtonum(3) from OpenBSD?



On Tue, Jun 23, 2009 at 05:14:54PM -0400, Matthew Mondor wrote:
 > Two possible draft alternatives are attached to fuel even more
 > debate (yes, seems I had too much time on my hands tonight :)  

Returned value(s) should be the last args, not the first. You're also
forgetting the "base" argument, and in the code, testing errno without
checking for an error return value isn't safe.

However, I'd propose something quite a bit simpler.

Since strto* already violate the standard conventions for errno
handling, ISTM that the best approach for a simplified interface is to
guarantee errno 0 on success. Then you just do

   errno = 0;
   x = strgetl(str, 10);
   if (errno) {
      err(1, "invalid number");
   }

and the interface is simple and tidy. The code is pretty easy too,
assuming I haven't forgotten some further standard quirk:

inline
long
strgetl(const char *str, int base)
{
        long ret;
        char *t;

        errno = 0;
        ret = strtol(str, &t, base);
        if ((ret != LONG_MAX && ret != LONG_MIN) || errno == 0) {
                errno = (*t == '\0') ? 0 : EINVAL;
        }
        return ret;
}

This can also easily be replicated with cpp for all desired integer
types to avoid having to coerce through intmax_t.

If you know that your strto* implementations don't do certain silly
but technically legal things with errno, this can be simplified
further.

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index