Date: Mon, 28 Jan 2002 10:29:13 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: Chad David <davidc@acns.ab.ca> Cc: "Andrey A. Chernov" <ache@nagual.pp.ru>, "Brian F. Feldman" <green@FreeBSD.ORG>, <arch@FreeBSD.ORG> Subject: Re: strtod() Message-ID: <20020128100000.T39789-100000@gamplex.bde.org> In-Reply-To: <20020127024626.B40668@colnta.acns.ab.ca>
index | next in thread | previous in thread | raw e-mail
On Sun, 27 Jan 2002, Chad David wrote:
> On Sun, Jan 27, 2002 at 11:35:30AM +0300, Andrey A. Chernov wrote:
> > It looks like it is not localeconv() problem, but incorrect locale
> > problem.
>
> Maybe, I don't really know much about the locale code, but it seems the
> default C monetary locale is all nulls.
It always calls cnv() on the string "\0177" here. This is the default
for the C locale. From lmonetary.c:
static char empty[] = "";
static char numempty[] = { CHAR_MAX, '\0'};
% static const struct lc_monetary_T _C_monetary_locale = {
% empty, /* int_curr_symbol */
% empty, /* currency_symbol */
% empty, /* mon_decimal_point */
% empty, /* mon_thousands_sep */
% numempty, /* mon_grouping */
% empty, /* positive_sign */
% empty, /* negative_sign */
% numempty, /* int_frac_digits */
% numempty, /* frac_digits */
% numempty, /* p_cs_precedes */
% numempty, /* p_sep_by_space */
% numempty, /* n_cs_precedes */
% numempty, /* n_sep_by_space */
% numempty, /* p_sign_posn */
% numempty /* n_sign_posn */
% };
> > > The attached patch fixes this case, and probably others. Comments?
> >
> > Don't do that, fix locale instead. cnv() expected to be called on valid
> > numeric fields only.
"\0177" isn't very valid :-).
> How would you fix it? I'm not sure errno should get modified just because
> a locale has an invalid entry? Do you fix the locale (if so how??), or do
> you make the code a little more robust?
% Index: localeconv.c
% ===================================================================
% RCS file: /mnt1/ncvs/src/lib/libc/locale/localeconv.c,v
% retrieving revision 1.3
% diff -u -d -r1.3 localeconv.c
% --- localeconv.c 10 Feb 2001 02:00:56 -0000 1.3
% +++ localeconv.c 27 Jan 2002 07:28:51 -0000
% @@ -49,9 +49,16 @@
% int __mlocale_changed = 1;
% int __nlocale_changed = 1;
%
% +extern int errno; /* required in cnv() */
% +
% static char
% cnv(char *str) {
% - return (char)strtol(str, NULL, 0);
% + int save_errno = errno;
% + char ret;
% +
% + ret = (char)strtol(str, NULL, 0);
% + errno = save_errno;
% + return (ret);
% }
%
% /*
This seems reasonable, except:
(1) it breaks the threaded case (errno might not be "extern int")
(2) it breaks the style rule about inintializing variables in declarations
(I might agree with "const int save_errno = errno").
(3) it makes the broken error handling more obvious (cnv() doesn't check
for errors from strtol(), and it truncates the value to a char without
checking for overflow). Perhaps errors "can't happen", but they just
happened.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020128100000.T39789-100000>
