Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6607 serge 1
/*
2
FUNCTION
3
        <>, <>---wide char string to double or float
4
 
5
INDEX
6
	wcstod
7
INDEX
8
	_wcstod_r
9
INDEX
10
	wcstof
11
INDEX
12
	_wcstof_r
13
 
14
ANSI_SYNOPSIS
15
        #include 
16
        double wcstod(const wchar_t *__restrict <[str]>,
17
            wchar_t **__restrict <[tail]>);
18
        float wcstof(const wchar_t *__restrict <[str]>,
19
            wchar_t **__restrict <[tail]>);
20
 
21
        double _wcstod_r(void *<[reent]>,
22
                         const wchar_t *<[str]>, wchar_t **<[tail]>);
23
        float _wcstof_r(void *<[reent]>,
24
                         const wchar_t *<[str]>, wchar_t **<[tail]>);
25
 
26
TRAD_SYNOPSIS
27
        #include 
28
        double wcstod(<[str]>,<[tail]>)
29
        wchar_t *__restrict <[str]>;
30
        wchar_t **__restrict <[tail]>;
31
 
32
        float wcstof(<[str]>,<[tail]>)
33
        wchar_t *__restrict <[str]>;
34
        wchar_t **__restrict <[tail]>;
35
 
36
        double _wcstod_r(<[reent]>,<[str]>,<[tail]>)
37
	wchar_t *<[reent]>;
38
        wchar_t *<[str]>;
39
        wchar_t **<[tail]>;
40
 
41
        float _wcstof_r(<[reent]>,<[str]>,<[tail]>)
42
	wchar_t *<[reent]>;
43
        wchar_t *<[str]>;
44
        wchar_t **<[tail]>;
45
 
46
DESCRIPTION
47
	The function <> parses the wide character string <[str]>,
48
	producing a substring which can be converted to a double
49
	value.  The substring converted is the longest initial
50
	subsequence of <[str]>, beginning with the first
51
	non-whitespace character, that has one of these formats:
52
	.[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>]
53
	.[+|-].<[digits]>[(e|E)[+|-]<[digits]>]
54
	.[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)]
55
	.[+|-](n|N)(a|A)(n|N)[<(>[<[hexdigits]>]<)>]
56
	.[+|-]0(x|X)<[hexdigits]>[.[<[hexdigits]>]][(p|P)[+|-]<[digits]>]
57
	.[+|-]0(x|X).<[hexdigits]>[(p|P)[+|-]<[digits]>]
58
	The substring contains no characters if <[str]> is empty, consists
59
	entirely of whitespace, or if the first non-whitespace
60
	character is something other than <<+>>, <<->>, <<.>>, or a
61
	digit, and cannot be parsed as infinity or NaN. If the platform
62
	does not support NaN, then NaN is treated as an empty substring.
63
	If the substring is empty, no conversion is done, and
64
	the value of <[str]> is stored in <<*<[tail]>>>.  Otherwise,
65
	the substring is converted, and a pointer to the final string
66
	(which will contain at least the terminating null character of
67
	<[str]>) is stored in <<*<[tail]>>>.  If you want no
68
	assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
69
	<> is identical to <> except for its return type.
70
 
71
	This implementation returns the nearest machine number to the
72
	input decimal string.  Ties are broken by using the IEEE
73
	round-even rule.  However, <> is currently subject to
74
	double rounding errors.
75
 
76
	The alternate functions <<_wcstod_r>> and <<_wcstof_r>> are
77
	reentrant versions of <> and <>, respectively.
78
	The extra argument <[reent]> is a pointer to a reentrancy structure.
79
 
80
RETURNS
81
	Return the converted substring value, if any.  If
82
	no conversion could be performed, 0 is returned.  If the
83
	correct value is out of the range of representable values,
84
	plus or minus <> is returned, and <> is
85
	stored in errno. If the correct value would cause underflow, 0
86
	is returned and <> is stored in errno.
87
 
88
Supporting OS subroutines required: <>, <>, <>,
89
<>, <>, <>, <>.
90
*/
91
 
92
/*-
93
 * Copyright (c) 2002 Tim J. Robbins
94
 * All rights reserved.
95
 *
96
 * Redistribution and use in source and binary forms, with or without
97
 * modification, are permitted provided that the following conditions
98
 * are met:
99
 * 1. Redistributions of source code must retain the above copyright
100
 *    notice, this list of conditions and the following disclaimer.
101
 * 2. Redistributions in binary form must reproduce the above copyright
102
 *    notice, this list of conditions and the following disclaimer in the
103
 *    documentation and/or other materials provided with the distribution.
104
 *
105
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
106
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
107
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
108
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
109
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
110
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
111
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
112
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
113
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
114
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
115
 * SUCH DAMAGE.
116
 */
117
 
118
#include <_ansi.h>
119
#include 
120
#include 
121
#include 
122
#include 
123
#include 
124
#include 
125
#include 
126
 
127
double
128
_DEFUN (_wcstod_r, (ptr, nptr, endptr),
129
	struct _reent *ptr _AND
130
	_CONST wchar_t *nptr _AND
131
	wchar_t **endptr)
132
{
133
        static const mbstate_t initial;
134
        mbstate_t mbs;
135
        double val;
136
        char *buf, *end;
137
        const wchar_t *wcp;
138
        size_t len;
139
 
140
        while (iswspace(*nptr))
141
                nptr++;
142
 
143
        /*
144
         * Convert the supplied numeric wide char. string to multibyte.
145
         *
146
         * We could attempt to find the end of the numeric portion of the
147
         * wide char. string to avoid converting unneeded characters but
148
         * choose not to bother; optimising the uncommon case where
149
         * the input string contains a lot of text after the number
150
         * duplicates a lot of strtod()'s functionality and slows down the
151
         * most common cases.
152
         */
153
        wcp = nptr;
154
        mbs = initial;
155
        if ((len = _wcsrtombs_r(ptr, NULL, &wcp, 0, &mbs)) == (size_t)-1) {
156
                if (endptr != NULL)
157
                        *endptr = (wchar_t *)nptr;
158
                return (0.0);
159
        }
160
        if ((buf = _malloc_r(ptr, len + 1)) == NULL)
161
                return (0.0);
162
        mbs = initial;
163
        _wcsrtombs_r(ptr, buf, &wcp, len + 1, &mbs);
164
 
165
        /* Let strtod() do most of the work for us. */
166
        val = _strtod_r(ptr, buf, &end);
167
 
168
        /*
169
         * We only know where the number ended in the _multibyte_
170
         * representation of the string. If the caller wants to know
171
         * where it ended, count multibyte characters to find the
172
         * corresponding position in the wide char string.
173
         */
174
        if (endptr != NULL) {
175
		/* The only valid multibyte char in a float converted by
176
		   strtod/wcstod is the radix char.  What we do here is,
177
		   figure out if the radix char was in the valid leading
178
		   float sequence in the incoming string.  If so, the
179
		   multibyte float string is strlen(radix char) - 1 bytes
180
		   longer than the incoming wide char string has characters.
181
		   To fix endptr, reposition end as if the radix char was
182
		   just one byte long.  The resulting difference (end - buf)
183
		   is then equivalent to the number of valid wide characters
184
		   in the input string. */
185
		len = strlen (_localeconv_r (ptr)->decimal_point);
186
		if (len > 1) {
187
			char *d = strstr (buf,
188
					  _localeconv_r (ptr)->decimal_point);
189
			if (d && d < end)
190
				end -= len - 1;
191
		}
192
                *endptr = (wchar_t *)nptr + (end - buf);
193
	}
194
 
195
        _free_r(ptr, buf);
196
 
197
        return (val);
198
}
199
 
200
float
201
_DEFUN (_wcstof_r, (ptr, nptr, endptr),
202
	struct _reent *ptr _AND
203
	_CONST wchar_t *nptr _AND
204
	wchar_t **endptr)
205
{
206
  double retval = _wcstod_r (ptr, nptr, endptr);
207
  if (isnan (retval))
208
    return nanf (NULL);
209
  return (float)retval;
210
}
211
 
212
#ifndef _REENT_ONLY
213
 
214
double
215
_DEFUN (wcstod, (nptr, endptr),
216
	_CONST wchar_t *__restrict nptr _AND wchar_t **__restrict endptr)
217
{
218
  return _wcstod_r (_REENT, nptr, endptr);
219
}
220
 
221
float
222
_DEFUN (wcstof, (nptr, endptr),
223
	_CONST wchar_t *__restrict nptr _AND
224
	wchar_t **__restrict endptr)
225
{
226
  double retval = _wcstod_r (_REENT, nptr, endptr);
227
  if (isnan (retval))
228
    return nanf (NULL);
229
  return (float)retval;
230
}
231
 
232
#endif