Date: Sun, 21 Jul 2019 05:57:49 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: John Baldwin <jhb@freebsd.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r350179 - head/lib/libutil Message-ID: <20190721042856.E2399@besplex.bde.org> In-Reply-To: <201907201603.x6KG3san038622@repo.freebsd.org> References: <201907201603.x6KG3san038622@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 20 Jul 2019, John Baldwin wrote: > Log: > expand_number(3) parses suffixes, not prefixes. This is not quite correct, although conflating prefixes and suffixes is one of the bugs that I pointed out in mails about [de]humanize_number and expand_number() long ago. Bugs in expand_number() start with its name. It doesn't expand numbers. It parses strings and produces integers with a wrong limited type/range (uint64_t instead of uintmax_t plus sign info). I don't know what it means to expand a number, but this is close to the opposite. expand_number() is not nearly as badly designed as humanize_number(). humanize_number() doesn't humanize numbers. It converts integers with a different wrong limited type/range (int64_t instead of uint64_t plus sign info) to a hideous/dehumanized string format. The humanized format would be decimal decimal. humanize_number() produces a scientific format. humanize_number() still documents SI prefixes, and has a suffix arg which gives the units. Its SI prefixes are prefixes to the suffix. E.g., a prefix of "K" and a suffix of "B" gives units of non-disk-marketers kilobytes. It is only when the suffix is null that the prefix becomes a suffix. Most quantities have units, but it is common to omit the units in the string representation to save space. expand_number() doesn't even support units, except it treats the suffix "B" or "b" as a null unit provided it doesn't have a prefix (e.g., "1B" gives 1, byut "1KB" is a syntax error). strtonum() uses the long long abomination instead of the correct type (uintmax_t with sign info). Its name is better, but uses the precious str* namespace for a badly designed API. I would prefer a strtonum() that is more like expand_number() (not too much error handling) but handles any number of suffixes and multipliers like the number-parsing function in dd. This should be almost as easy to use as atoi(), but have some error handling. E.g., uintmax_t strtonum(const char *nptr, const char *errspec, ...); where simple uses use errspec = NULL to get default error handling similar to expand_number(). errspec would need 3 specifiers to specify the last 3 args in the current strtonum(). > Modified: head/lib/libutil/expand_number.3 > ============================================================================== > --- head/lib/libutil/expand_number.3 Sat Jul 20 15:59:49 2019 (r350178) > +++ head/lib/libutil/expand_number.3 Sat Jul 20 16:03:54 2019 (r350179) > @@ -42,11 +42,10 @@ > .Sh DESCRIPTION > The > .Fn expand_number > -function unformats the > +function parses the Better. The supported formats are still undocumented. Not even that they are integers. They may have leading whitespace and signs, or hex and octal prefixes (anything parseable by strtoumax(), with special treatment of a single optional suffix character). > .Fa buf > -string and stores a unsigned 64-bit quantity at address pointed out by the > -.Fa num > -argument. > +string and stores a unsigned 64-bit quantity at > +.Fa *num . "unsigned 64-bit quantity" is a bad way of spelling of "uint64_t". uint64_t's aren't quantities. > .Pp > The > .Fn expand_number > @@ -54,9 +53,9 @@ function > is case-insensitive and > follows the SI power of two convention. There is no SI power of 2 convention according to Wikipedia. humanize_number() and its bugs must be understood to see what this means. Google gives approximately zero hits for "SI suffix". It automatically translates "SI suffix" to "SI prefix" and of course finds zillions of hits for that. humanize_number(3) says that it "follows the traditional computer science conventions by default, rather than the IEE/IEC (and now also SI) power of two convention...", but according to Wikipedia, IEC 60027-2 Amendment 2 confirms that SI only supports power of 10 prefixes. According to Wikipedia, the power of 2 convention is IEC for kibi through yobi, and JEDEC has the better traditional prefixes and names for K/kilo though G/Giga. k is documented to mean 1000 and K 1024 for humanize_number(), but expand_number() treats both as 1024. The other prefixes can't be disambiguated like this. > .Pp > -The prefixes are: > -.Bl -column "Prefix" "Description" "1000000000000000000" -offset indent > -.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" > +The suffixes are: > +.Bl -column "Suffix" "Description" "1000000000000000000" -offset indent > +.It Sy "Suffix" Ta Sy "Description" Ta Sy "Multiplier" > .It Li K Ta No kilo Ta 1024 > .It Li M Ta No mega Ta 1048576 > .It Li G Ta No giga Ta 1073741824 > @@ -74,7 +73,7 @@ function will fail if: > .It Bq Er EINVAL > The given string contains no digits. > .It Bq Er EINVAL > -An unrecognized prefix was given. > +An unrecognized suffix was given. > .It Bq Er ERANGE > Result doesn't fit into 64 bits. > .El Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20190721042856.E2399>