
1: /* Copyright (C) 2000 Free Software Foundation, Inc. 2: This file is part of the GNU C Library. 3: Contributed by Ulrich Drepper <drepper@gnu.org>, 2000. 4: 5: The GNU C Library is free software; you can redistribute it and/or 6: modify it under the terms of the GNU Lesser General Public 7: License as published by the Free Software Foundation; either 8: version 2.1 of the License, or (at your option) any later version. 9: 10: The GNU C Library is distributed in the hope that it will be useful, 11: but WITHOUT ANY WARRANTY; without even the implied warranty of 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13: Lesser General Public License for more details. 14: 15: You should have received a copy of the GNU Lesser General Public 16: License along with the GNU C Library; if not, write to the Free 17: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18: 02111-1307 USA. */ 19: 20: #include <assert.h> 21: #include <langinfo.h> 22: #include <string.h> 23: 24: /* Look up the value of the next multibyte character and return its numerical 25: value if it is one of the digits known in the locale. If *DECIDED is 26: -1 this means it is not yet decided which form it is and we have to 27: search through all available digits. Otherwise we know which script 28: the digits are from. */ 29: static inline int 30: indigit_value (const char **s, size_t *len, int *decided) 31: { 32: int from_level; 33: int to_level; 34: const char *mbdigits[10]; 35: int i; 36: int n; 37: 38: if (*decided != -1) 39: from_level = to_level = *decided; 40: else 41: { 42: from_level = 0; 43: to_level = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_INDIGITS_MB_LEN) - 1; 44: assert (from_level <= to_level); 45: } 46: 47: /* In this round we get the pointer to the digit strings and also perform 48: the first round of comparisons. */ 49: for (n = 0; n < 10; ++n) 50: { 51: size_t dlen; 52: 53: /* Get the string for the digits with value N. */ 54: mbdigits[n] = _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_MB + n); 55: dlen = strlen (mbdigits[n]); 56: 57: if (from_level == 0 && dlen <= *len 58: && memcmp (*s, mbdigits[n], dlen) == 0) 59: { 60: /* Found it. */ 61: *s += dlen; 62: *len -= dlen; 63: if (*decided == -1) 64: *decided = 0; 65: return n; 66: } 67: 68: /* Advance the pointer to the next string. */ 69: mbdigits[n] += dlen + 1; 70: } 71: 72: /* Now perform the remaining tests. */ 73: for (i = 1; i <= to_level; ++i) 74: { 75: /* Search all ten digits of this level. */ 76: for (n = 0; n < 10; ++n) 77: { 78: size_t dlen = strlen (mbdigits[n]); 79: 80: if (i >= from_level && dlen <= *len 81: && memcmp (*s, mbdigits[n], dlen) == 0) 82: { 83: /* Found it. */ 84: *s += dlen; 85: *len -= dlen; 86: if (*decided == -1) 87: *decided = from_level; 88: return n; 89: } 90: 91: /* Advance the pointer to the next string. */ 92: mbdigits[n] += dlen + 1; 93: } 94: } 95: 96: /* If we reach this point no matching digit was found. */ 97: return -1; 98: }