wcstol.c 1.8 KB

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