| Index: fusl/src/stdlib/wcstod.c
|
| diff --git a/fusl/src/stdlib/wcstod.c b/fusl/src/stdlib/wcstod.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..26fe9af8b4cc7d7c5f69fbab349d1bb1735f18f8
|
| --- /dev/null
|
| +++ b/fusl/src/stdlib/wcstod.c
|
| @@ -0,0 +1,65 @@
|
| +#include "shgetc.h"
|
| +#include "floatscan.h"
|
| +#include "stdio_impl.h"
|
| +#include <wchar.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);
|
| +}
|
|
|