+/*
+ * Returns the index at which the paths differ.
+ * If the value returned equals len, it means the paths are identical
+ * from index 0 to len-1.
+ */
+static int compare_paths(GArray *a, GArray *b, int len)
+{
+ int i;
+
+ assert(len <= a->len);
+ assert(len <= b->len);
+
+ for (i = 0; i < len; i++) {
+ GQuark qa, qb;
+
+ qa = g_array_index(a, GQuark, i);
+ qb = g_array_index(b, GQuark, i);
+ if (qa != qb)
+ return i;
+ }
+ return i;
+}
+
+static int is_path_child_of(GArray *path, GArray *maybe_parent)
+{
+ int i, ret;
+
+ if (babeltrace_debug) {
+ int need_dot = 0;
+
+ printf_debug("Is path \"");
+ for (i = 0; i < path->len; need_dot = 1, i++)
+ printf("%s%s", need_dot ? "." : "",
+ g_quark_to_string(g_array_index(path, GQuark, i)));
+ need_dot = 0;
+ printf("\" child of \"");
+ for (i = 0; i < maybe_parent->len; need_dot = 1, i++)
+ printf("%s%s", need_dot ? "." : "",
+ g_quark_to_string(g_array_index(maybe_parent, GQuark, i)));
+ printf("\" ? ");
+ }
+
+ if (path->len <= maybe_parent->len) {
+ ret = 0;
+ goto end;
+ }
+ if (compare_paths(path, maybe_parent, maybe_parent->len)
+ == maybe_parent->len)
+ ret = 1;
+ else
+ ret = 0;
+end:
+ if (babeltrace_debug)
+ printf("%s\n", ret ? "Yes" : "No");
+ return ret;
+}
+
+static struct definition_scope *
+ get_definition_scope(struct definition *definition)
+{
+ return definition->scope;
+}
+
+/*
+ * OK, here is the fun. We want to lookup a field that is:
+ * - either in the same dynamic scope:
+ * - either in the current scope, but prior to the current field.
+ * - or in a parent scope (or parent of parent ...) still in a field
+ * prior to the current field position within the parents.
+ * - or in a different dynamic scope:
+ * - either in a upper dynamic scope (walk down a targeted scope from
+ * the dynamic scope root)
+ * - or in a lower dynamic scope (failure)
+ * The dynamic scope roots are linked together, so we can access the
+ * parent dynamic scope from the child dynamic scope by walking up to
+ * the parent.
+ * If we cannot find such a field that is prior to our current path, we
+ * return NULL.
+ *
+ * cur_path: the path leading to the variant definition.
+ * lookup_path: the path leading to the enum we want to look for.
+ * scope: the definition scope containing the variant definition.
+ */