* float8in_internal_opt_error - guts of float8in() * * This is exposed for use by functions that want a reasonably * platform-independent way of inputting doubles. The behavior is * essentially like strtod + ereport on error, but note the following * differences: * 1. Both leading and trailing whitespace are skipped. * 2. If endptr_p is NULL, we throw error if there's trailing junk. * Oth
| 376 | * error. This is helpful when caller need to handle errors by itself. |
| 377 | */ |
| 378 | double |
| 379 | float8in_internal_opt_error(char *num, char **endptr_p, |
| 380 | const char *type_name, const char *orig_string, |
| 381 | bool *have_error) |
| 382 | { |
| 383 | double val; |
| 384 | char *endptr; |
| 385 | |
| 386 | if (have_error) |
| 387 | *have_error = false; |
| 388 | |
| 389 | /* skip leading whitespace */ |
| 390 | while (*num != '\0' && isspace((unsigned char) *num)) |
| 391 | num++; |
| 392 | |
| 393 | /* |
| 394 | * Check for an empty-string input to begin with, to avoid the vagaries of |
| 395 | * strtod() on different platforms. |
| 396 | */ |
| 397 | if (*num == '\0') |
| 398 | RETURN_ERROR(ereport(ERROR, |
| 399 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), |
| 400 | errmsg("invalid input syntax for type %s: \"%s\"", |
| 401 | type_name, orig_string))), |
| 402 | have_error); |
| 403 | |
| 404 | errno = 0; |
| 405 | val = strtod(num, &endptr); |
| 406 | |
| 407 | /* did we not see anything that looks like a double? */ |
| 408 | if (endptr == num || errno != 0) |
| 409 | { |
| 410 | int save_errno = errno; |
| 411 | |
| 412 | /* |
| 413 | * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf, |
| 414 | * but not all platforms support all of these (and some accept them |
| 415 | * but set ERANGE anyway...) Therefore, we check for these inputs |
| 416 | * ourselves if strtod() fails. |
| 417 | * |
| 418 | * Note: C99 also requires hexadecimal input as well as some extended |
| 419 | * forms of NaN, but we consider these forms unportable and don't try |
| 420 | * to support them. You can use 'em if your strtod() takes 'em. |
| 421 | */ |
| 422 | if (pg_strncasecmp(num, "NaN", 3) == 0) |
| 423 | { |
| 424 | val = get_float8_nan(); |
| 425 | endptr = num + 3; |
| 426 | } |
| 427 | else if (pg_strncasecmp(num, "Infinity", 8) == 0) |
| 428 | { |
| 429 | val = get_float8_infinity(); |
| 430 | endptr = num + 8; |
| 431 | } |
| 432 | else if (pg_strncasecmp(num, "+Infinity", 9) == 0) |
| 433 | { |
| 434 | val = get_float8_infinity(); |
| 435 | endptr = num + 9; |
no test coverage detected