| 111 | } |
| 112 | |
| 113 | uintmax_t |
| 114 | malloc_strtoumax(const char *restrict nptr, char **restrict endptr, int base) { |
| 115 | uintmax_t ret, digit; |
| 116 | unsigned b; |
| 117 | bool neg; |
| 118 | const char *p, *ns; |
| 119 | |
| 120 | p = nptr; |
| 121 | if (base < 0 || base == 1 || base > 36) { |
| 122 | ns = p; |
| 123 | set_errno(EINVAL); |
| 124 | ret = UINTMAX_MAX; |
| 125 | goto label_return; |
| 126 | } |
| 127 | b = base; |
| 128 | |
| 129 | /* Swallow leading whitespace and get sign, if any. */ |
| 130 | neg = false; |
| 131 | while (true) { |
| 132 | switch (*p) { |
| 133 | case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': |
| 134 | p++; |
| 135 | break; |
| 136 | case '-': |
| 137 | neg = true; |
| 138 | /* Fall through. */ |
| 139 | case '+': |
| 140 | p++; |
| 141 | /* Fall through. */ |
| 142 | default: |
| 143 | goto label_prefix; |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /* Get prefix, if any. */ |
| 148 | label_prefix: |
| 149 | /* |
| 150 | * Note where the first non-whitespace/sign character is so that it is |
| 151 | * possible to tell whether any digits are consumed (e.g., " 0" vs. |
| 152 | * " -x"). |
| 153 | */ |
| 154 | ns = p; |
| 155 | if (*p == '0') { |
| 156 | switch (p[1]) { |
| 157 | case '0': case '1': case '2': case '3': case '4': case '5': |
| 158 | case '6': case '7': |
| 159 | if (b == 0) { |
| 160 | b = 8; |
| 161 | } |
| 162 | if (b == 8) { |
| 163 | p++; |
| 164 | } |
| 165 | break; |
| 166 | case 'X': case 'x': |
| 167 | switch (p[2]) { |
| 168 | case '0': case '1': case '2': case '3': case '4': |
| 169 | case '5': case '6': case '7': case '8': case '9': |
| 170 | case 'A': case 'B': case 'C': case 'D': case 'E': |