1 /* $OpenBSD: _wcstod.h,v 1.4 2015/10/01 02:32:07 guenther Exp $ */ 2 /* $NetBSD: wcstod.c,v 1.4 2001/10/28 12:08:43 yamt Exp $ */ 3 4 /*- 5 * Copyright (c)1999, 2000, 2001 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstod.c,v 1.2 2001/09/27 16:23:57 yamt Exp $ 30 */ 31 32 /* 33 * function template for wcstof, wcstod and wcstold. 34 * 35 * parameters: 36 * FUNCNAME : function name 37 * float_type : return type 38 * STRTOD_FUNC : conversion function 39 */ 40 41 float_type 42 FUNCNAME(const wchar_t *nptr, wchar_t **endptr) 43 { 44 const wchar_t *src; 45 size_t size; 46 const wchar_t *start; 47 const wchar_t *aftersign; 48 49 /* 50 * check length of string and call strtod 51 */ 52 src = nptr; 53 54 /* skip space first */ 55 while (iswspace(*src)) { 56 src++; 57 } 58 59 /* get length of string */ 60 start = src; 61 if (*src && wcschr(L"+-", *src)) 62 src++; 63 aftersign = src; 64 if (wcsncasecmp(src, L"inf", 3) == 0) { 65 src += 3; 66 if (wcsncasecmp(src, L"inity", 5) == 0) 67 src += 5; 68 goto match; 69 } 70 if (wcsncasecmp(src, L"nan", 3) == 0) { 71 src += 3; 72 if (*src == L'(') { 73 size = 1; 74 while (src[size] != L'\0' && src[size] != L')') 75 size++; 76 if (src[size] == L')') 77 src += size + 1; 78 } 79 goto match; 80 } 81 size = wcsspn(src, L"0123456789"); 82 src += size; 83 if (*src == L'.') {/* XXX use localeconv */ 84 src++; 85 size = wcsspn(src, L"0123456789"); 86 src += size; 87 } 88 if (*src && wcschr(L"Ee", *src)) { 89 src++; 90 if (*src && wcschr(L"+-", *src)) 91 src++; 92 size = wcsspn(src, L"0123456789"); 93 src += size; 94 } 95 match: 96 size = src - start; 97 98 /* 99 * convert to a char-string and pass it to strtod. 100 */ 101 if (src > aftersign) { 102 mbstate_t st; 103 char *buf; 104 char *end; 105 const wchar_t *s; 106 size_t size_converted; 107 float_type result; 108 size_t bufsize; 109 110 s = start; 111 memset(&st, 0, sizeof(st)); 112 bufsize = wcsnrtombs(NULL, &s, size, 0, &st); 113 114 buf = malloc(bufsize + 1); 115 if (!buf) { 116 errno = ENOMEM; /* XXX */ 117 goto fail; 118 } 119 120 s = start; 121 memset(&st, 0, sizeof(st)); 122 size_converted = wcsnrtombs(buf, &s, size, bufsize, &st); 123 if (size_converted != bufsize) { 124 /* XXX should not happen */ 125 free(buf); 126 errno = EILSEQ; 127 goto fail; 128 } 129 130 buf[bufsize] = 0; 131 result = STRTOD_FUNC(buf, &end); 132 133 if (endptr) { 134 const char *s = buf; 135 memset(&st, 0, sizeof(st)); 136 size = mbsnrtowcs(NULL, &s, end - buf, 0, &st); 137 *endptr = (wchar_t*)start + size; 138 } 139 140 free(buf); 141 142 return result; 143 } 144 145 fail: 146 if (endptr) 147 *endptr = (wchar_t*)nptr; 148 149 return 0; 150 } 151 DEF_STRONG(FUNCNAME); 152