1/*- 2 * Copyright (c) 2002, 2003 Tim J. Robbins 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); 29 30#include "xlocale_private.h" 31 32#include <stdlib.h> 33#include <wchar.h> 34#include <wctype.h> 35#include <_simple.h> 36 37/* 38 * See wcstod() for comments as to the logic used. 39 */ 40 41extern size_t __wcs_end_offset(const char * __restrict buf, const char * __restrict end, locale_t loc); 42 43long double 44wcstold_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, 45 locale_t loc) 46{ 47 static const mbstate_t initial; 48 mbstate_t mbs; 49 long double val; 50 char *buf, *end; 51 size_t len; 52 locale_t ctype; 53 _SIMPLE_STRING b; 54 char mb[MB_CUR_MAX + 1]; 55 const wchar_t *nptr0 = nptr; 56 const wchar_t *first; 57 58 NORMALIZE_LOCALE(loc); 59 ctype = __numeric_ctype(loc); 60 61 while (iswspace_l(*nptr, ctype)) 62 nptr++; 63 64 if ((b = _simple_salloc()) == NULL) 65 return (0.0); 66 67 first = nptr; 68 mbs = initial; 69 while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { 70 mb[len] = 0; 71 if (_simple_sappend(b, mb) < 0) { /* no memory */ 72 _simple_sfree(b); 73 return (0.0); 74 } 75 nptr++; 76 } 77 78 buf = _simple_string(b); 79 val = strtold_l(buf, &end, loc); 80 81 if (endptr != NULL) 82 *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + __wcs_end_offset(buf, end, loc)); 83 84 _simple_sfree(b); 85 86 return (val); 87} 88 89long double 90wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) 91{ 92 return wcstold_l(nptr, endptr, __current_locale()); 93} 94