pkg: Make ordering of output from print_package_list() deterministic

The iteration order of GHashTable changed in GLib 2.59, which broke the
check-print-options test, as it relied on a fixed output order from the
--list-all argument to pkg-config.

Fix that by making print_package_list() output in alphabetical order by
Package.key; and update the test to match. This should work with older
and newer versions of GLib.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2019-03-11 12:32:44 +00:00
parent 2dd2b19944
commit 2ad16fa7ac
2 changed files with 41 additions and 24 deletions

View file

@ -35,9 +35,9 @@ RESULT="private-dep >= 1"
run_test --print-requires-private requires-test run_test --print-requires-private requires-test
# --list-all, limit to a subdirectory # --list-all, limit to a subdirectory
RESULT="sub1 Subdirectory package 1 - Test package 1 for subdirectory RESULT="broken Broken package - Module with broken .pc file
sub2 Subdirectory package 2 - Test package 2 for subdirectory sub1 Subdirectory package 1 - Test package 1 for subdirectory
broken Broken package - Module with broken .pc file" sub2 Subdirectory package 2 - Test package 2 for subdirectory"
PKG_CONFIG_LIBDIR="$srcdir/sub" run_test --list-all PKG_CONFIG_LIBDIR="$srcdir/sub" run_test --list-all
# Check handling when multiple incompatible options are set # Check handling when multiple incompatible options are set

59
pkg.c
View file

@ -1160,38 +1160,55 @@ comparison_to_str (ComparisonType comparison)
return "???"; return "???";
} }
static void static gint
max_len_foreach (gpointer key, gpointer value, gpointer data) packages_sort_cb (gconstpointer a,
gconstpointer b)
{ {
int *mlen = data; const Package *package_a = *((Package **) a);
const Package *package_b = *((Package **) b);
*mlen = MAX (*mlen, strlen (key)); return g_strcmp0 (package_a->key, package_b->key);
}
static void
packages_foreach (gpointer key, gpointer value, gpointer data)
{
Package *pkg = value;
char *pad;
pad = g_strnfill (GPOINTER_TO_INT (data) - strlen (pkg->key), ' ');
printf ("%s%s%s - %s\n",
pkg->key, pad, pkg->name, pkg->description);
g_free (pad);
} }
void void
print_package_list (void) print_package_list (void)
{ {
int mlen = 0; gsize mlen = 0;
GPtrArray *packages_array = NULL;
GHashTableIter iter;
gpointer key, value;
guint i;
ignore_requires = TRUE; ignore_requires = TRUE;
ignore_requires_private = TRUE; ignore_requires_private = TRUE;
g_hash_table_foreach (packages, max_len_foreach, &mlen); /* Add the packages to a pointer array and sort by pkg->key first, to give
g_hash_table_foreach (packages, packages_foreach, GINT_TO_POINTER (mlen + 1)); * deterministic output. While doing that, work out the maximum key length
* so we can pad the output correctly. */
packages_array = g_ptr_array_sized_new (g_hash_table_size (packages));
g_hash_table_iter_init (&iter, packages);
while (g_hash_table_iter_next (&iter, &key, &value))
{
g_ptr_array_add (packages_array, value);
mlen = MAX (mlen, strlen (key));
}
g_ptr_array_sort (packages_array, packages_sort_cb);
for (i = 0; i < packages_array->len; i++)
{
Package *pkg = g_ptr_array_index (packages_array, i);
char *pad;
pad = g_strnfill (mlen + 1 - strlen (pkg->key), ' ');
printf ("%s%s%s - %s\n",
pkg->key, pad, pkg->name, pkg->description);
g_free (pad);
}
g_ptr_array_free (packages_array, TRUE);
} }
void void