Changeset 31a566b in mainline
- Timestamp:
- 2019-05-27T16:17:24Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0260034
- Parents:
- af5037d
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2019-02-25 16:35:41)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2019-05-27 16:17:24)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/strtol.c
raf5037d r31a566b 69 69 } 70 70 71 static inline int _prefixbase(const char *restrict *nptrptr, bool nonstandard_prefixes) 72 { 73 const char *nptr = *nptrptr; 74 75 if (nptr[0] != '0') 76 return 10; 77 78 if (nptr[1] == 'x' || nptr[1] == 'X') { 79 *nptrptr += 2; 80 return 16; 81 } 82 83 if (nonstandard_prefixes) { 84 switch (nptr[1]) { 85 case 'b': 86 case 'B': 87 *nptrptr += 2; 88 return 2; 89 case 'o': 90 case 'O': 91 *nptrptr += 2; 92 return 8; 93 case 'd': 94 case 'D': 95 case 't': 96 case 'T': 97 *nptrptr += 2; 98 return 10; 99 } 100 } 101 102 return 8; 103 } 104 71 105 static inline uintmax_t _strtoumax( 72 106 const char *restrict nptr, char **restrict endptr, int base, 73 bool *restrict sgn )107 bool *restrict sgn, errno_t *err, bool nonstandard_prefixes) 74 108 { 75 109 assert(nptr != NULL); … … 96 130 /* Figure out the base. */ 97 131 98 if (base == 0) { 99 if (*nptr == '0') { 100 if (tolower(nptr[1]) == 'x') { 101 /* 0x... is hex. */ 102 base = 16; 103 nptr += 2; 104 } else { 105 /* 0... is octal. */ 106 base = 8; 107 } 108 } else { 109 /* Anything else is decimal by default. */ 110 base = 10; 111 } 112 } else if (base == 16) { 113 /* Allow hex number to be prefixed with "0x". */ 114 if (nptr[0] == '0' && tolower(nptr[1]) == 'x') { 132 if (base == 0) 133 base = _prefixbase(&nptr, nonstandard_prefixes); 134 135 if (base == 16 && !nonstandard_prefixes) { 136 /* 137 * Standard strto* functions allow hexadecimal prefix to be 138 * present when base is explicitly set to 16. 139 * Our nonstandard str_* functions don't allow it. 140 */ 141 142 if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) 115 143 nptr += 2; 116 } 117 } else if (base < 0 || base == 1 || base > 36) { 118 errno = EINVAL; 144 } 145 146 if (base < 2 || base > 36) { 147 *err = EINVAL; 119 148 return 0; 120 149 } … … 127 156 128 157 while (digit = _digit_value(*nptr), digit < base) { 129 130 158 if (result > max || 131 159 __builtin_add_overflow(result * base, digit, &result)) { 132 160 133 errno= ERANGE;161 *err = ERANGE; 134 162 result = UINTMAX_MAX; 135 163 break; … … 145 173 * Move the pointer to the end of the number, 146 174 * in case it isn't there already. 175 * This can happen when the number has legal formatting, 176 * but is out of range of the target type. 147 177 */ 148 178 while (_digit_value(*nptr) < base) { … … 157 187 158 188 static inline intmax_t _strtosigned(const char *nptr, char **endptr, int base, 159 intmax_t min, intmax_t max )189 intmax_t min, intmax_t max, errno_t *err, bool nonstandard_prefixes) 160 190 { 161 191 bool sgn = false; 162 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn); 192 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, 193 nonstandard_prefixes); 163 194 164 195 if (number > (uintmax_t) max) { … … 167 198 } 168 199 169 errno= ERANGE;200 *err = ERANGE; 170 201 return (sgn ? min : max); 171 202 } … … 175 206 176 207 static inline uintmax_t _strtounsigned(const char *nptr, char **endptr, int base, 177 uintmax_t max )208 uintmax_t max, errno_t *err, bool nonstandard_prefixes) 178 209 { 179 210 bool sgn = false; 180 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn); 181 182 if (sgn) { 183 if (number == 0) { 184 return 0; 185 } else { 186 errno = ERANGE; 187 return max; 188 } 189 } 211 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, 212 nonstandard_prefixes); 190 213 191 214 if (number > max) { 192 errno= ERANGE;215 *err = ERANGE; 193 216 return max; 194 217 } 195 218 196 return number;219 return (sgn ? -number : number); 197 220 } 198 221 … … 212 235 long strtol(const char *nptr, char **endptr, int base) 213 236 { 214 return _strtosigned(nptr, endptr, base, LONG_MIN, LONG_MAX );237 return _strtosigned(nptr, endptr, base, LONG_MIN, LONG_MAX, &errno, false); 215 238 } 216 239 … … 230 253 unsigned long strtoul(const char *nptr, char **endptr, int base) 231 254 { 232 return _strtounsigned(nptr, endptr, base, ULONG_MAX );255 return _strtounsigned(nptr, endptr, base, ULONG_MAX, &errno, false); 233 256 } 234 257 235 258 long long strtoll(const char *nptr, char **endptr, int base) 236 259 { 237 return _strtosigned(nptr, endptr, base, LLONG_MIN, LLONG_MAX );260 return _strtosigned(nptr, endptr, base, LLONG_MIN, LLONG_MAX, &errno, false); 238 261 } 239 262 240 263 unsigned long long strtoull(const char *nptr, char **endptr, int base) 241 264 { 242 return _strtounsigned(nptr, endptr, base, ULLONG_MAX );265 return _strtounsigned(nptr, endptr, base, ULLONG_MAX, &errno, false); 243 266 } 244 267 245 268 intmax_t strtoimax(const char *nptr, char **endptr, int base) 246 269 { 247 return _strtosigned(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX );270 return _strtosigned(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX, &errno, false); 248 271 } 249 272 250 273 uintmax_t strtoumax(const char *nptr, char **endptr, int base) 251 274 { 252 return _strtounsigned(nptr, endptr, base, UINTMAX_MAX );275 return _strtounsigned(nptr, endptr, base, UINTMAX_MAX, &errno, false); 253 276 } 254 277
Note:
See TracChangeset
for help on using the changeset viewer.