wcstol.c raw

   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  }
  82