Merge branch 'pattern-coalesce' into 'master'

gvariant-parser: Fix pattern coalesce of M and *

See merge request GNOME/glib!694
This commit is contained in:
Philip Withnall 2019-03-15 12:31:03 +00:00
commit c561870359
2 changed files with 19 additions and 18 deletions

View File

@ -418,6 +418,8 @@ pattern_copy (gchar **out,
while (brackets); while (brackets);
} }
/* Returns the most general pattern that is subpattern of left and subpattern
* of right, or NULL if there is no such pattern. */
static gchar * static gchar *
pattern_coalesce (const gchar *left, pattern_coalesce (const gchar *left,
const gchar *right) const gchar *right)
@ -458,7 +460,7 @@ pattern_coalesce (const gchar *left,
*out++ = *(*the_other)++; *out++ = *(*the_other)++;
} }
else if (**one == 'M' && **the_other != 'm') else if (**one == 'M' && **the_other != 'm' && **the_other != '*')
{ {
(*one)++; (*one)++;
} }
@ -672,18 +674,7 @@ ast_array_get_pattern (AST **array,
gint i; gint i;
/* Find the pattern which applies to all children in the array, by l-folding a /* Find the pattern which applies to all children in the array, by l-folding a
* coalesce operation. This will not always work: for example, the GVariant: * coalesce operation.
* [[0], [], [nothing]]
* has patterns:
* MaMN, Ma*, Mam*
* which pairwise coalesce as:
* MaMN + Ma* = MaN
* MaN + Mam* = (doesnt coalesce)
*
* However, the pattern MamN coalesces with all three child patterns. Finding
* this pattern would require trying all O(n_items^2) pairs, though, which is
* expensive. Just let it fail, and require the user to provide type
* annotations.
*/ */
pattern = ast_get_pattern (array[0], error); pattern = ast_get_pattern (array[0], error);
@ -719,10 +710,10 @@ ast_array_get_pattern (AST **array,
gchar *tmp2; gchar *tmp2;
gchar *m; gchar *m;
/* if 'j' reaches 'i' then we failed to find the pair, which can /* if 'j' reaches 'i' then we didn't find the pair that failed
* happen due to only trying pairwise coalesces in order rather * to coalesce. This shouldn't happen (see above), but just in
* than between all pairs (see above). so just report an error * case report an error:
* for i. */ */
if (j >= i) if (j >= i)
{ {
ast_set_error (array[i], error, NULL, ast_set_error (array[i], error, NULL,

View File

@ -3899,6 +3899,17 @@ test_parses (void)
g_free (printed); g_free (printed);
} }
/* pattern coalese of `MN` and `*` is `MN` */
{
GVariant *value = NULL;
GError *error = NULL;
value = g_variant_parse (NULL, "[[0], [], [nothing]]", NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (g_variant_get_type_string (value), ==, "aami");
g_variant_unref (value);
}
#ifndef _MSC_VER #ifndef _MSC_VER
/* inf/nan strings are C99 features which Visual C++ does not support */ /* inf/nan strings are C99 features which Visual C++ does not support */
/* inf/nan mini test */ /* inf/nan mini test */
@ -3943,7 +3954,6 @@ test_parse_failures (void)
"[4, 5, '']", "1-2,7-9:", "common type", "[4, 5, '']", "1-2,7-9:", "common type",
"[[4], [], ['']]", "1-4,10-14:", "common type", "[[4], [], ['']]", "1-4,10-14:", "common type",
"[[], [4], ['']]", "5-8,10-14:", "common type", "[[], [4], ['']]", "5-8,10-14:", "common type",
"[[0], [], [nothing]]", "10-19:", "common type",
"just", "4:", "expected value", "just", "4:", "expected value",
"nothing", "0-7:", "unable to infer", "nothing", "0-7:", "unable to infer",
"just [4, '']", "6-7,9-11:", "common type", "just [4, '']", "6-7,9-11:", "common type",