diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-06-10 09:26:54 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-06-10 15:04:35 +0900 |
| commit | df549c12e5852f640d37b2bd35e2d5dfc45a7283 (patch) | |
| tree | 63b3229b493716755818a81558fe9c162783989d /src/readflt.c | |
| parent | f2f6f2179b0c16720accfc1236890a7bc6d22a2b (diff) | |
| download | mruby-df549c12e5852f640d37b2bd35e2d5dfc45a7283.tar.gz mruby-df549c12e5852f640d37b2bd35e2d5dfc45a7283.zip | |
readflt.c: renamed from `strtod.c`
The file provides `mrb_read_float()` renamed from `vim_strtod()`.
Diffstat (limited to 'src/readflt.c')
| -rw-r--r-- | src/readflt.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/readflt.c b/src/readflt.c new file mode 100644 index 000000000..19a8e8dc6 --- /dev/null +++ b/src/readflt.c @@ -0,0 +1,120 @@ +#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 <stdlib.h> +#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 |
