blob: b320a43c141e307eacbb666f54f4f4e62340eb1e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#include <mruby.h>
#ifndef MRB_NO_FLOAT
/*
* strtod implementation.
* author: Yasuhiro Matsumoto (@mattn)
* license: public domain
*/
/*
The original code can be found in https://github.com/mattn/strtod
I modified the routine for mruby:
* renamed the function `vim_strtod` -> `mrb_float_read`
* simplified the code
My modifications in this file are also placed in the public domain.
Matz (Yukihiro Matsumoto)
*/
#include <string.h>
#include <math.h>
#include <errno.h>
MRB_API double
mrb_float_read(const char *str, char **end)
{
double d = 0.0;
int sign;
int n = 0;
const char *p, *a;
a = p = str;
while (ISSPACE(*p))
++p;
/* decimal part */
sign = 1;
if (*p == '-') {
sign = -1;
++p;
} else if (*p == '+')
++p;
if (ISDIGIT(*p)) {
d = (double)(*p++ - '0');
while (*p && ISDIGIT(*p)) {
d = d * 10.0 + (double)(*p - '0');
++p;
++n;
}
a = p;
} else if (*p != '.')
goto done;
d *= sign;
/* fraction part */
if (*p == '.') {
double f = 0.0;
double base = 0.1;
++p;
if (ISDIGIT(*p))
{
while (*p && ISDIGIT(*p)) {
f += base * (*p - '0') ;
base /= 10.0;
++p;
++n;
}
}
d += f * sign;
a = p;
}
/* exponential part */
if ((*p == 'E') || (*p == 'e')) {
int e = 0;
++p;
sign = 1;
if (*p == '-') {
sign = -1;
++p;
} else if (*p == '+')
++p;
if (ISDIGIT(*p)) {
while (*p == '0')
++p;
if (*p == '\0') --p;
e = (int)(*p++ - '0');
for (; *p && ISDIGIT(*p); p++) {
if (e < 10000)
e = e * 10 + (*p - '0');
}
e *= sign;
}
else if (!ISDIGIT(*(a-1))) {
a = str;
goto done;
}
else if (*p == 0)
goto done;
d *= pow(10.0, (double) e);
a = p;
}
else if (p > str && !ISDIGIT(*(p-1))) {
a = str;
goto done;
}
done:
if (end)
*end = (char*)a;
return d;
}
#endif
|