Back to index

glibc  2.9
indigits.h
Go to the documentation of this file.
00001 /* Copyright (C) 2000 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@gnu.org>, 2000.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <assert.h>
00021 #include <langinfo.h>
00022 #include <string.h>
00023 
00024 /* Look up the value of the next multibyte character and return its numerical
00025    value if it is one of the digits known in the locale.  If *DECIDED is
00026    -1 this means it is not yet decided which form it is and we have to
00027    search through all available digits.  Otherwise we know which script
00028    the digits are from.  */
00029 static inline int
00030 indigit_value (const char **s, size_t *len, int *decided)
00031 {
00032   int from_level;
00033   int to_level;
00034   const char *mbdigits[10];
00035   int i;
00036   int n;
00037 
00038   if (*decided != -1)
00039     from_level = to_level = *decided;
00040   else
00041     {
00042       from_level = 0;
00043       to_level = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_INDIGITS_MB_LEN) - 1;
00044       assert (from_level <= to_level);
00045     }
00046 
00047   /* In this round we get the pointer to the digit strings and also perform
00048      the first round of comparisons.  */
00049   for (n = 0; n < 10; ++n)
00050     {
00051       size_t dlen;
00052 
00053       /* Get the string for the digits with value N.  */
00054       mbdigits[n] = _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_MB + n);
00055       dlen = strlen (mbdigits[n]);
00056 
00057       if (from_level == 0 && dlen <= *len
00058          && memcmp (*s, mbdigits[n], dlen) == 0)
00059        {
00060          /* Found it.  */
00061          *s += dlen;
00062          *len -= dlen;
00063          if (*decided == -1)
00064            *decided = 0;
00065          return n;
00066        }
00067 
00068       /* Advance the pointer to the next string.  */
00069       mbdigits[n] += dlen + 1;
00070     }
00071 
00072   /* Now perform the remaining tests.  */
00073   for (i = 1; i <= to_level; ++i)
00074     {
00075       /* Search all ten digits of this level.  */
00076       for (n = 0; n < 10; ++n)
00077        {
00078          size_t dlen = strlen (mbdigits[n]);
00079 
00080          if (i >= from_level && dlen <= *len
00081              && memcmp (*s, mbdigits[n], dlen) == 0)
00082            {
00083              /* Found it.  */
00084              *s += dlen;
00085              *len -= dlen;
00086              if (*decided == -1)
00087               *decided = from_level;
00088              return n;
00089            }
00090 
00091          /* Advance the pointer to the next string.  */
00092          mbdigits[n] += dlen + 1;
00093        }
00094     }
00095 
00096   /* If we reach this point no matching digit was found.  */
00097   return -1;
00098 }