1112758Ssam/*- 2112758Ssam * Copyright (c) 2002, 2003 Tim J. Robbins 3112758Ssam * All rights reserved. 4112758Ssam * 5112758Ssam * Copyright (c) 2011 The FreeBSD Foundation 6112758Ssam * All rights reserved. 7112758Ssam * Portions of this software were developed by David Chisnall 8112758Ssam * under sponsorship from the FreeBSD Foundation. 9112758Ssam * 10112758Ssam * Redistribution and use in source and binary forms, with or without 11112758Ssam * modification, are permitted provided that the following conditions 12112758Ssam * are met: 13112758Ssam * 1. Redistributions of source code must retain the above copyright 14112758Ssam * notice, this list of conditions and the following disclaimer. 15112758Ssam * 2. Redistributions in binary form must reproduce the above copyright 16112758Ssam * notice, this list of conditions and the following disclaimer in the 17112758Ssam * documentation and/or other materials provided with the distribution. 18112758Ssam * 19112758Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20112758Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21112758Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22112758Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23112758Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24112758Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25112758Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26112758Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27112758Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28105197Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29105197Ssam * SUCH DAMAGE. 30105197Ssam */ 31105197Ssam 32105197Ssam#include <sys/cdefs.h> 33105197Ssam__FBSDID("$FreeBSD$"); 34105197Ssam 35159965Sthompsa#include <stdlib.h> 36105197Ssam#include <wchar.h> 37105197Ssam#include <wctype.h> 38105197Ssam#include "xlocale_private.h" 39105197Ssam 40105197Ssam/* 41105197Ssam * See wcstod() for comments as to the logic used. 42105197Ssam */ 43105197Ssamlong double 44105197Ssamwcstold_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, 45105197Ssam locale_t locale) 46105197Ssam{ 47171497Sbz static const mbstate_t initial; 48195699Srwatson mbstate_t mbs; 49105197Ssam long double val; 50105197Ssam char *buf, *end; 51105197Ssam const wchar_t *wcp = nptr; 52105197Ssam size_t len; 53105197Ssam size_t spaces = 0; 54105197Ssam FIX_LOCALE(locale); 55105197Ssam 56105197Ssam while (iswspace_l(*wcp, locale)) { 57105197Ssam wcp++; 58105197Ssam spaces++; 59105197Ssam } 60105197Ssam 61105197Ssam wcp = nptr; 62105197Ssam mbs = initial; 63105197Ssam if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, locale)) == (size_t)-1) { 64105197Ssam if (endptr != NULL) 65105197Ssam *endptr = (wchar_t *)nptr; 66105197Ssam return (0.0); 67105197Ssam } 68105197Ssam if ((buf = malloc(len + 1)) == NULL) 69105197Ssam return (0.0); 70105197Ssam mbs = initial; 71105197Ssam wcsrtombs_l(buf, &wcp, len + 1, &mbs, locale); 72105197Ssam 73105197Ssam val = strtold_l(buf, &end, locale); 74105197Ssam 75105197Ssam if (endptr != NULL) { 76105197Ssam /* XXX Assume each wide char is one byte. */ 77105197Ssam *endptr = (wchar_t *)nptr + (end - buf); 78105197Ssam if (buf != end) 79105197Ssam *endptr += spaces; 80105197Ssam } 81105197Ssam 82105197Ssam free(buf); 83105197Ssam 84105197Ssam return (val); 85194062Svanhu} 86194062Svanhulong double 87194062Svanhuwcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) 88194062Svanhu{ 89181627Svanhu return wcstold_l(nptr, endptr, __get_locale()); 90181627Svanhu} 91181627Svanhu