@@ -10,21 +10,19 @@ The full license is in the LICENSE file, distributed with this software.
10
10
#ifndef PANDAS__LIBS_SRC_PARSE_HELPER_H_
11
11
#define PANDAS__LIBS_SRC_PARSE_HELPER_H_
12
12
13
- #include <errno.h>
14
13
#include <float.h>
15
14
#include "inline_helper.h"
16
15
#include "headers/portable.h"
17
-
18
- static double xstrtod (const char * p , char * * q , char decimal , char sci ,
19
- int skip_trailing , int * maybe_int );
16
+ #include "parser/tokenizer.h"
20
17
21
18
int to_double (char * item , double * p_value , char sci , char decimal ,
22
19
int * maybe_int ) {
23
20
char * p_end = NULL ;
21
+ int error = 0 ;
24
22
25
- * p_value = xstrtod (item , & p_end , decimal , sci , 1 , maybe_int );
23
+ * p_value = xstrtod (item , & p_end , decimal , sci , '\0' , 1 , & error , maybe_int );
26
24
27
- return (errno == 0 ) && (!* p_end );
25
+ return (error == 0 ) && (!* p_end );
28
26
}
29
27
30
28
#if PY_VERSION_HEX < 0x02060000
@@ -82,61 +80,8 @@ int floatify(PyObject *str, double *result, int *maybe_int) {
82
80
PyErr_Format (PyExc_ValueError , "Unable to parse string \"%s\"" , data );
83
81
Py_XDECREF (tmp );
84
82
return -1 ;
85
-
86
- /*
87
- #if PY_VERSION_HEX >= 0x03000000
88
- return PyFloat_FromString(str);
89
- #else
90
- return PyFloat_FromString(str, NULL);
91
- #endif
92
- */
93
83
}
94
84
95
- // ---------------------------------------------------------------------------
96
- // Implementation of xstrtod
97
-
98
- //
99
- // strtod.c
100
- //
101
- // Convert string to double
102
- //
103
- // Copyright (C) 2002 Michael Ringgaard. All rights reserved.
104
- //
105
- // Redistribution and use in source and binary forms, with or without
106
- // modification, are permitted provided that the following conditions
107
- // are met:
108
- //
109
- // 1. Redistributions of source code must retain the above copyright
110
- // notice, this list of conditions and the following disclaimer.
111
- // 2. Redistributions in binary form must reproduce the above copyright
112
- // notice, this list of conditions and the following disclaimer in the
113
- // documentation and/or other materials provided with the distribution.
114
- // 3. Neither the name of the project nor the names of its contributors
115
- // may be used to endorse or promote products derived from this software
116
- // without specific prior written permission.
117
- //
118
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
119
- // AND
120
- // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
121
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
122
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
123
- // LIABLE
124
- // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
125
- // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
126
- // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
127
- // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
128
- // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
129
- // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
130
- // SUCH DAMAGE.
131
- //
132
- // -----------------------------------------------------------------------
133
- // Modifications by Warren Weckesser, March 2011:
134
- // * Rename strtod() to xstrtod().
135
- // * Added decimal and sci arguments.
136
- // * Skip trailing spaces.
137
- // * Commented out the other functions.
138
- //
139
-
140
85
PANDAS_INLINE void lowercase (char * p ) {
141
86
for (; * p ; ++ p ) * p = tolower_ascii (* p );
142
87
}
@@ -145,130 +90,4 @@ PANDAS_INLINE void uppercase(char *p) {
145
90
for (; * p ; ++ p ) * p = toupper_ascii (* p );
146
91
}
147
92
148
- static double xstrtod (const char * str , char * * endptr , char decimal , char sci ,
149
- int skip_trailing , int * maybe_int ) {
150
- double number ;
151
- int exponent ;
152
- int negative ;
153
- char * p = (char * )str ;
154
- double p10 ;
155
- int n ;
156
- int num_digits ;
157
- int num_decimals ;
158
-
159
- errno = 0 ;
160
- * maybe_int = 1 ;
161
-
162
- // Skip leading whitespace
163
- while (isspace (* p )) p ++ ;
164
-
165
- // Handle optional sign
166
- negative = 0 ;
167
- switch (* p ) {
168
- case '-' :
169
- negative = 1 ; // Fall through to increment position
170
- case '+' :
171
- p ++ ;
172
- }
173
-
174
- number = 0. ;
175
- exponent = 0 ;
176
- num_digits = 0 ;
177
- num_decimals = 0 ;
178
-
179
- // Process string of digits
180
- while (isdigit_ascii (* p )) {
181
- number = number * 10. + (* p - '0' );
182
- p ++ ;
183
- num_digits ++ ;
184
- }
185
-
186
- // Process decimal part
187
- if (* p == decimal ) {
188
- * maybe_int = 0 ;
189
- p ++ ;
190
-
191
- while (isdigit_ascii (* p )) {
192
- number = number * 10. + (* p - '0' );
193
- p ++ ;
194
- num_digits ++ ;
195
- num_decimals ++ ;
196
- }
197
-
198
- exponent -= num_decimals ;
199
- }
200
-
201
- if (num_digits == 0 ) {
202
- errno = ERANGE ;
203
- return 0.0 ;
204
- }
205
-
206
- // Correct for sign
207
- if (negative ) number = - number ;
208
-
209
- // Process an exponent string
210
- if (toupper_ascii (* p ) == toupper_ascii (sci )) {
211
- * maybe_int = 0 ;
212
-
213
- // Handle optional sign
214
- negative = 0 ;
215
- switch (* ++ p ) {
216
- case '-' :
217
- negative = 1 ; // Fall through to increment pos
218
- case '+' :
219
- p ++ ;
220
- }
221
-
222
- // Process string of digits
223
- num_digits = 0 ;
224
- n = 0 ;
225
- while (isdigit_ascii (* p )) {
226
- n = n * 10 + (* p - '0' );
227
- num_digits ++ ;
228
- p ++ ;
229
- }
230
-
231
- if (negative )
232
- exponent -= n ;
233
- else
234
- exponent += n ;
235
-
236
- // If no digits, after the 'e'/'E', un-consume it
237
- if (num_digits == 0 ) p -- ;
238
- }
239
-
240
- if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP ) {
241
- errno = ERANGE ;
242
- return HUGE_VAL ;
243
- }
244
-
245
- // Scale the result
246
- p10 = 10. ;
247
- n = exponent ;
248
- if (n < 0 ) n = - n ;
249
- while (n ) {
250
- if (n & 1 ) {
251
- if (exponent < 0 )
252
- number /= p10 ;
253
- else
254
- number *= p10 ;
255
- }
256
- n >>= 1 ;
257
- p10 *= p10 ;
258
- }
259
-
260
- if (number == HUGE_VAL ) {
261
- errno = ERANGE ;
262
- }
263
-
264
- if (skip_trailing ) {
265
- // Skip trailing whitespace
266
- while (isspace_ascii (* p )) p ++ ;
267
- }
268
-
269
- if (endptr ) * endptr = p ;
270
-
271
- return number ;
272
- }
273
-
274
93
#endif // PANDAS__LIBS_SRC_PARSE_HELPER_H_
0 commit comments