diff options
Diffstat (limited to 'stdlib/grouping.h')
-rw-r--r-- | stdlib/grouping.h | 176 |
1 files changed, 12 insertions, 164 deletions
diff --git a/stdlib/grouping.h b/stdlib/grouping.h index 830304d2f1..c0f8d47fba 100644 --- a/stdlib/grouping.h +++ b/stdlib/grouping.h @@ -1,5 +1,5 @@ /* Internal header for proving correct grouping in strings of numbers. - Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1995,1996,1997,1998,2000,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. @@ -18,169 +18,17 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <limits.h> - -#ifndef MAX -#define MAX(a,b) ({ typeof(a) _a = (a); typeof(b) _b = (b); \ - _a > _b ? _a : _b; }) -#endif - /* Find the maximum prefix of the string between BEGIN and END which satisfies the grouping rules. It is assumed that at least one digit follows BEGIN directly. */ - -static inline const STRING_TYPE * -correctly_grouped_prefix (const STRING_TYPE *begin, const STRING_TYPE *end, -#ifdef USE_WIDE_CHAR - wchar_t thousands, -#else - const char *thousands, -#endif - const char *grouping) -{ -#ifndef USE_WIDE_CHAR - size_t thousands_len; - int cnt; -#endif - - if (grouping == NULL) - return end; - -#ifndef USE_WIDE_CHAR - thousands_len = strlen (thousands); -#endif - - while (end > begin) - { - const STRING_TYPE *cp = end - 1; - const char *gp = grouping; - - /* Check first group. */ - while (cp >= begin) - { -#ifdef USE_WIDE_CHAR - if (*cp == thousands) - break; -#else - if (cp[thousands_len - 1] == *thousands) - { - for (cnt = 1; thousands[cnt] != '\0'; ++cnt) - if (thousands[cnt] != cp[thousands_len - 1 - cnt]) - break; - if (thousands[cnt] == '\0') - break; - } -#endif - --cp; - } - - /* We allow the representation to contain no grouping at all even if - the locale specifies we can have grouping. */ - if (cp < begin) - return end; - - if (end - cp == (int) *gp + 1) - { - /* This group matches the specification. */ - - const STRING_TYPE *new_end; - - if (cp < begin) - /* There is just one complete group. We are done. */ - return end; - - /* CP points to a thousands separator character. The preceding - remainder of the string from BEGIN to NEW_END is the part we - will consider if there is a grouping error in this trailing - portion from CP to END. */ - new_end = cp - 1; - - /* Loop while the grouping is correct. */ - while (1) - { - /* Get the next grouping rule. */ - ++gp; - if (*gp == 0) - /* If end is reached use last rule. */ - --gp; - - /* Skip the thousands separator. */ - --cp; - - if (*gp == CHAR_MAX -#if CHAR_MIN < 0 - || *gp < 0 -#endif - ) - { - /* No more thousands separators are allowed to follow. */ - while (cp >= begin) - { -#ifdef USE_WIDE_CHAR - if (*cp == thousands) - break; -#else - for (cnt = 0; thousands[cnt] != '\0'; ++cnt) - if (thousands[cnt] != cp[thousands_len - cnt - 1]) - break; - if (thousands[cnt] == '\0') - break; -#endif - --cp; - } - - if (cp < begin) - /* OK, only digits followed. */ - return end; - } - else - { - /* Check the next group. */ - const STRING_TYPE *group_end = cp; - - while (cp >= begin) - { -#ifdef USE_WIDE_CHAR - if (*cp == thousands) - break; -#else - for (cnt = 0; thousands[cnt] != '\0'; ++cnt) - if (thousands[cnt] != cp[thousands_len - cnt - 1]) - break; - if (thousands[cnt] == '\0') - break; -#endif - --cp; - } - - if (cp < begin && group_end - cp <= (int) *gp) - /* Final group is correct. */ - return end; - - if (cp < begin || group_end - cp != (int) *gp) - /* Incorrect group. Punt. */ - break; - } - } - - /* The trailing portion of the string starting at NEW_END - contains a grouping error. So we will look for a correctly - grouped number in the preceding portion instead. */ - end = new_end; - } - else - { - /* Even the first group was wrong; determine maximum shift. */ - if (end - cp > (int) *gp + 1) - end = cp + (int) *gp + 1; - else if (cp < begin) - /* This number does not fill the first group, but is correct. */ - return end; - else - /* CP points to a thousands separator character. */ - end = cp; - } - } - - return MAX (begin, end); -} +extern const wchar_t *__correctly_grouped_prefixwc (const wchar_t *begin, + const wchar_t *end, + wchar_t thousands, + const char *grouping) + attribute_hidden; + +extern const char *__correctly_grouped_prefixmb (const char *begin, + const char *end, + const char *thousands, + const char *grouping) + attribute_hidden; |