wcstod.c raw

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