github.com/afumu/libc@v0.0.6/musl/src/stdlib/wcstod.c (about)

     1  #include "shgetc.h"
     2  #include "floatscan.h"
     3  #include "stdio_impl.h"
     4  #include <wchar.h>
     5  #include <wctype.h>
     6  
     7  /* This read function heavily cheats. It knows:
     8   *  (1) len will always be 1
     9   *  (2) non-ascii characters don't matter */
    10  
    11  static size_t do_read(FILE *f, unsigned char *buf, size_t len)
    12  {
    13  	size_t i;
    14  	const wchar_t *wcs = f->cookie;
    15  
    16  	if (!wcs[0]) wcs=L"@";
    17  	for (i=0; i<f->buf_size && wcs[i]; i++)
    18  		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
    19  	f->rpos = f->buf;
    20  	f->rend = f->buf + i;
    21  	f->cookie = (void *)(wcs+i);
    22  
    23  	if (i && len) {
    24  		*buf = *f->rpos++;
    25  		return 1;
    26  	}
    27  	return 0;
    28  }
    29  
    30  static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
    31  {
    32  	wchar_t *t = (wchar_t *)s;
    33  	unsigned char buf[64];
    34  	FILE f = {0};
    35  	f.flags = 0;
    36  	f.rpos = f.rend = f.buf = buf + 4;
    37  	f.buf_size = sizeof buf - 4;
    38  	f.lock = -1;
    39  	f.read = do_read;
    40  	while (iswspace(*t)) t++;
    41  	f.cookie = (void *)t;
    42  	shlim(&f, 0);
    43  	long double y = __floatscan(&f, prec, 1);
    44  	if (p) {
    45  		size_t cnt = shcnt(&f);
    46  		*p = cnt ? t + cnt : (wchar_t *)s;
    47  	}
    48  	return y;
    49  }
    50  
    51  float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
    52  {
    53  	return wcstox(s, p, 0);
    54  }
    55  
    56  double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
    57  {
    58  	return wcstox(s, p, 1);
    59  }
    60  
    61  long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
    62  {
    63  	return wcstox(s, p, 2);
    64  }