From owner-freebsd-arch Sun Jan 27 15:27:41 2002 Delivered-To: freebsd-arch@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 591C337B400; Sun, 27 Jan 2002 15:27:36 -0800 (PST) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id KAA29584; Mon, 28 Jan 2002 10:27:19 +1100 Date: Mon, 28 Jan 2002 10:29:13 +1100 (EST) From: Bruce Evans X-X-Sender: To: Chad David Cc: "Andrey A. Chernov" , "Brian F. Feldman" , Subject: Re: strtod() In-Reply-To: <20020127024626.B40668@colnta.acns.ab.ca> Message-ID: <20020128100000.T39789-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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