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>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020128100000.T39789-100000>