Implementation of auto-depends, based on Idris's start.
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 5 Jun 2009 07:32:24 +0000 (17:02 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 5 Jun 2009 07:32:24 +0000 (17:02 +0930)
tools/ccanlint/Makefile
tools/ccanlint/ccanlint.c
tools/ccanlint/ccanlint.h
tools/ccanlint/compulsory_tests/has_info.c
tools/ccanlint/compulsory_tests/has_main_header.c
tools/ccanlint/compulsory_tests/has_tests.c
tools/ccanlint/tests/has_info_documentation.c
tools/ccanlint/tests/idempotent.c
tools/ccanlint/tests/trailing_whitespace.c

index cd507e5d08d8237ba06b0c138a85c39dd39d25c4..e7c21d6f4bdfa3366860c3f6201ed0d5a224ce05 100644 (file)
@@ -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)
 
index 29ad7c6093164ad5f4e25c21c972e55b6a9874d3..184b8f5a19310ca2a42814acb8e1ba3013e3139a 100644 (file)
@@ -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>
 
 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;
index d704d58d6b9fcbd0ee484badeee4b0ba969bb764..ee12ce04fb81083c228e2ac47604c27ed39e25b8 100644 (file)
@@ -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 */
index ed2d4c813c0c1b7d4a29f9b7de6b79aec59bb043..974967bfa2377361a6b984ed9d50c739c996dc8e 100644 (file)
@@ -76,3 +76,5 @@ struct ccanlint has_info = {
        .describe = describe_has_info,
        .handle = create_info_template,
 };
+
+REGISTER_TEST(has_info, NULL);
index 978bfcb60029ca30e9beb6eae47dcab285043f0f..071c7157ba54b29fa7c822f0d5a31ab5fc8e048f 100644 (file)
@@ -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);
index a71a1569be702c609f96551a2cdc3e5727e91dd1..662a178147276f59f2560f5ef5096dd181580b5f 100644 (file)
@@ -128,3 +128,5 @@ struct ccanlint has_tests = {
        .describe = describe_has_tests,
        .handle = handle_no_tests,
 };
+
+REGISTER_TEST(has_tests, NULL);
index 8a506aba85253596975462dd1532038d30d6e79c..9233e2883d7229acb3e132659cf36fd00339a5b6 100644 (file)
@@ -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);
index 0aa7d8b3ae22c5ad741187bb3b7905abefe5e63b..924f5bea3c7d6b53c424ba7cff6fafe7897aadf2 100644 (file)
@@ -137,3 +137,5 @@ struct ccanlint idempotent = {
        .check = check_idempotent,
        .describe = describe_idempotent,
 };
+
+REGISTER_TEST(idempotent, &trailing_whitespace, NULL);
index f522d316e5c406742dc0e344be450114d83ca5f1..e5d2102ec295c389db2a6627de5a7ce762c3c9de 100644 (file)
@@ -45,3 +45,6 @@ struct ccanlint trailing_whitespace = {
        .check = check_trailing_whitespace,
        .describe = describe_trailing_whitespace,
 };
+
+
+REGISTER_TEST(trailing_whitespace, NULL);