| 1406 | it is an overflow, an indeterminate value if some other error occurred. */ |
| 1407 | |
| 1408 | static intmax_t |
| 1409 | parse_integer (char const *str, strtol_error *invalid) |
| 1410 | { |
| 1411 | /* Call xstrtoumax, not xstrtoimax, since we don't want to |
| 1412 | allow strings like " -0". Initialize N to an indeterminate value; |
| 1413 | calling code should not rely on this function returning 0 |
| 1414 | when *INVALID represents a non-overflow error. */ |
| 1415 | int indeterminate = 0; |
| 1416 | uintmax_t n = indeterminate; |
| 1417 | char *suffix; |
| 1418 | static char const suffixes[] = "bcEGkKMPQRTwYZ0"; |
| 1419 | strtol_error e = xstrtoumax (str, &suffix, 10, &n, suffixes); |
| 1420 | intmax_t result; |
| 1421 | |
| 1422 | if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR |
| 1423 | && *suffix == 'B' && str < suffix && suffix[-1] != 'B') |
| 1424 | { |
| 1425 | suffix++; |
| 1426 | if (!*suffix) |
| 1427 | e &= ~LONGINT_INVALID_SUFFIX_CHAR; |
| 1428 | } |
| 1429 | |
| 1430 | if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR |
| 1431 | && *suffix == 'x') |
| 1432 | { |
| 1433 | strtol_error f = LONGINT_OK; |
| 1434 | intmax_t o = parse_integer (suffix + 1, &f); |
| 1435 | if ((f & ~LONGINT_OVERFLOW) != LONGINT_OK) |
| 1436 | { |
| 1437 | e = f; |
| 1438 | result = indeterminate; |
| 1439 | } |
| 1440 | else if (ckd_mul (&result, n, o) |
| 1441 | || (result != 0 && ((e | f) & LONGINT_OVERFLOW))) |
| 1442 | { |
| 1443 | e = LONGINT_OVERFLOW; |
| 1444 | result = INTMAX_MAX; |
| 1445 | } |
| 1446 | else |
| 1447 | { |
| 1448 | if (result == 0 && STRPREFIX (str, "0x")) |
| 1449 | diagnose (0, _("warning: %s is a zero multiplier; " |
| 1450 | "use %s if that is intended"), |
| 1451 | quote_n (0, "0x"), quote_n (1, "00x")); |
| 1452 | e = LONGINT_OK; |
| 1453 | } |
| 1454 | } |
| 1455 | else if (n <= INTMAX_MAX) |
| 1456 | result = n; |
| 1457 | else |
| 1458 | { |
| 1459 | e = LONGINT_OVERFLOW; |
| 1460 | result = INTMAX_MAX; |
| 1461 | } |
| 1462 | |
| 1463 | *invalid = e; |
| 1464 | return result; |
| 1465 | } |