|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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 |
|
|
|