summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/wcstod.c
diff options
context:
space:
mode:
authortheraven <theraven@FreeBSD.org>2011-11-20 14:45:42 +0000
committertheraven <theraven@FreeBSD.org>2011-11-20 14:45:42 +0000
commit0f6ef690b3118882121ed67561c7ce2660cfebe1 (patch)
tree909189922493cddbeeac84af2e316dc897661311 /lib/libc/locale/wcstod.c
parent18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff (diff)
downloadFreeBSD-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.c37
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());
+}
OpenPOWER on IntegriCloud