diff --git a/glib/gvariant.c b/glib/gvariant.c index ee24ffc34..cd4c21ced 100644 --- a/glib/gvariant.c +++ b/glib/gvariant.c @@ -2226,8 +2226,9 @@ g_variant_print_string (GVariant *value, if (g_variant_n_children (value)) { - gchar *printed_child; - GVariant *element; + const GVariantType *base_type; + guint i, depth; + GVariant *element = NULL; /* Nested maybes: * @@ -2241,19 +2242,36 @@ g_variant_print_string (GVariant *value, * "just" is actually exactly the case where we have a nested * Nothing. * - * Instead of searching for that nested Nothing, we just print - * the contained value into a separate string and see if we - * end up with "nothing" at the end of it. If so, we need to - * add "just" at our level. + * Search for the nested Nothing, to save a lot of recursion if there + * are multiple levels of maybes. */ - element = g_variant_get_child_value (value, 0); - printed_child = g_variant_print (element, FALSE); - g_variant_unref (element); + for (depth = 0, base_type = g_variant_get_type (value); + g_variant_type_is_maybe (base_type); + depth++, base_type = g_variant_type_element (base_type)); - if (g_str_has_suffix (printed_child, "nothing")) - g_string_append (string, "just "); - g_string_append (string, printed_child); - g_free (printed_child); + element = g_variant_ref (value); + for (i = 0; i < depth && element != NULL; i++) + { + GVariant *new_element = g_variant_n_children (element) ? g_variant_get_child_value (element, 0) : NULL; + g_variant_unref (element); + element = g_steal_pointer (&new_element); + } + + if (element == NULL) + { + /* One of the maybes was Nothing, so print out the right number of + * justs. */ + for (; i > 1; i--) + g_string_append (string, "just "); + g_string_append (string, "nothing"); + } + else + { + /* There are no Nothings, so print out the child with no prefixes. */ + g_variant_print_string (element, string, FALSE); + } + + g_clear_pointer (&element, g_variant_unref); } else g_string_append (string, "nothing");