Fix problems when a locale-specific decimal separator directly follows a

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.
This commit is contained in:
Matthias Clasen 2004-04-22 15:51:16 +00:00 committed by Matthias Clasen
parent cbfb32bcff
commit d7af9f1a48
8 changed files with 74 additions and 14 deletions

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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;

View 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));