X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..HEAD:/locale/FreeBSD/wcstold.c diff --git a/locale/FreeBSD/wcstold.c b/locale/FreeBSD/wcstold.c index b468f9a..45222d8 100644 --- a/locale/FreeBSD/wcstold.c +++ b/locale/FreeBSD/wcstold.c @@ -25,60 +25,69 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.1 2003/03/13 06:29:53 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" #include #include #include +#include <_simple.h> /* * See wcstod() for comments as to the logic used. */ + +extern size_t __wcs_end_offset(const char * __restrict buf, const char * __restrict end, locale_t loc); + long double -wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +wcstold_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + locale_t loc) { static const mbstate_t initial; - mbstate_t state; + mbstate_t mbs; long double val; - char *buf, *end, *p; - const wchar_t *wcp; - size_t clen, len; + char *buf, *end; + size_t len; + locale_t ctype; + _SIMPLE_STRING b; + char mb[MB_CUR_MAX + 1]; + const wchar_t *nptr0 = nptr; + const wchar_t *first; - while (iswspace(*nptr)) + NORMALIZE_LOCALE(loc); + ctype = __numeric_ctype(loc); + + while (iswspace_l(*nptr, ctype)) nptr++; - state = initial; - wcp = nptr; - if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) { - if (endptr != NULL) - *endptr = (wchar_t *)nptr; - return (0.0); - } - if ((buf = malloc(len + 1)) == NULL) + if ((b = _simple_salloc()) == NULL) return (0.0); - state = initial; - wcsrtombs(buf, &wcp, len + 1, &state); - - val = strtold(buf, &end); - if (endptr != NULL) { -#if 1 /* Fast, assume 1:1 WC:MBS mapping. */ - *endptr = (wchar_t *)nptr + (end - buf); - (void)clen; - (void)p; -#else /* Slow, conservative approach. */ - state = initial; - *endptr = (wchar_t *)nptr; - p = buf; - while (p < end && - (clen = mbrlen(p, end - p, &state)) > 0) { - p += clen; - (*endptr)++; + first = nptr; + mbs = initial; + while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { + mb[len] = 0; + if (_simple_sappend(b, mb) < 0) { /* no memory */ + _simple_sfree(b); + return (0.0); } -#endif + nptr++; } - free(buf); + buf = _simple_string(b); + val = strtold_l(buf, &end, loc); + + if (endptr != NULL) + *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + __wcs_end_offset(buf, end, loc)); + + _simple_sfree(b); return (val); } + +long double +wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstold_l(nptr, endptr, __current_locale()); +}