https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=26a8b62e9a3398bc0308e13edfa053a01eb0cc21

commit 26a8b62e9a3398bc0308e13edfa053a01eb0cc21
Author: Corinna Vinschen <cori...@vinschen.de>
Date:   Sat Nov 21 16:51:12 2015 +0100

    Fix numeric and monetary decimal point and thousands separator in fa_IR and 
ps_AF locales
    
        * nlsfuncs.cc (setlocaleinfo): New macro calling __setlocaleinfo.
        (__setlocaleinfo): New function to set a locale-specific character
        to an explicit wchar_t value.
        (__set_lc_numeric_from_win): Handle fa_IR and ps_AF locales to return
        same decimal point and thousands separator characters as on Linux.
        (__set_lc_monetary_from_win): Ditto for monetary characters.
    
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog     |  9 +++++++
 winsup/cygwin/nlsfuncs.cc   | 66 ++++++++++++++++++++++++++++++++++++++-------
 winsup/cygwin/release/2.4.0 |  3 +++
 winsup/doc/ChangeLog        |  4 +++
 winsup/doc/new-features.xml |  5 ++++
 5 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a751696..689411d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+2015-11-21  Corinna Vinschen  <cori...@vinschen.de>
+
+       * nlsfuncs.cc (setlocaleinfo): New macro calling __setlocaleinfo.
+       (__setlocaleinfo): New function to set a locale-specific character
+       to an explicit wchar_t value.
+       (__set_lc_numeric_from_win): Handle fa_IR and ps_AF locales to return
+       same decimal point and thousands separator characters as on Linux.
+       (__set_lc_monetary_from_win): Ditto for monetary characters.
+
 2015-11-20  Corinna Vinschen  <cori...@vinschen.de>
 
        * common.din (strtold): Drop redirection to _strtold.
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index 1b2b2d7..9dbd9b1 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -31,6 +31,8 @@ details. */
 
 #define getlocaleinfo(category,type) \
            __getlocaleinfo(lcid,(type),_LC(category))
+#define setlocaleinfo(category,val) \
+           __setlocaleinfo(_LC(category),(val))
 #define eval_datetimefmt(type,flags) \
            __eval_datetimefmt(lcid,(type),(flags),&lc_time_ptr,\
                               lc_time_end-lc_time_ptr)
@@ -365,6 +367,20 @@ __getlocaleinfo (LCID lcid, LCTYPE type, char **ptr, 
size_t size)
   return ret;
 }
 
+static wchar_t *
+__setlocaleinfo (char **ptr, size_t size, wchar_t val)
+{
+  wchar_t *ret;
+
+  if ((uintptr_t) *ptr % 1)
+    ++*ptr;
+  ret = (wchar_t *) *ptr;
+  ret[0] = val;
+  ret[1] = L'\0';
+  *ptr = (char *) (ret + 2);
+  return ret;
+}
+
 static char *
 __charfromwchar (const wchar_t *in, char **ptr, size_t size,
                 wctomb_p f_wctomb, const char *charset)
@@ -868,11 +884,28 @@ __set_lc_numeric_from_win (const char *name,
     memcpy (_numeric_locale, _C_numeric_locale, sizeof (struct lc_numeric_T));
   else
     {
-      /* decimal_point */
-      _numeric_locale->wdecimal_point = getlocaleinfo (numeric, 
LOCALE_SDECIMAL);
+      /* decimal_point and thousands_sep */
+      if (lcid == 0x0429)      /* fa_IR.  Windows decimal_point is slash,
+                                          correct is dot */
+       {
+         _numeric_locale->wdecimal_point = setlocaleinfo (numeric, L'.');
+         _numeric_locale->wthousands_sep = setlocaleinfo (numeric, L',');
+       }
+      else if (lcid == 0x0463) /* ps_AF.  Windows decimal_point is dot,
+                                          thousands_sep is comma, correct are
+                                          arabic separators. */
+       {
+         _numeric_locale->wdecimal_point = setlocaleinfo (numeric, 0x066b);
+         _numeric_locale->wthousands_sep = setlocaleinfo (numeric, 0x066c);
+       }
+      else
+       {
+         _numeric_locale->wdecimal_point = getlocaleinfo (numeric,
+                                                          LOCALE_SDECIMAL);
+         _numeric_locale->wthousands_sep = getlocaleinfo (numeric,
+                                                          LOCALE_STHOUSAND);
+       }
       _numeric_locale->decimal_point = charfromwchar (numeric, wdecimal_point);
-      /* thousands_sep */
-      _numeric_locale->wthousands_sep = getlocaleinfo (numeric, 
LOCALE_STHOUSAND);
       _numeric_locale->thousands_sep = charfromwchar (numeric, wthousands_sep);
       /* grouping */
       _numeric_locale->grouping = conv_grouping (lcid, LOCALE_SGROUPING,
@@ -953,14 +986,27 @@ __set_lc_monetary_from_win (const char *name,
       else
        _monetary_locale->currency_symbol = charfromwchar (monetary,
                                                           wcurrency_symbol);
-      /* mon_decimal_point */
-      _monetary_locale->wmon_decimal_point = getlocaleinfo (monetary,
-                                                           
LOCALE_SMONDECIMALSEP);
+      /* mon_decimal_point and mon_thousands_sep */
+      if (lcid == 0x0429 || lcid == 0x0463)    /* fa_IR or ps_AF.  Windows
+                                                  mon_decimal_point is slash
+                                                  and comma, mon_thousands_sep
+                                                  is comma and dot, correct
+                                                  are arabic separators. */
+       {
+         _monetary_locale->wmon_decimal_point = setlocaleinfo (monetary,
+                                                               0x066b);
+         _monetary_locale->wmon_thousands_sep = setlocaleinfo (monetary,
+                                                               0x066c);
+       }
+      else
+       {
+         _monetary_locale->wmon_decimal_point = getlocaleinfo (monetary,
+                                                       LOCALE_SMONDECIMALSEP);
+         _monetary_locale->wmon_thousands_sep = getlocaleinfo (monetary,
+                                                       LOCALE_SMONTHOUSANDSEP);
+       }
       _monetary_locale->mon_decimal_point = charfromwchar (monetary,
                                                           wmon_decimal_point);
-      /* mon_thousands_sep */
-      _monetary_locale->wmon_thousands_sep = getlocaleinfo (monetary,
-                                                           
LOCALE_SMONTHOUSANDSEP);
       _monetary_locale->mon_thousands_sep = charfromwchar (monetary,
                                                           wmon_thousands_sep);
       /* mon_grouping */
diff --git a/winsup/cygwin/release/2.4.0 b/winsup/cygwin/release/2.4.0
index 20cde31..bb47216 100644
--- a/winsup/cygwin/release/2.4.0
+++ b/winsup/cygwin/release/2.4.0
@@ -31,6 +31,9 @@ What changed:
 - setfacl(1) now allows to use the -b and -k option combined to allow reducing
   an ACL to only reflect standard POSIX permissions.
 
+- Fix (numeric and monetary) decimal point and thousands separator in
+  fa_IR and ps_AF locales to be aligned with Linux.
+
 
 Bug Fixes
 ---------
diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index f20a72d..8d42f00 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-21  Corinna Vinschen  <cori...@vinschen.de>
+
+       * new-features.xml (ov-new2.4): Document fa_IR and ps_AF locale fixes.
+
 2015-11-18  Corinna Vinschen  <cori...@vinschen.de>
 
        * new-features.xml (ov-new2.4): Add new ACL changes.
diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml
index ff8c036..21bc691 100644
--- a/winsup/doc/new-features.xml
+++ b/winsup/doc/new-features.xml
@@ -40,6 +40,11 @@ setfacl(1) now allows to use the -b and -k option combined 
to allow reducing
 an ACL to only reflect standard POSIX permissions.
 </para></listitem>
 
+<listitem><para>
+Fix (numeric and monetary) decimal point and thousands separator in
+fa_IR and ps_AF locales to be aligned with Linux.
+</para></listitem>
+
 </itemizedlist>
 
 </sect2>

Reply via email to