Test g_printf() thousands grouping flag at runtime
authorJoão Valverde <joao.valverde@tecnico.ulisboa.pt>
Mon, 23 Oct 2017 18:00:27 +0000 (19:00 +0100)
committerJoão Valverde <j@v6e.pt>
Tue, 24 Oct 2017 22:00:46 +0000 (22:00 +0000)
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 <j@v6e.pt>
Tested-by: Petri Dish Buildbot
Reviewed-by: João Valverde <j@v6e.pt>
ConfigureChecks.cmake
configure.ac
wsutil/str_util.c

index c4bd431a1a1c5cdae078ab175864dcedad060160..99732f9e7d3ac2d5d54b610a1fd947dcdd6ffffa 100644 (file)
@@ -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 <glib.h>
-               #include <locale.h>
-               #include <stdio.h>
-               #include <string.h>
-
-               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
 #
index b504b5520c4d51681de55f104491df06a91c6d1a..cfbfb88c5a88292918478f3350014b241c889b1c 100644 (file)
@@ -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 <glib.h>
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-
-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)
index 8763666f9abeacf0d2c76067ce733187f8c5653a..e0e8531d9daac7a02a4aabd76427bcb815729c9f 100644 (file)
@@ -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: