Changeset aa5acd47 in mainline
- Timestamp:
- 2011-07-20T23:02:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 91aded7
- Parents:
- 4cf8ca6
- Location:
- uspace/lib/posix
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/inttypes.h
r4cf8ca6 raa5acd47 39 39 #include "libc/inttypes.h" 40 40 41 extern posix_intmax_t posix_strtoimax(const char *restrict nptr, 42 char **restrict endptr, int base); 43 extern posix_uintmax_t posix_strtoumax(const char *restrict nptr, 44 char **restrict endptr, int base); 45 41 46 #endif /* POSIX_INTTYPES_H_ */ 42 47 -
uspace/lib/posix/stdint.h
r4cf8ca6 raa5acd47 88 88 #define AOFF64_MIN UINT64_MIN 89 89 90 #undef INTMAX_MIN 91 #undef INTMAX_MAX 92 #define INTMAX_MIN INT64_MIN 93 #define INTMAX_MAX INT64_MAX 94 95 #undef UINTMAX_MIN 96 #undef UINTMAX_MAX 97 #define UINTMAX_MIN UINT64_MIN 98 #define UINTMAX_MAX UINT64_MAX 99 90 100 #include "libc/sys/types.h" 91 101 -
uspace/lib/posix/stdlib/strtol.c
r4cf8ca6 raa5acd47 38 38 #include "../stdlib.h" 39 39 40 #include "../limits.h"41 40 #include "../ctype.h" 42 41 #include "../errno.h" 42 #include "../inttypes.h" 43 #include "../limits.h" 44 45 #define intmax_t posix_intmax_t 46 #define uintmax_t posix_uintmax_t 43 47 44 48 /** … … 63 67 * 64 68 * @param c Character representation of the digit. 65 * @param base Base into which the digit belongs to.66 69 * @return Digit value represented by an integer. 67 70 */ 68 static inline int get_digit_in_base(int c, int base)71 static inline int digit_value(int c) 69 72 { 70 73 if (c <= '9') { … … 76 79 77 80 /** 78 * Backend for all integer conversion functions. Can be configured by arguments 79 * to convert both signed and unsigned integers of various sizes. 81 * Generic function for parsing an integer from it's string representation. 82 * Different variants differ in lower and upper bounds. 83 * The parsed string returned by this function is always positive, sign 84 * information is provided via a dedicated parameter. 80 85 * 81 86 * @param nptr Input string. 82 87 * @param endptr If non-NULL, *endptr is set to the position of the first 83 * unrecognized character. 84 * @param base Expected base of the string representation. 88 * unrecognized character. If no digit has been parsed, value of 89 * nptr is stored there (regardless of any skipped characters at the 90 * beginning). 91 * @param base Expected base of the string representation. If 0, base is 92 * determined to be decimal, octal or hexadecimal using the same rules 93 * as C syntax. Otherwise, value must be between 2 and 36, inclusive. 85 94 * @param min_value Lower bound for the resulting conversion. 86 95 * @param max_value Upper bound for the resulting conversion. … … 88 97 * bool variable into which shall be placed the negativity of the resulting 89 98 * converted value. 90 * @return Result of the conversion. 91 */ 92 static inline unsigned long long internal_strtol( 99 * @return The absolute value of the parsed value, or the closest in-range value 100 * if the parsed value is out of range. If the input is invalid, zero is 101 * returned and errno is set to EINVAL. 102 */ 103 static inline uintmax_t internal_strtol( 93 104 const char *restrict nptr, char **restrict endptr, int base, 94 const long long min_value, const unsigned long longmax_value,105 const intmax_t min_value, const uintmax_t max_value, 95 106 bool *restrict out_negative) 96 107 { … … 105 116 } 106 117 107 unsigned long long real_max_value = max_value; 118 /* The maximal absolute value that can be returned in this run. 119 * Depends on sign. 120 */ 121 uintmax_t real_max_value = max_value; 108 122 109 123 /* Current index in the input string. */ 110 int i = 0;124 size_t i = 0; 111 125 bool negative = false; 112 126 … … 120 134 case '-': 121 135 negative = true; 122 real_max_value = -min_value; 136 137 /* The strange computation is are there to avoid a corner case 138 * where -min_value can't be represented in intmax_t. 139 * (I'm not exactly sure what the semantics are in such a 140 * case, but this should be safe for any case.) 141 */ 142 real_max_value = (min_value == 0) 143 ? 0 144 :(((uintmax_t) -(min_value + 1)) + 1); 145 123 146 /* fallthrough */ 124 147 case '+': … … 131 154 if (nptr[i] == '0') { 132 155 if (tolower(nptr[i + 1]) == 'x') { 156 /* 0x... is hex. */ 133 157 base = 16; 134 158 i += 2; 135 159 } else { 160 /* 0... is octal. */ 136 161 base = 8; 137 162 } 138 163 } else { 164 /* Anything else is decimal by default. */ 139 165 base = 10; 140 166 } 141 167 break; 142 168 case 16: 169 /* Allow hex number to be prefixed with "0x". */ 143 170 if (nptr[i] == '0' && tolower(nptr[i + 1]) == 'x') { 144 171 i += 2; … … 160 187 * of overflow. 161 188 */ 162 u nsigned long longmax_safe_value = (real_max_value - base + 1) / base;163 164 u nsigned long longresult = 0;189 uintmax_t max_safe_value = (real_max_value - base + 1) / base; 190 191 uintmax_t result = 0; 165 192 166 193 if (real_max_value == 0) { … … 172 199 if (nptr[i] != '0') { 173 200 errno = ERANGE; 174 result = max_value;201 result = 0; 175 202 } 176 203 i++; … … 179 206 180 207 while (is_digit_in_base(nptr[i], base)) { 181 int digit = get_digit_in_base(nptr[i], base);208 int digit = digit_value(nptr[i]); 182 209 183 210 if (result > max_safe_value) { 184 211 /* corner case, check for overflow */ 185 212 186 unsigned long long 187 boundary = (real_max_value - digit) / base; 213 uintmax_t boundary = (real_max_value - digit) / base; 188 214 189 215 if (result > boundary) { … … 224 250 { 225 251 bool neg = false; 226 u nsigned long longresult =252 uintmax_t result = 227 253 internal_strtol(nptr, NULL, 10, INT_MIN, INT_MAX, &neg); 228 254 229 return ( int) (neg ? -result :result);255 return (neg ? ((int) -result) : (int) result); 230 256 } 231 257 … … 239 265 { 240 266 bool neg = false; 241 u nsigned long longresult =267 uintmax_t result = 242 268 internal_strtol(nptr, NULL, 10, LONG_MIN, LONG_MAX, &neg); 243 269 244 return ( long) (neg ? -result :result);270 return (neg ? ((long) -result) : (long) result); 245 271 } 246 272 … … 254 280 { 255 281 bool neg = false; 256 u nsigned long longresult =282 uintmax_t result = 257 283 internal_strtol(nptr, NULL, 10, LLONG_MIN, LLONG_MAX, &neg); 258 284 259 return ( long long) (neg ? -result :result);285 return (neg ? ((long long) -result) : (long long) result); 260 286 } 261 287 … … 272 298 { 273 299 bool neg = false; 274 u nsigned long longresult =300 uintmax_t result = 275 301 internal_strtol(nptr, endptr, base, LONG_MIN, LONG_MAX, &neg); 276 302 277 return ( long) (neg ? -result : result);303 return (neg ? ((long) -result) : ((long) result)); 278 304 } 279 305 … … 291 317 { 292 318 bool neg = false; 293 u nsigned long longresult =319 uintmax_t result = 294 320 internal_strtol(nptr, endptr, base, LLONG_MIN, LLONG_MAX, &neg); 295 321 296 return (long long) (neg ? -result : result); 322 return (neg ? ((long long) -result) : (long long) result); 323 } 324 325 /** 326 * Convert a string to a largest signed integer type. 327 * 328 * @param nptr Input string. 329 * @param endptr Pointer to the final part of the string which 330 * was not used for conversion. 331 * @param base Expected base of the string representation. 332 * @return Result of the conversion. 333 */ 334 intmax_t posix_strtoimax( 335 const char *restrict nptr, char **restrict endptr, int base) 336 { 337 bool neg = false; 338 uintmax_t result = 339 internal_strtol(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX, &neg); 340 341 return (neg ? ((intmax_t) -result) : (intmax_t) result); 297 342 } 298 343 … … 309 354 const char *restrict nptr, char **restrict endptr, int base) 310 355 { 311 u nsigned long longresult =356 uintmax_t result = 312 357 internal_strtol(nptr, endptr, base, 0, ULONG_MAX, NULL); 313 358 … … 316 361 317 362 /** 318 * Convert a string to a an unsigned long long integer.363 * Convert a string to an unsigned long long integer. 319 364 * 320 365 * @param nptr Input string. … … 327 372 const char *restrict nptr, char **restrict endptr, int base) 328 373 { 329 return internal_strtol(nptr, endptr, base, 0, ULLONG_MAX, NULL); 374 uintmax_t result = 375 internal_strtol(nptr, endptr, base, 0, ULLONG_MAX, NULL); 376 377 return (unsigned long long) result; 378 } 379 380 /** 381 * Convert a string to a largest unsigned integer type. 382 * 383 * @param nptr Input string. 384 * @param endptr Pointer to the final part of the string which 385 * was not used for conversion. 386 * @param base Expected base of the string representation. 387 * @return Result of the conversion. 388 */ 389 uintmax_t posix_strtoumax( 390 const char *restrict nptr, char **restrict endptr, int base) 391 { 392 uintmax_t result = 393 internal_strtol(nptr, endptr, base, 0, UINTMAX_MAX, NULL); 394 395 return result; 330 396 } 331 397
Note:
See TracChangeset
for help on using the changeset viewer.