diff options
author | theraven <theraven@FreeBSD.org> | 2011-11-20 14:45:42 +0000 |
---|---|---|
committer | theraven <theraven@FreeBSD.org> | 2011-11-20 14:45:42 +0000 |
commit | 0f6ef690b3118882121ed67561c7ce2660cfebe1 (patch) | |
tree | 909189922493cddbeeac84af2e316dc897661311 /lib/libc/locale/wcstod.c | |
parent | 18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff (diff) | |
download | FreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.zip FreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.tar.gz |
Implement xlocale APIs from Darwin, mainly for use by libc++. This adds a
load of _l suffixed versions of various standard library functions that use
the global locale, making them take an explicit locale parameter. Also
adds support for per-thread locales. This work was funded by the FreeBSD
Foundation.
Please test any code you have that uses the C standard locale functions!
Reviewed by: das (gdtoa changes)
Approved by: dim (mentor)
Diffstat (limited to 'lib/libc/locale/wcstod.c')
-rw-r--r-- | lib/libc/locale/wcstod.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/libc/locale/wcstod.c b/lib/libc/locale/wcstod.c index 68df1ed..8bc46a7 100644 --- a/lib/libc/locale/wcstod.c +++ b/lib/libc/locale/wcstod.c @@ -2,6 +2,11 @@ * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <stdlib.h> #include <wchar.h> #include <wctype.h> +#include "xlocale_private.h" /* * Convert a string to a double-precision number. @@ -41,17 +47,22 @@ __FBSDID("$FreeBSD$"); * for at least the digits, radix character and letters. */ double -wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +wcstod_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + locale_t locale) { static const mbstate_t initial; mbstate_t mbs; double val; char *buf, *end; - const wchar_t *wcp; + const wchar_t *wcp = nptr; size_t len; + size_t spaces = 0; + FIX_LOCALE(locale); - while (iswspace(*nptr)) - nptr++; + while (iswspace_l(*wcp, locale)) { + wcp++; + spaces++; + } /* * Convert the supplied numeric wide char. string to multibyte. @@ -63,9 +74,8 @@ wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) * duplicates a lot of strtod()'s functionality and slows down the * most common cases. */ - wcp = nptr; mbs = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, locale)) == (size_t)-1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); @@ -73,10 +83,10 @@ wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) if ((buf = malloc(len + 1)) == NULL) return (0.0); mbs = initial; - wcsrtombs(buf, &wcp, len + 1, &mbs); + wcsrtombs_l(buf, &wcp, len + 1, &mbs, locale); /* Let strtod() do most of the work for us. */ - val = strtod(buf, &end); + val = strtod_l(buf, &end, locale); /* * We only know where the number ended in the _multibyte_ @@ -84,11 +94,20 @@ wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) * where it ended, count multibyte characters to find the * corresponding position in the wide char string. */ - if (endptr != NULL) + if (endptr != NULL) { /* XXX Assume each wide char is one byte. */ *endptr = (wchar_t *)nptr + (end - buf); + if (buf != end) + *endptr += spaces; + } + free(buf); return (val); } +double +wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstod_l(nptr, endptr, __get_locale()); +} |