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
FUNCNAME(const wchar_t * nptr,wchar_t ** endptr)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