Convert a string into a long long. Returns 1 if the string could be parsed * into a (non-overflowing) long long, 0 otherwise. The value will be set to * the parsed value when appropriate. * * Note that this function demands that the string strictly represents * a long long: no spaces or other characters before or after the string * representing the number are accepted, nor zeroes at the star
| 383 | * you can convert a string into a long long, and obtain back the string |
| 384 | * from the number without any loss in the string representation. */ |
| 385 | int string2ll(const char *s, size_t slen, long long *value) { |
| 386 | const char *p = s; |
| 387 | size_t plen = 0; |
| 388 | int negative = 0; |
| 389 | unsigned long long v; |
| 390 | |
| 391 | /* A zero length string is not a valid number. */ |
| 392 | if (plen == slen) |
| 393 | return 0; |
| 394 | |
| 395 | /* Special case: first and only digit is 0. */ |
| 396 | if (slen == 1 && p[0] == '0') { |
| 397 | if (value != NULL) *value = 0; |
| 398 | return 1; |
| 399 | } |
| 400 | |
| 401 | /* Handle negative numbers: just set a flag and continue like if it |
| 402 | * was a positive number. Later convert into negative. */ |
| 403 | if (p[0] == '-') { |
| 404 | negative = 1; |
| 405 | p++; plen++; |
| 406 | |
| 407 | /* Abort on only a negative sign. */ |
| 408 | if (plen == slen) |
| 409 | return 0; |
| 410 | } |
| 411 | |
| 412 | /* First digit should be 1-9, otherwise the string should just be 0. */ |
| 413 | if (p[0] >= '1' && p[0] <= '9') { |
| 414 | v = p[0]-'0'; |
| 415 | p++; plen++; |
| 416 | } else { |
| 417 | return 0; |
| 418 | } |
| 419 | |
| 420 | /* Parse all the other digits, checking for overflow at every step. */ |
| 421 | while (plen < slen && p[0] >= '0' && p[0] <= '9') { |
| 422 | if (v > (ULLONG_MAX / 10)) /* Overflow. */ |
| 423 | return 0; |
| 424 | v *= 10; |
| 425 | |
| 426 | if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ |
| 427 | return 0; |
| 428 | v += p[0]-'0'; |
| 429 | |
| 430 | p++; plen++; |
| 431 | } |
| 432 | |
| 433 | /* Return if not all bytes were used. */ |
| 434 | if (plen < slen) |
| 435 | return 0; |
| 436 | |
| 437 | /* Convert to negative if needed, and do the final overflow check when |
| 438 | * converting from unsigned long long to long long. */ |
| 439 | if (negative) { |
| 440 | if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ |
| 441 | return 0; |
| 442 | if (value != NULL) *value = -v; |
no outgoing calls