gstrfuncs: Add g_strv_equal()

This is a utility function which I find myself writing in a number of
places. Mostly in unit tests.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2018-11-30 10:49:48 +00:00
parent b4479d97d5
commit a67eadbdc3
5 changed files with 69 additions and 16 deletions

View File

@ -1544,6 +1544,7 @@ g_strjoinv
GStrv GStrv
g_strv_length g_strv_length
g_strv_contains g_strv_contains
g_strv_equal
<SUBSECTION> <SUBSECTION>
g_strerror g_strerror

View File

@ -3181,6 +3181,40 @@ g_strv_contains (const gchar * const *strv,
return FALSE; return FALSE;
} }
/**
* g_strv_equal:
* @strv1: a %NULL-terminated array of strings
* @strv2: another %NULL-terminated array of strings
*
* Checks if @strv1 and @strv2 contain exactly the same elements in exactly the
* same order. Elements are compared using g_str_equal(). To match independently
* of order, sort the arrays first (using g_qsort_with_data() or similar).
*
* Two empty arrays are considered equal. Neither @strv1 not @strv2 may be
* %NULL.
*
* Returns: %TRUE if @strv1 and @strv2 are equal
* Since: 2.60
*/
gboolean
g_strv_equal (const gchar * const *strv1,
const gchar * const *strv2)
{
g_return_val_if_fail (strv1 != NULL, FALSE);
g_return_val_if_fail (strv2 != NULL, FALSE);
if (strv1 == strv2)
return TRUE;
for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++)
{
if (!g_str_equal (*strv1, *strv2))
return FALSE;
}
return (*strv1 == NULL && *strv2 == NULL);
}
static gboolean static gboolean
str_has_sign (const gchar *str) str_has_sign (const gchar *str)
{ {

View File

@ -307,6 +307,10 @@ GLIB_AVAILABLE_IN_2_44
gboolean g_strv_contains (const gchar * const *strv, gboolean g_strv_contains (const gchar * const *strv,
const gchar *str); const gchar *str);
GLIB_AVAILABLE_IN_2_60
gboolean g_strv_equal (const gchar * const *strv1,
const gchar * const *strv2);
/* Convenience ASCII string to number API */ /* Convenience ASCII string to number API */
/** /**

View File

@ -68,21 +68,6 @@ static CmdlineTest cmdline_tests[] =
{"foo '/bar/summer'\\''09 tours.pdf'", 2, {"foo", "/bar/summer'09 tours.pdf", NULL}, -1} {"foo '/bar/summer'\\''09 tours.pdf'", 2, {"foo", "/bar/summer'09 tours.pdf", NULL}, -1}
}; };
static gboolean
strv_equal (gchar **a, gchar **b)
{
gint i;
if (g_strv_length (a) != g_strv_length (b))
return FALSE;
for (i = 0; a[i]; i++)
if (g_strcmp0 (a[i], b[i]) != 0)
return FALSE;
return TRUE;
}
static void static void
do_cmdline_test (gconstpointer d) do_cmdline_test (gconstpointer d)
{ {
@ -99,7 +84,7 @@ do_cmdline_test (gconstpointer d)
{ {
g_assert (res); g_assert (res);
g_assert_cmpint (argc, ==, test->argc); g_assert_cmpint (argc, ==, test->argc);
g_assert (strv_equal (argv, (gchar **)test->argv)); g_assert (g_strv_equal ((const gchar * const *) argv, (const gchar * const *) test->argv));
g_assert_no_error (err); g_assert_no_error (err);
} }
else else

View File

@ -1507,6 +1507,34 @@ test_strv_contains (void)
g_assert_false (g_strv_contains (strv_empty, "")); g_assert_false (g_strv_contains (strv_empty, ""));
} }
/* Test g_strv_equal() works for various inputs. */
static void
test_strv_equal (void)
{
const gchar *strv_empty[] = { NULL };
const gchar *strv_empty2[] = { NULL };
const gchar *strv_simple[] = { "hello", "you", NULL };
const gchar *strv_simple2[] = { "hello", "you", NULL };
const gchar *strv_simple_reordered[] = { "you", "hello", NULL };
const gchar *strv_simple_superset[] = { "hello", "you", "again", NULL };
const gchar *strv_another[] = { "not", "a", "coded", "message", NULL };
g_assert_true (g_strv_equal (strv_empty, strv_empty));
g_assert_true (g_strv_equal (strv_empty, strv_empty2));
g_assert_true (g_strv_equal (strv_empty2, strv_empty));
g_assert_false (g_strv_equal (strv_empty, strv_simple));
g_assert_false (g_strv_equal (strv_simple, strv_empty));
g_assert_true (g_strv_equal (strv_simple, strv_simple));
g_assert_true (g_strv_equal (strv_simple, strv_simple2));
g_assert_true (g_strv_equal (strv_simple2, strv_simple));
g_assert_false (g_strv_equal (strv_simple, strv_simple_reordered));
g_assert_false (g_strv_equal (strv_simple_reordered, strv_simple));
g_assert_false (g_strv_equal (strv_simple, strv_simple_superset));
g_assert_false (g_strv_equal (strv_simple_superset, strv_simple));
g_assert_false (g_strv_equal (strv_simple, strv_another));
g_assert_false (g_strv_equal (strv_another, strv_simple));
}
typedef enum typedef enum
{ {
SIGNED, SIGNED,
@ -1761,6 +1789,7 @@ main (int argc,
g_test_add_func ("/strfuncs/strup", test_strup); g_test_add_func ("/strfuncs/strup", test_strup);
g_test_add_func ("/strfuncs/transliteration", test_transliteration); g_test_add_func ("/strfuncs/transliteration", test_transliteration);
g_test_add_func ("/strfuncs/strv-contains", test_strv_contains); g_test_add_func ("/strfuncs/strv-contains", test_strv_contains);
g_test_add_func ("/strfuncs/strv-equal", test_strv_equal);
g_test_add_func ("/strfuncs/ascii-string-to-num/usual", test_ascii_string_to_number_usual); g_test_add_func ("/strfuncs/ascii-string-to-num/usual", test_ascii_string_to_number_usual);
g_test_add_func ("/strfuncs/ascii-string-to-num/pathological", test_ascii_string_to_number_pathological); g_test_add_func ("/strfuncs/ascii-string-to-num/pathological", test_ascii_string_to_number_pathological);