+ *running_score += score->score;
+ *running_total += score->total;
+
+ if (!score->pass) {
+ /* Skip any tests which depend on this one. */
+ dgraph_traverse_from(&i->node, skip_node, "dependency failed");
+ }
+ dgraph_clear_node(&i->node);
+ return score->pass;
+}
+
+static void register_test(struct ccanlint *test)
+{
+ if (!strmap_add(&tests, test->key, test))
+ err(1, "Adding test %s", test->key);
+ test->options = talloc_array(NULL, char *, 1);
+ test->options[0] = NULL;
+ dgraph_init_node(&test->node);
+}
+
+static bool get_test(const char *member, struct ccanlint *i,
+ struct ccanlint **ret)
+{
+ if (tlist_empty(&i->node.edge[DGRAPH_TO])) {
+ *ret = i;
+ return false;
+ }
+ return true;
+}
+
+/**
+ * get_next_test - retrieves the next test to be processed
+ **/
+static inline struct ccanlint *get_next_test(void)
+{
+ struct ccanlint *i = NULL;
+
+ strmap_iterate(&tests, get_test, &i);
+ if (i)
+ return i;
+
+ if (strmap_empty(&tests))
+ return NULL;
+
+ errx(1, "Can't make process; test dependency cycle");
+}
+
+static struct ccanlint *find_test(const char *key)
+{
+ return strmap_get(&tests, key);
+}
+
+bool is_excluded(const char *name)
+{
+ return btree_lookup(cmdline_exclude, name) != NULL
+ || btree_lookup(info_exclude, name) != NULL
+ || find_test(name)->skip != NULL;
+}
+
+static bool reset_deps(const char *member, struct ccanlint *c, void *unused)
+{
+ char **deps = strsplit(NULL, c->needs, " ");
+ unsigned int i;
+
+ c->skip = NULL;
+ c->skip_fail = false;
+ for (i = 0; deps[i]; i++) {
+ struct ccanlint *dep;
+
+ dep = find_test(deps[i]);
+ if (!dep)
+ errx(1, "BUG: unknown dep '%s' for %s",
+ deps[i], c->key);
+ dgraph_add_edge(&dep->node, &c->node);
+ }
+ talloc_free(deps);
+ return true;
+}
+
+static bool check_names(const char *member, struct ccanlint *c,
+ struct ccanlint_map *names)
+{
+ if (!strmap_add(names, c->name, c))
+ err(1, "Duplicate name %s", c->name);
+ return true;
+}
+
+#undef REGISTER_TEST
+#define REGISTER_TEST(name, ...) extern struct ccanlint name
+#include "generated-testlist"
+
+static void init_tests(void)
+{
+ struct ccanlint_map names;
+
+ strmap_init(&tests);
+
+#undef REGISTER_TEST
+#define REGISTER_TEST(name) register_test(&name)
+#include "generated-testlist"
+
+ strmap_iterate(&tests, reset_deps, NULL);
+
+ /* Check for duplicate names. */
+ strmap_init(&names);
+ strmap_iterate(&tests, check_names, &names);
+ strmap_clear(&names);
+}
+
+static bool print_deps(const char *member, struct ccanlint *c, void *unused)
+{
+ if (!tlist_empty(&c->node.edge[DGRAPH_FROM])) {
+ struct dgraph_edge *e;
+
+ printf("These depend on %s:\n", c->key);
+ dgraph_for_each_edge(&c->node, e, DGRAPH_FROM) {
+ struct ccanlint *to = container_of(e->n[DGRAPH_TO],
+ struct ccanlint,
+ node);
+ printf("\t%s\n", to->key);