aboutsummaryrefslogtreecommitdiffstats
path: root/core/module-text.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/module-text.c')
-rw-r--r--core/module-text.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/core/module-text.c b/core/module-text.c
index 4ce1769..f09cb75 100644
--- a/core/module-text.c
+++ b/core/module-text.c
@@ -59,6 +59,30 @@ size_t pure_utf8_newlines(PureSpan span) {
return count;
}
+bool pure_parse_number(const unsigned char *text, size_t size, double *value) {
+ size_t i = 0;
+ if (i < size && text[i] == '-') ++i;
+ if (i == size || text[i] < '0' || text[i] > '9') return false;
+ if (text[i++] != '0') while (i < size && text[i] >= '0' && text[i] <= '9') ++i;
+ if (i < size && text[i] == '.') {
+ if (++i == size || text[i] < '0' || text[i] > '9') return false;
+ while (i < size && text[i] >= '0' && text[i] <= '9') ++i;
+ }
+ if (i < size && (text[i] == 'e' || text[i] == 'E')) {
+ if (++i < size && (text[i] == '+' || text[i] == '-')) ++i;
+ if (i == size || text[i] < '0' || text[i] > '9') return false;
+ while (i < size && text[i] >= '0' && text[i] <= '9') ++i;
+ }
+ if (i != size) return false;
+ char small[64], *digits = size < sizeof(small) ? small : malloc(size + 1); /* strtod rounds to nearest, ties to even */
+ if (!digits) return false;
+ memcpy(digits, text, size);
+ digits[size] = 0;
+ *value = strtod(digits, NULL);
+ if (digits != small) free(digits);
+ return isfinite(*value);
+}
+
size_t pure_format_number(double value, char out[32]) {
if (value == 0) { memcpy(out, "0", 2); return 1; }
if (value == floor(value) && fabs(value) < 1e15) {