| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
|
|
| #ifndef STRNUMCMP_IN_H |
| # define STRNUMCMP_IN_H 1 |
|
|
| # include "strnumcmp.h" |
|
|
| # include "c-ctype.h" |
| # include <stddef.h> |
|
|
| # define NEGATION_SIGN '-' |
| # define NUMERIC_ZERO '0' |
|
|
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| static inline int _GL_ATTRIBUTE_PURE |
| fraccompare (char const *a, char const *b, char decimal_point) |
| { |
| if (*a == decimal_point && *b == decimal_point) |
| { |
| while (*++a == *++b) |
| if (! c_isdigit (*a)) |
| return 0; |
| if (c_isdigit (*a) && c_isdigit (*b)) |
| return *a - *b; |
| if (c_isdigit (*a)) |
| goto a_trailing_nonzero; |
| if (c_isdigit (*b)) |
| goto b_trailing_nonzero; |
| return 0; |
| } |
| else if (*a++ == decimal_point) |
| { |
| a_trailing_nonzero: |
| while (*a == NUMERIC_ZERO) |
| a++; |
| return c_isdigit (*a); |
| } |
| else if (*b++ == decimal_point) |
| { |
| b_trailing_nonzero: |
| while (*b == NUMERIC_ZERO) |
| b++; |
| return - c_isdigit (*b); |
| } |
| return 0; |
| } |
|
|
| |
| |
| |
| |
| |
| |
|
|
| static inline int _GL_ATTRIBUTE_PURE |
| numcompare (char const *a, char const *b, |
| int decimal_point, int thousands_sep) |
| { |
| char tmpa = *a; |
| char tmpb = *b; |
| int tmp; |
| size_t log_a; |
| size_t log_b; |
|
|
| if (tmpa == NEGATION_SIGN) |
| { |
| do |
| tmpa = *++a; |
| while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep); |
| if (tmpb != NEGATION_SIGN) |
| { |
| if (tmpa == decimal_point) |
| do |
| tmpa = *++a; |
| while (tmpa == NUMERIC_ZERO); |
| if (c_isdigit (tmpa)) |
| return -1; |
| while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep) |
| tmpb = *++b; |
| if (tmpb == decimal_point) |
| do |
| tmpb = *++b; |
| while (tmpb == NUMERIC_ZERO); |
| return - c_isdigit (tmpb); |
| } |
| do |
| tmpb = *++b; |
| while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep); |
|
|
| while (tmpa == tmpb && c_isdigit (tmpa)) |
| { |
| do |
| tmpa = *++a; |
| while (tmpa == thousands_sep); |
| do |
| tmpb = *++b; |
| while (tmpb == thousands_sep); |
| } |
|
|
| if ((tmpa == decimal_point && !c_isdigit (tmpb)) |
| || (tmpb == decimal_point && !c_isdigit (tmpa))) |
| return fraccompare (b, a, decimal_point); |
|
|
| tmp = tmpb - tmpa; |
|
|
| for (log_a = 0; c_isdigit (tmpa); ++log_a) |
| do |
| tmpa = *++a; |
| while (tmpa == thousands_sep); |
|
|
| for (log_b = 0; c_isdigit (tmpb); ++log_b) |
| do |
| tmpb = *++b; |
| while (tmpb == thousands_sep); |
|
|
| if (log_a != log_b) |
| return log_a < log_b ? 1 : -1; |
|
|
| if (!log_a) |
| return 0; |
|
|
| return tmp; |
| } |
| else if (tmpb == NEGATION_SIGN) |
| { |
| do |
| tmpb = *++b; |
| while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep); |
| if (tmpb == decimal_point) |
| do |
| tmpb = *++b; |
| while (tmpb == NUMERIC_ZERO); |
| if (c_isdigit (tmpb)) |
| return 1; |
| while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep) |
| tmpa = *++a; |
| if (tmpa == decimal_point) |
| do |
| tmpa = *++a; |
| while (tmpa == NUMERIC_ZERO); |
| return c_isdigit (tmpa); |
| } |
| else |
| { |
| while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep) |
| tmpa = *++a; |
| while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep) |
| tmpb = *++b; |
|
|
| while (tmpa == tmpb && c_isdigit (tmpa)) |
| { |
| do |
| tmpa = *++a; |
| while (tmpa == thousands_sep); |
| do |
| tmpb = *++b; |
| while (tmpb == thousands_sep); |
| } |
|
|
| if ((tmpa == decimal_point && !c_isdigit (tmpb)) |
| || (tmpb == decimal_point && !c_isdigit (tmpa))) |
| return fraccompare (a, b, decimal_point); |
|
|
| tmp = tmpa - tmpb; |
|
|
| for (log_a = 0; c_isdigit (tmpa); ++log_a) |
| do |
| tmpa = *++a; |
| while (tmpa == thousands_sep); |
|
|
| for (log_b = 0; c_isdigit (tmpb); ++log_b) |
| do |
| tmpb = *++b; |
| while (tmpb == thousands_sep); |
|
|
| if (log_a != log_b) |
| return log_a < log_b ? -1 : 1; |
|
|
| if (!log_a) |
| return 0; |
|
|
| return tmp; |
| } |
| } |
|
|
| #endif |
|
|