diff options
author | Bruce Mitchener <bruce.mitchener@gmail.com> | 2013-09-21 09:59:43 +0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2014-01-14 02:21:11 +0700 |
commit | c0229303f8fe4176d05286f3b887127c2b028368 (patch) | |
tree | 5aa09ee11658583c4ef1ea16cc92ecb40e9da495 /system/lib/libc/musl/src/stdlib/wcstod.c | |
parent | 369b8330ed5e115be82b616414892aaf1e3c7b2c (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.c | 64 |
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); +} |