From e1ef8e5f7555a1608d0cddde6c824c5a897f6e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Mon, 23 Oct 2017 19:00:27 +0100 Subject: [PATCH] Test g_printf() thousands grouping flag at runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This tests the runtime environment so avoid hard-coding it during the build. For now we avoid messing with locales for the test, unless it turns out to be necessary (ISO C printf behaviour with invalid conversion specifier is undefined). Change-Id: I341c2ab5e716973689cf9002f13435404a41369f Reviewed-on: https://code.wireshark.org/review/24038 Petri-Dish: João Valverde Tested-by: Petri Dish Buildbot Reviewed-by: João Valverde --- ConfigureChecks.cmake | 35 ----------------------------------- configure.ac | 35 ----------------------------------- wsutil/str_util.c | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 29 insertions(+), 83 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index c4bd431a1a..99732f9e7d 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -184,41 +184,6 @@ if (NL_FOUND) ) endif() -# -# Check whether GLib's printf supports thousands grouping. (This might -# be different from the system's printf since GLib can optionally use -# its own printf implementation.) -# -if (CMAKE_CROSSCOMPILING OR WIN32) - # - # Play it safe when cross-compiling. - # - # XXX - compiling and trying to run the test below appears - # to loop infinitely on Windows, and the locale is wrong in - # any case, so we don't do this on Window for now. - # - set(HAVE_GLIB_PRINTF_GROUPING FALSE) -else() - cmake_push_check_state() - set(CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS}) - set(CMAKE_REQUIRED_LIBRARIES ${GLIB2_LIBRARIES}) - check_c_source_runs( - "#include - #include - #include - #include - - int - main () - { - gchar *str; - setlocale(LC_ALL, \"en_US.UTF-8\"); - str = g_strdup_printf(\"%'u\", 123456); - return (strcmp (str, \"123,456\") != 0); - }" HAVE_GLIB_PRINTF_GROUPING) - cmake_pop_check_state() -endif() - # # Editor modelines - http://www.wireshark.org/tools/modelines.html # diff --git a/configure.ac b/configure.ac index b504b5520c..cfbfb88c5a 100644 --- a/configure.ac +++ b/configure.ac @@ -1515,41 +1515,6 @@ then LIBS="$ac_save_LIBS" fi -# -# Check whether GLib's printf supports thousands grouping. (This might -# be different from the system's printf since GLib can optionally use -# its own printf implementation.) -# -AC_CACHE_CHECK([whether GLib supports POSIX/XSI thousands grouping], - [ac_cv_glib_supports_printf_grouping], [ -ac_save_CFLAGS="$CFLAGS" -ac_save_LIBS="$LIBS" -CFLAGS="$WS_CFLAGS $GLIB_CFLAGS $CFLAGS" -LIBS="$LIBS $GLIB_LIBS" -AC_TRY_RUN([ -#include -#include -#include -#include - -int -main () -{ - gchar *str; - setlocale(LC_ALL, "en_US.UTF-8"); - str = g_strdup_printf("%'u", 123456); - return (strcmp (str, "123,456") != 0); -} -], ac_cv_glib_supports_printf_grouping=yes, ac_cv_glib_supports_printf_grouping=no, - [echo $ac_n "cross compiling; playing it safe... $ac_c" - ac_cv_glib_supports_printf_grouping=no]) -CFLAGS="$ac_save_CFLAGS" -LIBS="$ac_save_LIBS" -]) -if test "$ac_cv_glib_supports_printf_grouping" = yes ; then - AC_DEFINE(HAVE_GLIB_PRINTF_GROUPING, 1, [Define if GLib's printf functions support thousands grouping.]) -fi - AC_SUBST(wireshark_bin) AC_SUBST(wireshark_man) AC_SUBST(wireshark_SUBDIRS) diff --git a/wsutil/str_util.c b/wsutil/str_util.c index 8763666f9a..e0e8531d9d 100644 --- a/wsutil/str_util.c +++ b/wsutil/str_util.c @@ -113,11 +113,21 @@ isdigit_string(guchar *str) #define FORMAT_SIZE_UNIT_MASK 0x00ff #define FORMAT_SIZE_PFX_MASK 0xff00 -#ifdef HAVE_GLIB_PRINTF_GROUPING -#define GROUP_FLAG "'" -#else -#define GROUP_FLAG "" -#endif +static const char *thousands_grouping_fmt = NULL; + +DIAG_OFF(format) +static void test_printf_thousands_grouping(void) { + /* test whether g_printf works with "'" flag character */ + gchar *str = g_strdup_printf("%'d", 22); + if (g_strcmp0(str, "22") == 0) { + thousands_grouping_fmt = "%'"G_GINT64_MODIFIER"d"; + } else { + /* Don't use */ + thousands_grouping_fmt = "%"G_GINT64_MODIFIER"d"; + } + g_free(str); +} +DIAG_ON(format) /* Given a size, return its value in a human-readable format */ /* This doesn't handle fractional values. We might want to make size a double. */ @@ -128,28 +138,34 @@ format_size(gint64 size, format_size_flags_e flags) int power = 1000; int pfx_off = 0; gboolean is_small = FALSE; - static const gchar *prefix[] = {"T", "G", "M", "k", "Ti", "Gi", "Mi", "Ki"}; + static const gchar *prefix[] = {" T", " G", " M", " k", " Ti", " Gi", " Mi", " Ki"}; gchar *ret_val; + if (thousands_grouping_fmt == NULL) + test_printf_thousands_grouping(); + if ((flags & FORMAT_SIZE_PFX_MASK) == format_size_prefix_iec) { pfx_off = 4; power = 1024; } -DIAG_OFF(format) if (size / power / power / power / power >= 10) { - g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d %s", size / power / power / power / power, prefix[pfx_off]); + g_string_printf(human_str, thousands_grouping_fmt, size / power / power / power / power); + g_string_append(human_str, prefix[pfx_off]); } else if (size / power / power / power >= 10) { - g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d %s", size / power / power / power, prefix[pfx_off+1]); + g_string_printf(human_str, thousands_grouping_fmt, size / power / power / power); + g_string_append(human_str, prefix[pfx_off+1]); } else if (size / power / power >= 10) { - g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d %s", size / power / power, prefix[pfx_off+2]); + g_string_printf(human_str, thousands_grouping_fmt, size / power / power); + g_string_append(human_str, prefix[pfx_off+2]); } else if (size / power >= 10) { - g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d %s", size / power, prefix[pfx_off+3]); + g_string_printf(human_str, thousands_grouping_fmt, size / power); + g_string_append(human_str, prefix[pfx_off+3]); } else { - g_string_printf(human_str, "%" GROUP_FLAG G_GINT64_MODIFIER "d", size); + g_string_printf(human_str, thousands_grouping_fmt, size); is_small = TRUE; } -DIAG_ON(format) + switch (flags & FORMAT_SIZE_UNIT_MASK) { case format_size_unit_none: