1 1.4 joerg /* $NetBSD: _wcstod.h,v 1.4 2013/05/17 12:55:57 joerg Exp $ */ 2 1.1 tnozaki 3 1.1 tnozaki /*- 4 1.1 tnozaki * Copyright (c) 2002 Tim J. Robbins 5 1.1 tnozaki * All rights reserved. 6 1.1 tnozaki * 7 1.1 tnozaki * Redistribution and use in source and binary forms, with or without 8 1.1 tnozaki * modification, are permitted provided that the following conditions 9 1.3 joerg * aINre met: 10 1.1 tnozaki * 1. Redistributions of source code must retain the above copyright 11 1.1 tnozaki * notice, this list of conditions and the following disclaimer. 12 1.1 tnozaki * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 tnozaki * notice, this list of conditions and the following disclaimer in the 14 1.1 tnozaki * documentation and/or other materials provided with the distribution. 15 1.1 tnozaki * 16 1.1 tnozaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 tnozaki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 tnozaki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 tnozaki * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 tnozaki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 tnozaki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 tnozaki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 tnozaki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 tnozaki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 tnozaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 tnozaki * SUCH DAMAGE. 27 1.1 tnozaki * 28 1.1 tnozaki * Original version ID: 29 1.1 tnozaki * FreeBSD: /repoman/r/ncvs/src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp 30 1.1 tnozaki * NetBSD: wcstod.c,v 1.8 2006/04/13 01:25:13 tnozaki Exp 31 1.1 tnozaki */ 32 1.1 tnozaki 33 1.1 tnozaki /* 34 1.1 tnozaki * function template for wcstof, wcstod, wcstold. 35 1.1 tnozaki * 36 1.1 tnozaki * parameters: 37 1.1 tnozaki * _FUNCNAME : function name 38 1.1 tnozaki * _RETURN_TYPE : return type 39 1.1 tnozaki * _STRTOD_FUNC : real conversion function 40 1.1 tnozaki */ 41 1.1 tnozaki #ifndef __WCSTOD_H_ 42 1.1 tnozaki #define __WCSTOD_H_ 43 1.1 tnozaki 44 1.3 joerg #include <locale.h> 45 1.3 joerg #include "setlocale_local.h" 46 1.3 joerg #define INT_NAME_(pre, middle, post) pre ## middle ## post 47 1.3 joerg #define INT_NAME(pre, middle, post) INT_NAME_(pre, middle, post) 48 1.3 joerg 49 1.1 tnozaki /* 50 1.1 tnozaki * Convert a string to a double-precision number. 51 1.1 tnozaki * 52 1.1 tnozaki * This is the wide-character counterpart of strto{f,d,ld}(). So that 53 1.1 tnozaki * we do not have to duplicate the code of strto{f,d,ld}() here, 54 1.2 wiz * we convert the supplied wide-character string to multibyte and 55 1.1 tnozaki * call strto{f,d,ld}() on the result. 56 1.1 tnozaki * This assumes that the multibyte encoding is compatible with ASCII 57 1.1 tnozaki * for at least the digits, radix character and letters. 58 1.1 tnozaki */ 59 1.3 joerg static _RETURN_TYPE 60 1.3 joerg INT_NAME(_int_, _FUNCNAME, _l)(const wchar_t * __restrict nptr, 61 1.3 joerg wchar_t ** __restrict endptr, locale_t loc) 62 1.1 tnozaki { 63 1.1 tnozaki const wchar_t *src, *start; 64 1.1 tnozaki _RETURN_TYPE val; 65 1.1 tnozaki char *buf, *end; 66 1.1 tnozaki size_t bufsiz, len; 67 1.1 tnozaki 68 1.1 tnozaki _DIAGASSERT(nptr != NULL); 69 1.1 tnozaki /* endptr may be null */ 70 1.1 tnozaki 71 1.1 tnozaki src = nptr; 72 1.3 joerg while (iswspace_l((wint_t)*src, loc) != 0) 73 1.1 tnozaki ++src; 74 1.1 tnozaki if (*src == L'\0') 75 1.1 tnozaki goto no_convert; 76 1.1 tnozaki 77 1.1 tnozaki /* 78 1.2 wiz * Convert the supplied numeric wide-char. string to multibyte. 79 1.1 tnozaki * 80 1.1 tnozaki * We could attempt to find the end of the numeric portion of the 81 1.2 wiz * wide-char. string to avoid converting unneeded characters but 82 1.1 tnozaki * choose not to bother; optimising the uncommon case where 83 1.1 tnozaki * the input string contains a lot of text after the number 84 1.1 tnozaki * duplicates a lot of strto{f,d,ld}()'s functionality and 85 1.1 tnozaki * slows down the most common cases. 86 1.1 tnozaki */ 87 1.1 tnozaki start = src; 88 1.3 joerg len = wcstombs_l(NULL, src, 0, loc); 89 1.1 tnozaki if (len == (size_t)-1) 90 1.1 tnozaki /* errno = EILSEQ */ 91 1.1 tnozaki goto no_convert; 92 1.1 tnozaki 93 1.1 tnozaki _DIAGASSERT(len > 0); 94 1.1 tnozaki 95 1.1 tnozaki bufsiz = len; 96 1.1 tnozaki buf = (void *)malloc(bufsiz + 1); 97 1.1 tnozaki if (buf == NULL) 98 1.1 tnozaki /* errno = ENOMEM */ 99 1.1 tnozaki goto no_convert; 100 1.1 tnozaki 101 1.3 joerg len = wcstombs_l(buf, src, bufsiz + 1, loc); 102 1.1 tnozaki 103 1.1 tnozaki _DIAGASSERT(len == bufsiz); 104 1.1 tnozaki _DIAGASSERT(buf[len] == '\0'); 105 1.1 tnozaki 106 1.1 tnozaki /* Let strto{f,d,ld}() do most of the work for us. */ 107 1.3 joerg val = _STRTOD_FUNC(buf, &end, loc); 108 1.1 tnozaki if (buf == end) { 109 1.1 tnozaki free(buf); 110 1.1 tnozaki goto no_convert; 111 1.1 tnozaki } 112 1.1 tnozaki 113 1.1 tnozaki /* 114 1.1 tnozaki * We only know where the number ended in the _multibyte_ 115 1.1 tnozaki * representation of the string. If the caller wants to know 116 1.1 tnozaki * where it ended, count multibyte characters to find the 117 1.2 wiz * corresponding position in the wide-char string. 118 1.1 tnozaki */ 119 1.1 tnozaki if (endptr != NULL) 120 1.1 tnozaki /* XXX Assume each wide char is one byte. */ 121 1.1 tnozaki *endptr = __UNCONST(start + (size_t)(end - buf)); 122 1.1 tnozaki 123 1.1 tnozaki free(buf); 124 1.1 tnozaki 125 1.1 tnozaki return val; 126 1.1 tnozaki 127 1.1 tnozaki no_convert: 128 1.1 tnozaki if (endptr != NULL) 129 1.1 tnozaki *endptr = __UNCONST(nptr); 130 1.1 tnozaki return 0; 131 1.1 tnozaki } 132 1.3 joerg 133 1.3 joerg _RETURN_TYPE 134 1.3 joerg INT_NAME(, _FUNCNAME, )(const wchar_t * __restrict nptr, 135 1.3 joerg wchar_t ** __restrict endptr) 136 1.3 joerg { 137 1.4 joerg return INT_NAME(_int_, _FUNCNAME, _l)(nptr, endptr, _current_locale()); 138 1.3 joerg } 139 1.3 joerg 140 1.3 joerg _RETURN_TYPE 141 1.3 joerg INT_NAME(, _FUNCNAME, _l)(const wchar_t * __restrict nptr, 142 1.3 joerg wchar_t ** __restrict endptr, locale_t loc) 143 1.3 joerg { 144 1.3 joerg return INT_NAME(_int_, _FUNCNAME, _l)(nptr, endptr, loc); 145 1.3 joerg } 146 1.1 tnozaki #endif /*__WCSTOD_H_*/ 147