diff options
Diffstat (limited to 'lib/strnumcmp-in.h')
-rw-r--r-- | lib/strnumcmp-in.h | 244 |
1 files changed, 0 insertions, 244 deletions
diff --git a/lib/strnumcmp-in.h b/lib/strnumcmp-in.h deleted file mode 100644 index 95ab55fdc..000000000 --- a/lib/strnumcmp-in.h +++ /dev/null @@ -1,244 +0,0 @@ -/* Compare numeric strings. This is an internal include file. - - Copyright (C) 1988-2012 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* Written by Mike Haertel. */ - -#ifndef STRNUMCMP_IN_H -# define STRNUMCMP_IN_H 1 - -# include "strnumcmp.h" - -# include <stddef.h> - -# define NEGATION_SIGN '-' -# define NUMERIC_ZERO '0' - -/* ISDIGIT differs from isdigit, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char - or EOF. - - It's typically faster. - POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to - isdigit unless it's important to use the locale's definition - of 'digit' even when the host does not conform to POSIX. */ -# define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) - - -/* Compare strings A and B containing decimal fractions < 1. - DECIMAL_POINT is the decimal point. Each string - should begin with a decimal point followed immediately by the digits - of the fraction. Strings not of this form are treated as zero. */ - -/* The goal here, is to take two numbers a and b... compare these - in parallel. Instead of converting each, and then comparing the - outcome. Most likely stopping the comparison before the conversion - is complete. The algorithm used, in the old "sort" utility: - - Algorithm: fraccompare - Action : compare two decimal fractions - accepts : char *a, char *b - returns : -1 if a<b, 0 if a=b, 1 if a>b. - implement: - - if *a == decimal_point AND *b == decimal_point - find first character different in a and b. - if both are digits, return the difference *a - *b. - if *a is a digit - skip past zeros - if digit return 1, else 0 - if *b is a digit - skip past zeros - if digit return -1, else 0 - if *a is a decimal_point - skip past decimal_point and zeros - if digit return 1, else 0 - if *b is a decimal_point - skip past decimal_point and zeros - if digit return -1, else 0 - return 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 (! ISDIGIT (*a)) - return 0; - if (ISDIGIT (*a) && ISDIGIT (*b)) - return *a - *b; - if (ISDIGIT (*a)) - goto a_trailing_nonzero; - if (ISDIGIT (*b)) - goto b_trailing_nonzero; - return 0; - } - else if (*a++ == decimal_point) - { - a_trailing_nonzero: - while (*a == NUMERIC_ZERO) - a++; - return ISDIGIT (*a); - } - else if (*b++ == decimal_point) - { - b_trailing_nonzero: - while (*b == NUMERIC_ZERO) - b++; - return - ISDIGIT (*b); - } - return 0; -} - -/* Compare strings A and B as numbers without explicitly converting - them to machine numbers, to avoid overflow problems and perhaps - improve performance. DECIMAL_POINT is the decimal point and - THOUSANDS_SEP the thousands separator. A DECIMAL_POINT of -1 - causes comparisons to act as if there is no decimal point - character, and likewise for THOUSANDS_SEP. */ - -static inline int _GL_ATTRIBUTE_PURE -numcompare (char const *a, char const *b, - int decimal_point, int thousands_sep) -{ - unsigned char tmpa = *a; - unsigned 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 (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 - ISDIGIT (tmpb); - } - do - tmpb = *++b; - while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep); - - while (tmpa == tmpb && ISDIGIT (tmpa)) - { - do - tmpa = *++a; - while (tmpa == thousands_sep); - do - tmpb = *++b; - while (tmpb == thousands_sep); - } - - if ((tmpa == decimal_point && !ISDIGIT (tmpb)) - || (tmpb == decimal_point && !ISDIGIT (tmpa))) - return fraccompare (b, a, decimal_point); - - tmp = tmpb - tmpa; - - for (log_a = 0; ISDIGIT (tmpa); ++log_a) - do - tmpa = *++a; - while (tmpa == thousands_sep); - - for (log_b = 0; 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 (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 ISDIGIT (tmpa); - } - else - { - while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep) - tmpa = *++a; - while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep) - tmpb = *++b; - - while (tmpa == tmpb && ISDIGIT (tmpa)) - { - do - tmpa = *++a; - while (tmpa == thousands_sep); - do - tmpb = *++b; - while (tmpb == thousands_sep); - } - - if ((tmpa == decimal_point && !ISDIGIT (tmpb)) - || (tmpb == decimal_point && !ISDIGIT (tmpa))) - return fraccompare (a, b, decimal_point); - - tmp = tmpa - tmpb; - - for (log_a = 0; ISDIGIT (tmpa); ++log_a) - do - tmpa = *++a; - while (tmpa == thousands_sep); - - for (log_b = 0; 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 |