Fix problems when a locale-specific decimal separator directly follows a
authorMatthias Clasen <mclasen@redhat.com>
Thu, 22 Apr 2004 15:51:16 +0000 (15:51 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 22 Apr 2004 15:51:16 +0000 (15:51 +0000)
2004-04-22  Matthias Clasen  <mclasen@redhat.com>

* glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a
locale-specific decimal separator directly follows a
number.  (#138424, Nickolay V. Shmyrev)

* tests/strtod-test.c (main): Add some more testcases.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/gstrfuncs.c
tests/strtod-test.c

index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index d5feb1e1551072d22f8f494d0bbe8da4ad003c51..b6c1976a2107597a8ef94cf54062ae7e7846bc98 100644 (file)
@@ -1,5 +1,11 @@
 2004-04-22  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gstrfuncs.c (g_ascii_strtod): Fix problems when a 
+       locale-specific decimal separator directly follows a 
+       number.  (#138424, Nickolay V. Shmyrev)
+
+       * tests/strtod-test.c (main): Add some more testcases.
+
        * glib/gmain.c (g_main_context_query): Only set time_is_current to 
        FALSE if context->timeout is not zero.  (#137795, Christian Krause)
 
index ae5d64ac6be7c80ea0a1af3fad4f9cffe262e056..5644519987e1af15cc20aa6df0bc9eb14a40e869 100644 (file)
@@ -346,7 +346,7 @@ g_ascii_strtod (const gchar *nptr,
   g_assert (decimal_point_len != 0);
   
   decimal_point_pos = NULL;
-  if (decimal_point[0] != '.' ||
+  if (decimal_point[0] != '.' || 
       decimal_point[1] != 0)
     {
       p = nptr;
@@ -358,7 +358,7 @@ g_ascii_strtod (const gchar *nptr,
       if (*p == '+' || *p == '-')
        p++;
       
-      if (p[0] == '0' &&
+      if (p[0] == '0' && 
          (p[1] == 'x' || p[1] == 'X'))
        {
          p += 2;
@@ -380,7 +380,6 @@ g_ascii_strtod (const gchar *nptr,
                p++;
              while (g_ascii_isdigit (*p))
                p++;
-             end = p;
            }
        }
       else
@@ -401,10 +400,10 @@ g_ascii_strtod (const gchar *nptr,
                p++;
              while (g_ascii_isdigit (*p))
                p++;
-             end = p;
            }
        }
       /* For the other cases, we need not convert the decimal point */
+      end = p;
     }
 
   /* Set errno to zero, so that we can distinguish zero results
@@ -440,8 +439,28 @@ g_ascii_strtod (const gchar *nptr,
       g_free (copy);
          
     }
+  else if (decimal_point[0] != '.' ||
+          decimal_point[1] != 0)
+    {
+      char *copy;
+      
+      copy = g_malloc (end - (char *)nptr + 1);
+      memcpy (copy, nptr, end - nptr);
+      *(copy + (end - (char *)nptr)) = 0;
+      
+      val = strtod (copy, &fail_pos);
+      
+      if (fail_pos)
+       {
+         fail_pos = (char *)nptr + (fail_pos - copy);
+       }
+      
+      g_free (copy);
+    }
   else
-    val = strtod (nptr, &fail_pos);
+    {
+      val = strtod (nptr, &fail_pos);
+    }
 
   if (endptr)
     *endptr = fail_pos;
index df1755907ada1edeb1321e253ebb2f8fdfd7e62d..703f11ce63d24879078897e6bef552e21570e468 100644 (file)
@@ -7,10 +7,10 @@
 #include <math.h>
 
 void
-test_string (char *number, double res)
+test_string (char *number, double res, gboolean check_end, int correct_len)
 {
   gdouble d;
-  char *locales[] = {"sv_SE", "en_US", "fa_IR", "C"};
+  char *locales[] = {"sv_SE", "en_US", "fa_IR", "C", "ru_RU"};
   int l;
   char *end;
   char *dummy;
@@ -28,7 +28,9 @@ test_string (char *number, double res)
       d = g_ascii_strtod (number, &end);
       if (d != res)
        g_print ("g_ascii_strtod for locale %s failed\n", locales[l]);
-      if (end - number != strlen(number))
+      if (check_end && end - number != correct_len)
+       g_print ("g_ascii_strtod for locale %s endptr was wrong\n", locales[l]);
+      if (!check_end && end - number != strlen (number))
        g_print ("g_ascii_strtod for locale %s endptr was wrong\n", locales[l]);
     }
   
@@ -42,12 +44,15 @@ main ()
   gdouble d;
   char buffer[G_ASCII_DTOSTR_BUF_SIZE];
 
-  test_string ("123.123", 123.123);
-  test_string ("123.123e2", 123.123e2);
-  test_string ("123.123e-2", 123.123e-2);
-  test_string ("-123.123", -123.123);
-  test_string ("-123.123e2", -123.123e2);
-  test_string ("-123.123e-2", -123.123e-2);
+  test_string ("123.123", 123.123, FALSE, 0);
+  test_string ("123.123e2", 123.123e2, FALSE, 0);
+  test_string ("123.123e-2", 123.123e-2, FALSE, 0);
+  test_string ("-123.123", -123.123, FALSE, 0);
+  test_string ("-123.123e2", -123.123e2, FALSE, 0);
+  test_string ("-123.123e-2", -123.123e-2, FALSE, 0);
+  test_string ("5.4", 5.4, TRUE, 3);
+  test_string ("5.4,5.5", 5.4, TRUE, 3);
+  test_string ("5,4", 5.0, TRUE, 1);
   
   d = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0;
   g_assert (d == g_ascii_strtod (g_ascii_dtostr (buffer, sizeof (buffer), d), NULL));