Use xlocale functions where available

Implement g_ascii_strto{d,ll,ull} and g_ascii_formatd using
xlocale functions where available. This is slightly faster
and a lot less icky than our homegrown code.

https://bugzilla.gnome.org/show_bug.cgi?id=640293
This commit is contained in:
Matthias Clasen 2011-09-17 22:44:28 -04:00
parent 7b9571e4dd
commit e02b062635
2 changed files with 56 additions and 7 deletions

View File

@ -1030,6 +1030,8 @@ AS_IF([test x$ac_cv_func_statfs = xyes],
AC_CHECK_HEADERS(crt_externs.h)
AC_CHECK_FUNCS(_NSGetEnviron)
AC_CHECK_FUNCS(newlocale uselocale strtod_l strtoll_l strtoull_l)
AC_FUNC_VSNPRINTF_C99
AC_FUNC_PRINTF_UNIX98

View File

@ -33,6 +33,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <locale.h>
#include <errno.h>
@ -46,6 +47,7 @@
#include "gprintf.h"
#include "gprintfint.h"
#include "glibintl.h"
#include "gthreadprivate.h"
#ifdef G_OS_WIN32
@ -78,6 +80,25 @@ static const guint16 ascii_table_data[256] = {
const guint16 * const g_ascii_table = ascii_table_data;
#ifdef HAVE_NEWLOCALE
static locale_t
get_C_locale (void)
{
static gsize initialized = FALSE;
static locale_t C_locale = NULL;
g_thread_init_glib ();
if (g_once_init_enter (&initialized))
{
C_locale = newlocale (LC_ALL_MASK, "C", NULL);
g_once_init_leave (&initialized, TRUE);
}
return C_locale;
}
#endif
/**
* g_strdup:
* @str: the string to duplicate
@ -427,6 +448,9 @@ gdouble
g_ascii_strtod (const gchar *nptr,
gchar **endptr)
{
#ifdef HAVE_STRTOD_L
return strtod_l (nptr, endptr, get_C_locale ());
#else
gchar *fail_pos;
gdouble val;
struct lconv *locale_data;
@ -571,6 +595,7 @@ g_ascii_strtod (const gchar *nptr,
errno = strtod_errno;
return val;
#endif
}
@ -623,6 +648,15 @@ g_ascii_formatd (gchar *buffer,
const gchar *format,
gdouble d)
{
#ifdef HAVE_USELOCALE
locale_t old_locale;
old_locale = uselocale (get_C_locale ());
_g_snprintf (buffer, buf_len, format, d);
uselocale (old_locale);
return buffer;
#else
struct lconv *locale_data;
const char *decimal_point;
int decimal_point_len;
@ -688,8 +722,19 @@ g_ascii_formatd (gchar *buffer,
}
return buffer;
#endif
}
#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
(c) == '\r' || (c) == '\t' || (c) == '\v')
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define ISLOWER(c) ((c) >= 'a' && (c) <= 'z')
#define ISALPHA(c) (ISUPPER (c) || ISLOWER (c))
#define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
#if !defined(HAVE_STRTOLL_L) || !defined(HAVE_STRTOULL_L)
static guint64
g_parse_long_long (const gchar *nptr,
const gchar **endptr,
@ -702,13 +747,6 @@ g_parse_long_long (const gchar *nptr,
* Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02
* Free Software Foundation, Inc.
*/
#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
(c) == '\r' || (c) == '\t' || (c) == '\v')
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define ISLOWER(c) ((c) >= 'a' && (c) <= 'z')
#define ISALPHA(c) (ISUPPER (c) || ISLOWER (c))
#define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
gboolean overflow;
guint64 cutoff;
guint64 cutlim;
@ -820,6 +858,7 @@ g_parse_long_long (const gchar *nptr,
}
return 0;
}
#endif
/**
* g_ascii_strtoull:
@ -854,6 +893,9 @@ g_ascii_strtoull (const gchar *nptr,
gchar **endptr,
guint base)
{
#ifdef HAVE_STRTOULL_L
return strtoull_l (nptr, endptr, base, get_C_locale ());
#else
gboolean negative;
guint64 result;
@ -861,6 +903,7 @@ g_ascii_strtoull (const gchar *nptr,
/* Return the result of the appropriate sign. */
return negative ? -result : result;
#endif
}
/**
@ -896,6 +939,9 @@ g_ascii_strtoll (const gchar *nptr,
gchar **endptr,
guint base)
{
#ifdef HAVE_STRTOLL_L
return strtoll_l (nptr, endptr, base, get_C_locale ());
#else
gboolean negative;
guint64 result;
@ -915,6 +961,7 @@ g_ascii_strtoll (const gchar *nptr,
return - (gint64) result;
else
return (gint64) result;
#endif
}
/**