Browse Source

Implementation of auto-depends, based on Idris's start.

Rusty Russell 16 years ago
parent
commit
501b31cddf

+ 4 - 3
tools/ccanlint/Makefile

@@ -10,10 +10,11 @@ CORE_OBJS := tools/ccanlint/ccanlint.o \
 
 OBJS := $(CORE_OBJS) $(TEST_OBJS)
 
-tools/ccanlint/generated-init-tests: $(OBJS)
-	cat $(OBJS:.o=.c) | sed -n 's/^struct ccanlint \([A-Za-z0-9_]*\) = {/{ extern struct ccanlint \1; list_add(\&tests, \&\1.list); }/p' >$@
+# FIXME: write a trivial C program to do this
+tools/ccanlint/generated-init-tests: $(TEST_CFILES)
+	cat $(TEST_CFILES) | grep ^REGISTER_TEST > $@
 
-tools/ccanlint/ccanlint.o: tools/ccanlint/generated-init-tests
+$(TEST_OBJS): tools/ccanlint/generated-init-tests
 
 tools/ccanlint/ccanlint: $(OBJS)
 

+ 49 - 5
tools/ccanlint/ccanlint.c

@@ -19,6 +19,7 @@
 #include "ccanlint.h"
 #include <unistd.h>
 #include <getopt.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,11 +28,7 @@
 
 static unsigned int verbose = 0;
 static LIST_HEAD(tests);
-
-static void init_tests(void)
-{
-#include "generated-init-tests" 
-}
+static LIST_HEAD(finished_tests);
 
 static void usage(const char *name)
 {
@@ -111,6 +108,53 @@ static bool run_test(const struct ccanlint *i,
 	return false;
 }
 
+static void register_test(struct ccanlint *test, ...)
+{
+	va_list ap;
+	struct ccanlint *depends; 
+	struct dependent *dchild;
+
+	list_add(&tests, &test->list);
+	va_start(ap, test);
+	/* Careful: we might have been initialized by a dependent. */
+	if (test->dependencies.n.next == NULL)
+		list_head_init(&test->dependencies);
+
+	//dependant(s) args (if any), last one is NULL
+	while ((depends = va_arg(ap, struct ccanlint *)) != NULL) {
+		dchild = malloc(sizeof(*dchild));
+		dchild->dependent = test;
+		/* The thing we depend on might not be initialized yet! */
+		if (depends->dependencies.n.next == NULL)
+			list_head_init(&depends->dependencies);
+		list_add_tail(&depends->dependencies, &dchild->node);
+		test->num_depends++;
+	}
+	va_end(ap);
+}
+
+static void init_tests(void)
+{
+	const struct ccanlint *i;
+
+#undef REGISTER_TEST
+#define REGISTER_TEST(name, ...) register_test(&name, __VA_ARGS__)
+#include "generated-init-tests"
+
+	if (!verbose)
+		return;
+
+	list_for_each(&tests, i, list) {
+		printf("%s depends on %u others\n", i->name, i->num_depends);
+		if (!list_empty(&i->dependencies)) {
+			const struct dependent *d;
+			printf("These depend on us:\n");
+			list_for_each(&i->dependencies, d, node)
+				printf("\t%s\n", d->dependent->name);
+		}
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	int c;

+ 19 - 4
tools/ccanlint/ccanlint.h

@@ -4,6 +4,12 @@
 #include <stdbool.h>
 #include "../doc_extract.h"
 
+#define REGISTER_TEST(name, ...) extern struct ccanlint name
+#include "generated-init-tests"
+#undef REGISTER_TEST
+
+#define REGISTER_TEST(name, ...) 
+
 struct manifest {
 	char *basename;
 	struct ccan_file *info_file;
@@ -44,6 +50,12 @@ struct ccanlint {
 
 	/* Can we do something about it? (NULL if not) */
 	void (*handle)(struct manifest *m, void *check_result);
+
+	/* Internal use fields: */
+	/* Who depends on us? */
+	struct list_head dependencies;
+	/* How many things do we (still) depend on? */
+	unsigned int num_depends;
 };
 
 /* Ask the user a yes/no question: the answer is NO if there's an error. */
@@ -134,10 +146,13 @@ char *report_on_lines(struct list_head *files,
 		      char *(*report)(const char *),
 		      char *sofar);
 
-/* The critical tests which mean fail if they don't pass. */
-extern struct ccanlint no_info;
-extern struct ccanlint has_main_header;
-
 /* Normal tests. */
 extern struct ccanlint trailing_whitespace;
+
+/* Dependencies */
+struct dependent {
+	struct list_node node;
+	struct ccanlint *dependent;
+};
+
 #endif /* CCAN_LINT_H */

+ 2 - 0
tools/ccanlint/compulsory_tests/has_info.c

@@ -76,3 +76,5 @@ struct ccanlint has_info = {
 	.describe = describe_has_info,
 	.handle = create_info_template,
 };
+
+REGISTER_TEST(has_info, NULL);

+ 2 - 0
tools/ccanlint/compulsory_tests/has_main_header.c

@@ -39,3 +39,5 @@ struct ccanlint has_main_header = {
 	.check = check_has_main_header,
 	.describe = describe_has_main_header,
 };
+
+REGISTER_TEST(has_main_header, NULL);

+ 2 - 0
tools/ccanlint/compulsory_tests/has_tests.c

@@ -128,3 +128,5 @@ struct ccanlint has_tests = {
 	.describe = describe_has_tests,
 	.handle = handle_no_tests,
 };
+
+REGISTER_TEST(has_tests, NULL);

+ 2 - 0
tools/ccanlint/tests/has_info_documentation.c

@@ -128,3 +128,5 @@ struct ccanlint has_info_documentation = {
 	.check = check_has_info_documentation,
 	.describe = describe_has_info_documentation,
 };
+
+REGISTER_TEST(has_info_documentation, NULL);

+ 2 - 0
tools/ccanlint/tests/idempotent.c

@@ -137,3 +137,5 @@ struct ccanlint idempotent = {
 	.check = check_idempotent,
 	.describe = describe_idempotent,
 };
+
+REGISTER_TEST(idempotent, &trailing_whitespace, NULL);

+ 3 - 0
tools/ccanlint/tests/trailing_whitespace.c

@@ -45,3 +45,6 @@ struct ccanlint trailing_whitespace = {
 	.check = check_trailing_whitespace,
 	.describe = describe_trailing_whitespace,
 };
+
+
+REGISTER_TEST(trailing_whitespace, NULL);