Re: alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD
Alejandro Colomar <[email protected]> Thu, 20 Mar 2025 02:15:51 +0100
| Newsgroups | gmane.os.netbsd.devel.general |
|---|---|
| Message-ID | <hgqg7m4leyaam3rmeidg7zl26vvnpe4braqgcbj27ggbtuif7s@q67pd2w3yw6b> |
--wajlvynyceu6b5rr Content-Type: text/plain; protected-headers=v1; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable From: Alejandro Colomar <[email protected]> To: Paul Eggert <[email protected]> Cc: Bruno Haible <[email protected]>, [email protected], [email protected], [email protected], [email protected], christos <[email protected]>, =?utf-8?B?xJBvw6BuIFRy4bqnbiBDw7RuZw==?= Danh <[email protected]>, Eli Schwartz <[email protected]>, Guillem Jover <[email protected]>, Iker Pedrosa <[email protected]>, Michael Vetter <[email protected]>, Robert Elz <[email protected]>, [email protected], Sam James <[email protected]>, "Serge E. Hallyn" <[email protected]> Subject: Re: alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD References: <mgcfwxfmv3kpfnkkf6uj63kx5tdzl64p2zg2us4ntsu6q5xkwj@k52z5yyiywoo> <18739733.sWSEgdgrri@nimes> <mvwnrmk2xf45ivyk4kzxdxuwdk67666yt3kwafck6vo4vq2lru@wkqmoqsacqkf> <3237498.fEcJ0Lxnt5@nimes> <[email protected]> <azfxoxklec7hlxll52ocmjiooq7bahy7xgrplbzmfbdygbubxc@upuk7c6bckto> <[email protected]> <2bk4qlhebhsgby4dda4fshocgoyixmqwqlnlgwcyzywkhpbeum@yr5ko5sv6ezy> <[email protected]> MIME-Version: 1.0 In-Reply-To: <[email protected]> Hi Paul, On Wed, Mar 19, 2025 at 05:39:33PM -0700, Paul Eggert wrote: > On 3/19/25 14:23, Alejandro Colomar wrote: >=20 > > I think not reporting errors or warnings on saturation needs > > justification. >=20 > I don't know what "justification" means, but if it means a comment in the > code I'm not sure I agree. Code where saturation is ordinarily what's wan= ted > shouldn't need a comment on each nontrivial line saying "Saturation is OK > here." Nah, not a source-code comment. I think comments are usually evil. More like you telling me now why you do it that way. Actually, Bruno send detailed responses in his last email, and I think that you'd benefit from range checks, actually. (See my response to his email.) <https://lore.kernel.org/liba2i/6oyljvsenypqnrmgjbcwskqpdsag677h2dzay6hvfoo= sju4224@3j7iczm4d7nw/T/#m38066e6eec63a8906e3cbfea275c9d7940d8df98> > > Thanks, those changes look good. BTW, what do you think of using > > strspn(3) to simplify the c_isspace loop? >=20 > Not worth the trouble. The loop is easier to read and debug than the strs= pn > call, I guess I got used to the niceties of strspn(3) that I find it easier to read. It's a matter of taste, so ok. :) > which got some minor details wrong and fixing that would complicate > the strspn code even further. Do you mean that the implementation of strspn(3) was temporarily broken? Or that the specification is bad? I'm curious about it; could you please clarify? > > However, would you mind clarifying why you don't diagnose huge values in > > the two places that you have updated? >=20 > For this particular resource, a limit of ULONG_MAX has the same practical > effect as a limit of ULONG_MAX + 1. Since the user can't tell the differe= nce > in behavior, it's fine to implement the larger limit as the smaller one, > with no diagnostic. According to Bruno, that limit is later clamped at a much lower value, so I think that clamping could be moved up to the strtou(3) call. Of course, that would mean having to implement strtou(3) for now, since it's non-standard, so keeping it as is is simpler. I was just trying to say that if strtou(3) was standard in libc, then you could just use it and simplify code, while making it more robust. > A reasonable amount of GNU code works that way. Ok. > > struct foo { > > long val; > > int err; > > } > >=20 > > struct foo ret; > >=20 > > ret =3D f(time_t, ...); > > if (ret.err !=3D 0) > > err(1, "f"); > >=20 > > How do I know which variant of struct foo I need? >=20 > I don't understand the question. There's no variant here; "variant" to me > implies something like a union. >=20 > But to fill in the details: C doesn't have a convenient notation for > returning multiple values, you do need a struct. One convention is to use= a > struct whose tag is the same as the function. So, something like this in a > header file somewhere: >=20 > struct a2i { intmax_t val; ptrdiff_t len; } > a2i (char const *str, int base); How do you get a uintmax_t? Let's say I'm parsing an unsigned variable. Also, how do I perform range checks in that call? I need to specify min and max limits. > where LEN is negative for errors, and callers look like this: How do you know how much has been parsed on error? That's something useful from strtoi/u(3). > struct a2i r =3D a2i(stringval, 10); > if (r.len < 0 || stringval[r.len]) > err("a2i", stringval, r.len); >=20 > the "|| stringval[r.len]" is needed only for callers that consider > nonnumeric suffixes to be an error. How do you perform range checks with this API? > This is simpler than the pointers and "restrict"s in the proposed API. Compare to QChar *alt_2(typename T, T *restrict n, QChar *s, int base, T min, T max); which can be called time_t t; char *end; errno =3D 0; end =3D alt_2(time_t, &t, s, 0, past, future); if (errno =3D=3D ERANGE && t =3D=3D past) goto too_old; if (errno =3D=3D ERANGE && t =3D=3D future) goto too_new; if (errno =3D=3D ENOTSUP) goto trailing_test; if (errno !=3D 0) goto hard_error; // All's good here. Can use 't'. ... return; trailing_text: printf("Trailing text: %s", end); which gives me for free checks that t is between past and future, and of course saturation. It also gives me for free type validation that t is of type time_t. It calls strtoi(3) if time_t is a signed type, and strtou(3) if time_t is an unsigned type. I can perform all the checks to errno that I want, or I can omit them if I want. This is the API I'm working on at the moment, and I don't think a struct has anything more compelling than that. Have a lovely night! Alex --=20 <https://www.alejandro-colomar.es/> --wajlvynyceu6b5rr Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmfbbEEACgkQ64mZXMKQ wqmwGg//Vj/SoNquvQ/kqgz+BUgGqrDZ2lVIh3ubfrdtee1aU1AwXqZ/So3CsggZ ExHlIm96oJHYiQpz9Z+4CWOxEFVEtiNG2BLtOZpjV2uYqmE3a9e9G7zSVvmtZ1j0 Jkv6t1DYQrpyn5K1Ark//Yp25+J435dbiy6VvNVh0JzRrEucTG4QHreZVjCVB9ah 0F0hCCfsfMFF2aLoUQ5s7vDiNEJywGSEYXJNkFRyorOocvHnIAGTngss4sfIYhyE tkYqS7DDnl6IA4xVn2UDuSMx7ItaOob5Hz3LMH6THQ1FE2e6IBdO9FQZIYWN/LWr dYp30RwByKtpDIAl8jogrmYXnjbsrQ4yq8wfxwdu4UtVykcTM9GoP1Flade9ozqX ygt5hHds6sVrWVyJ8Mgo5d2NuhgwB+v/1obPhEj6nBP072q5SKBvK6ctH9AMtW0B WFXIudYxmUs0tbeBFcLzCoR8mCPBFjmZNSGkkzAHxYCxHLEmfWXXa0MQUYkO++yF Ek9Oc8UQ5o3sH/8jBsjunNO4EveosZZQx3Xouyv0q5QRO3T6wxQgyqoj0m0NKT5m RhlchZO6QBhOAiGvd9M75g0SGx3IXWKJKdnlfOI4mkZI8GWU1T8wNaDFTnpQTrGV djvo9fdSnKDT5U8G2MBYHJ9bJcnmXDbNL9CnWmjAMvQJHVagpi0= =dK0k -----END PGP SIGNATURE----- --wajlvynyceu6b5rr--