fix various bugs in new integer parser framework
[musl] / src / stdlib / wcstoimax.c
index 861fcb5..344fe3a 100644 (file)
@@ -1,24 +1,39 @@
 #include <wchar.h>
+#include <wctype.h>
 #include <inttypes.h>
 #include <errno.h>
+#include "intparse.h"
 
 intmax_t wcstoimax(const wchar_t *s, wchar_t **p, int base)
 {
-       int sign = 0;
-       uintmax_t x;
+       const wchar_t *s1 = s;
+       struct intparse ip = {0};
+
+       if (p) *p = (wchar_t *)s;
+
+       if (base && base-2U > 34) {
+               errno = EINVAL;
+               return 0;
+       }
 
-       /* Initial whitespace */
        for (; iswspace(*s); s++);
 
-       /* Optional sign */
-       if (*s == '-') sign = *s++;
-       else if (*s == '+') s++;
+       ip.base = base;
+       for (; __intparse(&ip, (char[]){(*s&-(*s<128U))}, 1); s++);
+
+       if (p && ip.err != EINVAL)
+               *p = (wchar_t *)s1 + ip.cnt;
+
+       if (ip.err) {
+               errno = ip.err;
+               if (ip.err == EINVAL) return 0;
+               return ip.neg ? INTMAX_MIN : INTMAX_MAX;
+       }
 
-       x = wcstoumax(s, p, base);
-       if (x > INTMAX_MAX) {
-               if (!sign || -x != INTMAX_MIN)
+       if (ip.val > INTMAX_MAX) {
+               if (!ip.neg || -ip.val != INTMAX_MIN)
                        errno = ERANGE;
-               return sign ? INTMAX_MIN : INTMAX_MAX;
+               return ip.neg ? INTMAX_MIN : INTMAX_MAX;
        }
-       return sign ? -x : x;
+       return ip.neg ? -ip.val : ip.val;
 }