* read_numberlike_string: * * fp: FILE pointer * * value: Place to store the value read * * Read what looks like valid numeric input and store it in a buffer * for later parsing as a number. * * Similarly to fscanf, this function always consumes leading whitespace, * and any text that could be the leading part in valid input. * * Return value: similar to fscanf. * * 0 if
| 600 | * * EOF if end-of-file met before reading anything. |
| 601 | */ |
| 602 | static int |
| 603 | read_numberlike_string(FILE *fp, char *buffer, size_t buflen) |
| 604 | { |
| 605 | |
| 606 | char *endp; |
| 607 | char *p; |
| 608 | int c; |
| 609 | int ok; |
| 610 | |
| 611 | /* |
| 612 | * Fill buffer with the leftmost matching part in regexp |
| 613 | * |
| 614 | * \s*[+-]? ( [0-9]*\.[0-9]+([eE][+-]?[0-9]+) |
| 615 | * | nan ( \([:alphanum:_]*\) )? |
| 616 | * | inf(inity)? |
| 617 | * ) |
| 618 | * |
| 619 | * case-insensitively. |
| 620 | * |
| 621 | * The "do { ... } while (0)" wrapping in macros ensures that they behave |
| 622 | * properly eg. in "if ... else" structures. |
| 623 | */ |
| 624 | |
| 625 | #define END_MATCH() \ |
| 626 | goto buffer_filled |
| 627 | |
| 628 | #define NEXT_CHAR() \ |
| 629 | do { \ |
| 630 | if (c == EOF || endp >= buffer + buflen - 1) \ |
| 631 | END_MATCH(); \ |
| 632 | *endp++ = (char)c; \ |
| 633 | c = getc(fp); \ |
| 634 | } while (0) |
| 635 | |
| 636 | #define MATCH_ALPHA_STRING_NOCASE(string) \ |
| 637 | do { \ |
| 638 | for (p=(string); *p!='\0' && (c==*p || c+('a'-'A')==*p); ++p) \ |
| 639 | NEXT_CHAR(); \ |
| 640 | if (*p != '\0') END_MATCH(); \ |
| 641 | } while (0) |
| 642 | |
| 643 | #define MATCH_ONE_OR_NONE(condition) \ |
| 644 | do { if (condition) NEXT_CHAR(); } while (0) |
| 645 | |
| 646 | #define MATCH_ONE_OR_MORE(condition) \ |
| 647 | do { \ |
| 648 | ok = 0; \ |
| 649 | while (condition) { NEXT_CHAR(); ok = 1; } \ |
| 650 | if (!ok) END_MATCH(); \ |
| 651 | } while (0) |
| 652 | |
| 653 | #define MATCH_ZERO_OR_MORE(condition) \ |
| 654 | while (condition) { NEXT_CHAR(); } |
| 655 | |
| 656 | /* 1. emulate fscanf EOF handling */ |
| 657 | c = getc(fp); |
| 658 | if (c == EOF) { |
| 659 | return EOF; |
no test coverage detected