summaryrefslogtreecommitdiff
path: root/system/lib/libc/musl/src/stdlib/wcstod.c
diff options
context:
space:
mode:
authorBruce Mitchener <bruce.mitchener@gmail.com>2013-09-21 09:59:43 +0700
committerBruce Mitchener <bruce.mitchener@gmail.com>2014-01-14 02:21:11 +0700
commitc0229303f8fe4176d05286f3b887127c2b028368 (patch)
tree5aa09ee11658583c4ef1ea16cc92ecb40e9da495 /system/lib/libc/musl/src/stdlib/wcstod.c
parent369b8330ed5e115be82b616414892aaf1e3c7b2c (diff)
Add strtod(), wcstod(), wcstol() and friends.
This implementation of strtod() replaces the old as it implements support for parsing hex constants which is needed by various tests.
Diffstat (limited to 'system/lib/libc/musl/src/stdlib/wcstod.c')
-rw-r--r--system/lib/libc/musl/src/stdlib/wcstod.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/system/lib/libc/musl/src/stdlib/wcstod.c b/system/lib/libc/musl/src/stdlib/wcstod.c
new file mode 100644
index 00000000..83f308d3
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/wcstod.c
@@ -0,0 +1,64 @@
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include <wctype.h>
+
+/* This read function heavily cheats. It knows:
+ * (1) len will always be 1
+ * (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+ size_t i;
+ const wchar_t *wcs = f->cookie;
+
+ if (!wcs[0]) wcs=L"@";
+ for (i=0; i<f->buf_size && wcs[i]; i++)
+ f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+ f->rpos = f->buf;
+ f->rend = f->buf + i;
+ f->cookie = (void *)(wcs+i);
+
+ if (i && len) {
+ *buf = *f->rpos++;
+ return 1;
+ }
+ return 0;
+}
+
+static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
+{
+ wchar_t *t = (wchar_t *)s;
+ unsigned char buf[64];
+ FILE f = {0};
+ f.flags = 0;
+ f.rpos = f.rend = 0;
+ f.buf = buf + 4;
+ f.buf_size = sizeof buf - 4;
+ f.lock = -1;
+ f.read = do_read;
+ while (iswspace(*t)) t++;
+ f.cookie = (void *)t;
+ shlim(&f, 0);
+ long double y = __floatscan(&f, prec, 1);
+ if (p) {
+ size_t cnt = shcnt(&f);
+ *p = cnt ? t + cnt : (wchar_t *)s;
+ }
+ return y;
+}
+
+float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 0);
+}
+
+double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 1);
+}
+
+long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
+{
+ return wcstox(s, p, 2);
+}