Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3-0]: src Pull up following revision(s) (requested by tnozaki in ...



details:   https://anonhg.NetBSD.org/src/rev/2354f4d63396
branches:  netbsd-3-0
changeset: 579210:2354f4d63396
user:      riz <riz%NetBSD.org@localhost>
date:      Fri Apr 28 21:59:57 2006 +0000

description:
Pull up following revision(s) (requested by tnozaki in ticket #1272):
        lib/libc/locale/wcstod.c: revision 1.4-1.8
        regress/lib/libc/locale/wcstod/wcstod_test.c: revision 1.1
        regress/lib/libc/locale/wcstod/Makefile: revision 1.1
replaced by FreeBSD version wcstod(3) for make it work
with L"inf", L"nan", and hex conversion.
suggested by joerg AT netbsd DOT org, thanks.

diffstat:

 lib/libc/locale/wcstod.c                     |  152 ++++-----
 regress/lib/libc/locale/wcstod/Makefile      |   11 +
 regress/lib/libc/locale/wcstod/wcstod_test.c |  412 +++++++++++++++++++++++++++
 3 files changed, 495 insertions(+), 80 deletions(-)

diffs (truncated from 623 to 300 lines):

diff -r 3d464759c4a0 -r 2354f4d63396 lib/libc/locale/wcstod.c
--- a/lib/libc/locale/wcstod.c  Tue Apr 25 23:52:02 2006 +0000
+++ b/lib/libc/locale/wcstod.c  Fri Apr 28 21:59:57 2006 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: wcstod.c,v 1.4 2001/10/28 12:08:43 yamt Exp $ */
+/* $NetBSD: wcstod.c,v 1.4.12.1 2006/04/28 21:59:57 riz Exp $ */
 
 /*-
- * Copyright (c)1999, 2000, 2001 Citrus Project,
+ * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,10 +25,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstod.c,v 1.2 2001/09/27 16:23:57 yamt Exp $
+ * Original version ID:
+ *   FreeBSD: /repoman/r/ncvs/src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp
  */
 
 #include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcstod.c,v 1.4.12.1 2006/04/28 21:59:57 riz Exp $");
+#endif /* LIBC_SCCS and not lint */
+
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -36,97 +41,84 @@
 #include <wchar.h>
 #include <wctype.h>
 
-#define _L(x) __CONCAT(L,x)
-#define _LC(x) __CONCAT(L,x)
-
+/*
+ * Convert a string to a double-precision number.
+ *
+ * This is the wide-character counterpart of strtod(). So that we do not
+ * have to duplicate the code of strtod() here, we convert the supplied
+ * wide character string to multibyte and call strtod() on the result.
+ * This assumes that the multibyte encoding is compatible with ASCII
+ * for at least the digits, radix character and letters.
+ */
 double
-wcstod(const wchar_t *nptr, wchar_t **endptr)
+wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr)
 {
-       const wchar_t *src;
-       size_t size;
-       const wchar_t *start;
-
-       _DIAGASSERT(nptr);
-
-       /*
-        * we do only check length of string
-        * and give it over strtod.
-        */
-       src = nptr;
+       const wchar_t *src, *start;
+       double val;
+       char *buf, *end;
+       size_t bufsiz, len;
 
-       /* skip space first */
-       while (iswspace(*src)) {
-               src++;
-       }
+       _DIAGASSERT(nptr != NULL);
+       /* endptr may be null */
 
-       /* get length of string */
-       start = src;    
-       if (wcschr(_L("+-"), *src))
-               src++;
-       size = wcsspn(src, _L("0123456789"));
-       src += size;
-       if (*src == _LC('.')) {/* XXX use localeconv */
-               src++;
-               size = wcsspn(src, _L("0123456789"));
-               src += size;
-       }
-       if (wcschr(_L("Ee"), *src)) {
-               src++;
-               if (wcschr(_L("+-"), *src))
-                       src++;
-               size = wcsspn(src, _L("0123456789"));
-               src += size;
-       }
-       size = src - start;
+       src = nptr;
+       while (iswspace((wint_t)*src) != 0)
+               ++src;
+       if (*src == L'\0')
+               goto no_convert;
 
        /*
-        * convert to a char-string and pass it to strtod.
+        * Convert the supplied numeric wide char. string to multibyte.
         *
-        * since all chars used to represent a double-constant
-        * are in the portable character set, we can assume
-        * that they are 1-byte chars.
+        * We could attempt to find the end of the numeric portion of the
+        * wide char. string to avoid converting unneeded characters but
+        * choose not to bother; optimising the uncommon case where
+        * the input string contains a lot of text after the number
+        * duplicates a lot of strtod()'s functionality and slows down the
+        * most common cases.
         */
-       if (size)
-       {
-               mbstate_t st;
-               char *buf;
-               char *end;
-               const wchar_t *s;
-               size_t size_converted;
-               double result;
-               
-               buf = malloc(size + 1);
-               if (!buf) {
-                       /* error */
-                       errno = ENOMEM; /* XXX */
-                       return 0;
-               }
-                       
-               s = start;
-               memset(&st, 0, sizeof(st));
-               size_converted = wcsrtombs(buf, &s, size, &st);
-               if (size != size_converted) {
-                       /* XXX should not happen */
-                       free(buf);
-                       errno = EILSEQ;
-                       return 0;
-               }
+       start = src;
+       len = wcstombs(NULL, src, 0);
+       if (len == (size_t)-1)
+               /* errno = EILSEQ */
+               goto no_convert;
+
+       _DIAGASSERT(len > 0);
 
-               buf[size] = 0;
-               result = strtod(buf, &end);
+       bufsiz = len;
+       buf = (void *)malloc(bufsiz + 1);
+       if (buf == NULL)
+               /* errno = ENOMEM */
+               goto no_convert;
 
-               free(buf);
+       len = wcstombs(buf, src, bufsiz + 1);
 
-               if (endptr)
-                       /* LINTED bad interface */
-                       *endptr = (wchar_t*)start + (end - buf);
+       _DIAGASSERT(len == bufsiz);
+       _DIAGASSERT(buf[len] == '\0');
 
-               return result;
+       /* Let strtod() do most of the work for us. */
+       val = strtod(buf, &end);
+       if (buf == end) {
+               free(buf);
+               goto no_convert;
        }
 
-       if (endptr)
-               /* LINTED bad interface */
-               *endptr = (wchar_t*)start;
+       /*
+        * We only know where the number ended in the _multibyte_
+        * representation of the string. If the caller wants to know
+        * where it ended, count multibyte characters to find the
+        * corresponding position in the wide char string.
+        */
+       if (endptr != NULL)
+               /* XXX Assume each wide char is one byte. */
+               *endptr = __UNCONST(start + (size_t)(end - buf));
 
+       free(buf);
+
+       return val;
+
+no_convert:
+       if (endptr != NULL)
+               *endptr = __UNCONST(nptr);
        return 0;
 }
diff -r 3d464759c4a0 -r 2354f4d63396 regress/lib/libc/locale/wcstod/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/regress/lib/libc/locale/wcstod/Makefile   Fri Apr 28 21:59:57 2006 +0000
@@ -0,0 +1,11 @@
+# $NetBSD: Makefile,v 1.1.4.2 2006/04/28 21:59:58 riz Exp $
+
+NOMAN= #defined
+
+PROG=  wcstod_test
+WARNS?=        4
+
+regress: ${PROG}
+       ./${PROG}
+
+.include <bsd.prog.mk>
diff -r 3d464759c4a0 -r 2354f4d63396 regress/lib/libc/locale/wcstod/wcstod_test.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/regress/lib/libc/locale/wcstod/wcstod_test.c      Fri Apr 28 21:59:57 2006 +0000
@@ -0,0 +1,412 @@
+/* $NetBSD: wcstod_test.c,v 1.1.4.2 2006/04/28 21:59:58 riz Exp $ */
+
+/*-
+ * Copyright (c)2005 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+typedef struct {
+       const wchar_t *wcs;
+       size_t exp_len;
+       double exp_val;
+       int exp_errno;
+} unitcase_t;
+
+#define        ALT_HUGE_VAL            -1
+#define        ALT_MINUS_HUGE_VAL      -2
+#define        ALT_NAN                 -3
+
+static const unitcase_t unitcases[] = {
+
+{ L"IN",               0,      0,                      0 },
+{ L"+IN",              0,      0,                      0 },
+{ L"-IN",              0,      0,                      0 },
+{ L"INX",              0,      0,                      0 },
+{ L"+INX",             0,      0,                      0 },
+{ L"-INX",             0,      0,                      0 },
+{ L"INF",              3,      ALT_HUGE_VAL,           0 },
+{ L"+INF",             4,      ALT_HUGE_VAL,           0 },
+{ L"-INF",             4,      ALT_MINUS_HUGE_VAL,     0 },
+{ L"INFX",             3,      ALT_HUGE_VAL,           0 },
+{ L"+INFX",            4,      ALT_HUGE_VAL,           0 },
+{ L"-INFX",            4,      ALT_MINUS_HUGE_VAL,     0 },
+{ L"     IN",          0,      0,                      0 },
+{ L"     +IN",         0,      0,                      0 },
+{ L"     -IN",         0,      0,                      0 },
+{ L"     INX",         0,      0,                      0 },
+{ L"     +INX",                0,      0,                      0 },
+{ L"     -INX",                0,      0,                      0 },
+{ L"+     INF",                0,      0,                      0 },
+{ L"-     INF",                0,      0,                      0 },
+{ L"     INF",         8,      ALT_HUGE_VAL,           0 },
+{ L"     +INF",                9,      ALT_HUGE_VAL,           0 },
+{ L"     -INF",                9,      ALT_MINUS_HUGE_VAL,     0 },
+{ L"     INFX",                8,      ALT_HUGE_VAL,           0 },
+{ L"     +INFX",       9,      ALT_HUGE_VAL,           0 },
+{ L"     -INFX",       9,      ALT_MINUS_HUGE_VAL,     0 },
+{ L"     INFINIT",     8,      ALT_HUGE_VAL,           0 },
+{ L"     +INFINIT",    9,      ALT_HUGE_VAL,           0 },
+{ L"     -INFINIT",    9,      ALT_MINUS_HUGE_VAL,     0 },
+{ L"     INFINITY",    13,     ALT_HUGE_VAL,           0 },
+{ L"     +INFINITY",   14,     ALT_HUGE_VAL,           0 },
+{ L"     -INFINITY",   14,     ALT_MINUS_HUGE_VAL,     0 },
+{ L"     INFINITYX",   13,     ALT_HUGE_VAL,           0 },
+{ L"     +INFINITYX",  14,     ALT_HUGE_VAL,           0 },
+{ L"     -INFINITYX",  14,     ALT_MINUS_HUGE_VAL,     0 },
+
+/* NAN */
+{ L"NA",               0,      0,                      0 },
+{ L"+NA",              0,      0,                      0 },
+{ L"-NA",              0,      0,                      0 },
+{ L"NAX",              0,      0,                      0 },



Home | Main Index | Thread Index | Old Index