| 139 | |
| 140 | template <typename Type> |
| 141 | static int ParseUnsigned(const char* str, const ScanSpecification& spec, Type* value) |
| 142 | { |
| 143 | int base = 0; |
| 144 | switch (spec.specifier) { |
| 145 | case 'v': |
| 146 | case 'i': |
| 147 | break; |
| 148 | case 'd': |
| 149 | case 'u': |
| 150 | base = 10; |
| 151 | break; |
| 152 | case 'x': |
| 153 | case 'X': |
| 154 | base = 16; |
| 155 | break; |
| 156 | case 'o': |
| 157 | base = 8; |
| 158 | break; |
| 159 | default: |
| 160 | LOG(DFATAL) << "Invalid scan specifier '" << spec.specifier |
| 161 | << "' for unsigned integral type"; |
| 162 | return 0; |
| 163 | } |
| 164 | |
| 165 | const char* nonspace = str; |
| 166 | while (*nonspace && isspace(*nonspace)) { // Skip leading spaces |
| 167 | ++nonspace; |
| 168 | } |
| 169 | if (*nonspace == '-') { |
| 170 | errno = ERANGE; |
| 171 | return 0; |
| 172 | } |
| 173 | |
| 174 | char* endptr; |
| 175 | int saved_errno = errno; |
| 176 | Type v; |
| 177 | errno = 0; |
| 178 | if (sizeof(Type) > sizeof(long)) { |
| 179 | unsigned long long n = strtoull(nonspace, &endptr, base); |
| 180 | if (errno != 0) |
| 181 | return 0; |
| 182 | v = n; |
| 183 | } else { |
| 184 | unsigned long n = strtoul(nonspace, &endptr, base); |
| 185 | if (errno != 0) |
| 186 | return 0; |
| 187 | v = n; |
| 188 | if (v != n) { |
| 189 | errno = ERANGE; |
| 190 | return 0; |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | *value = v; |
| 195 | errno = saved_errno; |
| 196 | return endptr - str; |
| 197 | } |
| 198 |
nothing calls this directly
no outgoing calls
no test coverage detected