]>
Commit | Line | Data |
---|---|---|
e5f14be3 | 1 | #ifdef __wasilibc_unmodified_upstream // Changes to optimize printf/scanf when long double isn't needed |
320054e8 DG |
2 | #else |
3 | #include "printscan.h" | |
4 | #endif | |
5 | #include "shgetc.h" | |
6 | #include "floatscan.h" | |
7 | #include "stdio_impl.h" | |
8 | #include <wchar.h> | |
9 | #include <wctype.h> | |
10 | ||
11 | /* This read function heavily cheats. It knows: | |
12 | * (1) len will always be 1 | |
13 | * (2) non-ascii characters don't matter */ | |
14 | ||
15 | static size_t do_read(FILE *f, unsigned char *buf, size_t len) | |
16 | { | |
17 | size_t i; | |
18 | const wchar_t *wcs = f->cookie; | |
19 | ||
20 | if (!wcs[0]) wcs=L"@"; | |
21 | for (i=0; i<f->buf_size && wcs[i]; i++) | |
22 | f->buf[i] = wcs[i] < 128 ? wcs[i] : '@'; | |
23 | f->rpos = f->buf; | |
24 | f->rend = f->buf + i; | |
25 | f->cookie = (void *)(wcs+i); | |
26 | ||
27 | if (i && len) { | |
28 | *buf = *f->rpos++; | |
29 | return 1; | |
30 | } | |
31 | return 0; | |
32 | } | |
33 | ||
34 | #if defined(__wasilibc_printscan_no_long_double) | |
35 | static long_double wcstox(const wchar_t *s, wchar_t **p, int prec) | |
36 | #else | |
37 | static long double wcstox(const wchar_t *s, wchar_t **p, int prec) | |
38 | #endif | |
39 | { | |
40 | wchar_t *t = (wchar_t *)s; | |
41 | unsigned char buf[64]; | |
42 | FILE f = {0}; | |
43 | f.flags = 0; | |
58795582 | 44 | f.rpos = f.rend = f.buf = buf + 4; |
320054e8 | 45 | f.buf_size = sizeof buf - 4; |
9bb4cc5c | 46 | #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) |
320054e8 | 47 | f.lock = -1; |
9bb4cc5c | 48 | #endif |
320054e8 DG |
49 | f.read = do_read; |
50 | while (iswspace(*t)) t++; | |
51 | f.cookie = (void *)t; | |
52 | shlim(&f, 0); | |
53 | #if defined(__wasilibc_printscan_no_long_double) | |
54 | long_double y = __floatscan(&f, prec, 1); | |
55 | #else | |
56 | long double y = __floatscan(&f, prec, 1); | |
57 | #endif | |
58 | if (p) { | |
59 | size_t cnt = shcnt(&f); | |
60 | *p = cnt ? t + cnt : (wchar_t *)s; | |
61 | } | |
62 | return y; | |
63 | } | |
64 | ||
65 | float wcstof(const wchar_t *restrict s, wchar_t **restrict p) | |
66 | { | |
67 | return wcstox(s, p, 0); | |
68 | } | |
69 | ||
70 | double wcstod(const wchar_t *restrict s, wchar_t **restrict p) | |
71 | { | |
72 | return wcstox(s, p, 1); | |
73 | } | |
74 | ||
75 | long double wcstold(const wchar_t *restrict s, wchar_t **restrict p) | |
76 | { | |
77 | #if defined(__wasilibc_printscan_no_long_double) | |
78 | long_double_not_supported(); | |
79 | #else | |
80 | return wcstox(s, p, 2); | |
81 | #endif | |
82 | } |