Skip site navigation (1)Skip section navigation (2)
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>