]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 11 Oct 2004 22:28:15 +0000 (22:28 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 11 Oct 2004 22:28:15 +0000 (22:28 +0000)
* stdio-common/vfscanf.c: Add support for reading localized
digits.  Patch mainly by Hamed Malek <hamed@bamdad.org>.

ChangeLog
localedata/ChangeLog
localedata/locales/fa_IR
stdio-common/vfscanf.c

index f023b2b6e034389876639ba74102696b2c9bb7e8..d595214af19ec9b5fe12ec89296e5e8002b6e124 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2004-10-11  Ulrich Drepper  <drepper@redhat.com>
 
+       * stdio-common/vfscanf.c: Add support for reading localized
+       digits.  Patch mainly by Hamed Malek <hamed@bamdad.org>.
+
        * resolv/res_init.c (res_thread_freeres): Reset _res.options.
        [BZ #434]
 
index 065136e8d7a9264bf2678865d15cc4c9a7cb45e2..5f362c62b74b852d1b2ecbe00158b8f2b96250c9 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * locales/fa_IR: Add to_inpunct map.
+       Patch by Hamed Malek <hamed@bamdad.org>.
+
 2004-10-04  Ulrich Drepper  <drepper@redhat.com>
 
        * locales/gu_IN: Update various incorrect and missing information.
index 128c5d8cdcb3dc23f196c5a93fd8205d08110710..8f65b1edd89f02ce1abc9a0bb4da9b11a8c43c5e 100644 (file)
@@ -10,8 +10,8 @@ escape_char  /
 % Fax: +98 21 6019568
 % Language: fa
 % Territory: IR
-% Revision: 2.3
-% Date: 2004-03-16
+% Revision: 2.4
+% Date: 2004-09-04
 % Users: general
 % Repertoiremap:
 % Charset: UTF-8
@@ -50,6 +50,20 @@ copy "i18n"
 
 outdigit <U06F0>..<U06F9>
 
+map to_inpunct; /
+  (<U0030>,<U06F0>); /
+  (<U0031>,<U06F1>); /
+  (<U0032>,<U06F2>); /
+  (<U0033>,<U06F3>); /
+  (<U0034>,<U06F4>); /
+  (<U0035>,<U06F5>); /
+  (<U0036>,<U06F6>); /
+  (<U0037>,<U06F7>); /
+  (<U0038>,<U06F8>); /
+  (<U0039>,<U06F9>); /
+  (<U002E>,<U066B>); /
+  (<U002C>,<U066C>)
+
 map to_outpunct; /
   (<U002E>,<U066B>); /
   (<U002C>,<U066C>)
index 63e7bd8815a38fb5efd73f338a14a3473941ea04..c641d2d37104c89847de88fb4749db13407d56f7 100644 (file)
@@ -1163,9 +1163,15 @@ _IO_vfscanf (s, format, argptr, errp)
              int level;
 #ifdef COMPILE_WSCANF
              const wchar_t *wcdigits[10];
+             const wchar_t *wcdigits_extended[10];
 #else
              const char *mbdigits[10];
+             const char *mbdigits_extended[10];
 #endif
+             /*  "to_inpunct" is a map from ASCII digits to their
+                 equivalent in locale. This is defined for locales
+                 which use an extra digits set.  */
+             wctrans_t map = __wctrans ("to_inpunct");
              int n;
 
              from_level = 0;
@@ -1176,6 +1182,66 @@ _IO_vfscanf (s, format, argptr, errp)
              to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
 #endif
 
+             /* Get the alternative digit forms if there are any.  */
+             if (__builtin_expect (map != NULL, 0))
+               {
+                 /*  Adding new level for extra digits set in locale file.  */
+                 ++to_level;
+
+                 for (n = 0; n < 10; ++n)
+                   {
+#ifdef COMPILE_WSCANF
+                     wcdigits[n] = (const wchar_t *)
+                        _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
+
+                     wchar_t *wc_extended = (wchar_t *)
+                       alloca ((to_level + 2) * sizeof (wchar_t));
+                     __wmemcpy (wc_extended, wcdigits[n], to_level);
+                     wc_extended[to_level] = __towctrans (L'0' + n, map);
+                     wc_extended[to_level + 1] = '\0';
+                     wcdigits_extended[n] = wc_extended;
+#else
+                     mbdigits[n]
+                        = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
+
+                     /*  Get the equivalent wide char in map.  */
+                     wint_t extra_wcdigit = __towctrans (L'0' + n, map);
+
+                     /*  Convert it to multibyte representation.  */
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (state));
+
+                     char extra_mbdigit[MB_LEN_MAX];
+                     size_t mblen
+                       = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
+
+                     if (mblen == (size_t) -1)
+                       {
+                         /*  Ignore this new level.  */
+                         map = NULL;
+                         break;
+                       }
+
+                     /*  Calculate the length of mbdigits[n].  */
+                     const char *last_char = mbdigits[n];
+                     for (level = 0; level < to_level; ++level)
+                       last_char = strchr (last_char, '\0') + 1;
+
+                     size_t mbdigits_len = last_char - mbdigits[n];
+
+                     /*  Allocate memory for extended multibyte digit.  */
+                     char *mb_extended;
+                     mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
+
+                     /*  And get the mbdigits + extra_digit string.  */
+                     *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
+                                                     mbdigits_len),
+                                          extra_mbdigit, mblen) = '\0';
+                     mbdigits_extended[n] = mb_extended;
+#endif
+                   }
+               }
+
              /* Read the number into workspace.  */
              while (c != EOF && width != 0)
                {
@@ -1185,8 +1251,11 @@ _IO_vfscanf (s, format, argptr, errp)
                    {
                      /* Get the string for the digits with value N.  */
 #ifdef COMPILE_WSCANF
-                     wcdigits[n] = (const wchar_t *)
-                       _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
+                     if (__builtin_expect (map != NULL, 0))
+                       wcdigits[n] = wcdigits_extended[n];
+                     else
+                       wcdigits[n] = (const wchar_t *)
+                         _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
                      wcdigits[n] += from_level;
 
                      if (c == (wint_t) *wcdigits[n])
@@ -1201,8 +1270,11 @@ _IO_vfscanf (s, format, argptr, errp)
                      const char *cmpp;
                      int avail = width > 0 ? width : INT_MAX;
 
-                     mbdigits[n]
-                       = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
+                     if (__builtin_expect (map != NULL, 0))
+                       mbdigits[n] = mbdigits_extended[n];
+                     else
+                       mbdigits[n]
+                         = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
 
                      for (level = 0; level < from_level; level++)
                        mbdigits[n] = strchr (mbdigits[n], '\0') + 1;