From d7af9f1a488b6cdf0ba8c22c6d502283b7a52913 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Apr 2004 15:51:16 +0000 Subject: [PATCH] Fix problems when a locale-specific decimal separator directly follows a 2004-04-22 Matthias Clasen * 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 | 6 ++++++ ChangeLog.pre-2-10 | 6 ++++++ ChangeLog.pre-2-12 | 6 ++++++ ChangeLog.pre-2-4 | 6 ++++++ ChangeLog.pre-2-6 | 6 ++++++ ChangeLog.pre-2-8 | 6 ++++++ glib/gstrfuncs.c | 29 ++++++++++++++++++++++++----- tests/strtod-test.c | 23 ++++++++++++++--------- 8 files changed, 74 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5feb1e1..b6c1976a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d5feb1e1..b6c1976a 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index d5feb1e1..b6c1976a 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d5feb1e1..b6c1976a 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d5feb1e1..b6c1976a 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d5feb1e1..b6c1976a 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,5 +1,11 @@ 2004-04-22 Matthias Clasen + * 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) diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index ae5d64ac..56445199 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -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; diff --git a/tests/strtod-test.c b/tests/strtod-test.c index df175590..703f11ce 100644 --- a/tests/strtod-test.c +++ b/tests/strtod-test.c @@ -7,10 +7,10 @@ #include 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)); -- 2.34.1