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

     1  #include "stdio_impl.h"
     2  #include "intscan.h"
     3  #include "shgetc.h"
     4  #include <inttypes.h>
     5  #include <limits.h>
     6  #include <wctype.h>
     7  #include <wchar.h>
     8  
     9  /* This read function heavily cheats. It knows:
    10   *  (1) len will always be 1
    11   *  (2) non-ascii characters don't matter */
    12  
    13  static size_t do_read(FILE *f, unsigned char *buf, size_t len)
    14  {
    15  	size_t i;
    16  	const wchar_t *wcs = f->cookie;
    17  
    18  	if (!wcs[0]) wcs=L"@";
    19  	for (i=0; i<f->buf_size && wcs[i]; i++)
    20  		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
    21  	f->rpos = f->buf;
    22  	f->rend = f->buf + i;
    23  	f->cookie = (void *)(wcs+i);
    24  
    25  	if (i && len) {
    26  		*buf = *f->rpos++;
    27  		return 1;
    28  	}
    29  	return 0;
    30  }
    31  
    32  static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
    33  {
    34  	wchar_t *t = (wchar_t *)s;
    35  	unsigned char buf[64];
    36  	FILE f = {0};
    37  	f.flags = 0;
    38  	f.rpos = f.rend = f.buf = buf + 4;
    39  	f.buf_size = sizeof buf - 4;
    40  	f.lock = -1;
    41  	f.read = do_read;
    42  	while (iswspace(*t)) t++;
    43  	f.cookie = (void *)t;
    44  	shlim(&f, 0);
    45  	unsigned long long y = __intscan(&f, base, 1, lim);
    46  	if (p) {
    47  		size_t cnt = shcnt(&f);
    48  		*p = cnt ? t + cnt : (wchar_t *)s;
    49  	}
    50  	return y;
    51  }
    52  
    53  unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
    54  {
    55  	return wcstox(s, p, base, ULLONG_MAX);
    56  }
    57  
    58  long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
    59  {
    60  	return wcstox(s, p, base, LLONG_MIN);
    61  }
    62  
    63  unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
    64  {
    65  	return wcstox(s, p, base, ULONG_MAX);
    66  }
    67  
    68  long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
    69  {
    70  	return wcstox(s, p, base, 0UL+LONG_MIN);
    71  }
    72  
    73  intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
    74  {
    75  	return wcstoll(s, p, base);
    76  }
    77  
    78  uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
    79  {
    80  	return wcstoull(s, p, base);
    81  }