Browse Source

Idris' dependency work.

Rusty Russell 16 years ago
parent
commit
822bce8835
1 changed files with 60 additions and 16 deletions
  1. 60 16
      tools/ccanlint/ccanlint.c

+ 60 - 16
tools/ccanlint/ccanlint.c

@@ -1,6 +1,6 @@
 /*
 /*
  * ccanlint: assorted checks and advice for a ccan package
  * ccanlint: assorted checks and advice for a ccan package
- * Copyright (C) 2008 Rusty Russell
+ * Copyright (C) 2008 Rusty Russell, Idris Soule
  *
  *
  * This program is free software; you can redistribute it and/or modify it
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
  * under the terms of the GNU General Public License as published by the Free
@@ -27,7 +27,8 @@
 #include <ctype.h>
 #include <ctype.h>
 
 
 static unsigned int verbose = 0;
 static unsigned int verbose = 0;
-static LIST_HEAD(tests);
+static LIST_HEAD(compulsory_tests);
+static LIST_HEAD(normal_tests);
 static LIST_HEAD(finished_tests);
 static LIST_HEAD(finished_tests);
 
 
 static void usage(const char *name)
 static void usage(const char *name)
@@ -64,7 +65,7 @@ bool ask(const char *question)
 		&& toupper(reply[0]) == 'Y';
 		&& toupper(reply[0]) == 'Y';
 }
 }
 
 
-static bool run_test(const struct ccanlint *i,
+static bool run_test(struct ccanlint *i,
 		     bool summary,
 		     bool summary,
 		     unsigned int *score,
 		     unsigned int *score,
 		     unsigned int *total_score,
 		     unsigned int *total_score,
@@ -72,16 +73,22 @@ static bool run_test(const struct ccanlint *i,
 {
 {
 	void *result;
 	void *result;
 	unsigned int this_score;
 	unsigned int this_score;
+	const struct dependent *d;
 
 
 	if (i->total_score)
 	if (i->total_score)
 		*total_score += i->total_score;
 		*total_score += i->total_score;
-
+	//one less test to run through
+	list_for_each(&i->dependencies, d, node)
+		d->dependent->num_depends--;
 	result = i->check(m);
 	result = i->check(m);
 	if (!result) {
 	if (!result) {
 		if (verbose)
 		if (verbose)
 			printf("  %s: OK\n", i->name);
 			printf("  %s: OK\n", i->name);
 		if (i->total_score)
 		if (i->total_score)
 			*score += i->total_score;
 			*score += i->total_score;
+
+		list_del(&i->list);
+		list_add_tail(&finished_tests, &i->list);
 		return true;
 		return true;
 	}
 	}
 
 
@@ -97,6 +104,8 @@ static bool run_test(const struct ccanlint *i,
 
 
 		if (verbose)
 		if (verbose)
 			indent_print(i->describe(m, result));
 			indent_print(i->describe(m, result));
+		list_del(&i->list);
+		list_add_tail(&finished_tests, &i->list);
 		return false;
 		return false;
 	}
 	}
 
 
@@ -104,23 +113,28 @@ static bool run_test(const struct ccanlint *i,
 
 
 	if (i->handle)
 	if (i->handle)
 		i->handle(m, result);
 		i->handle(m, result);
-
+	list_del(&i->list);
+	list_add_tail(&finished_tests, &i->list);
 	return false;
 	return false;
 }
 }
 
 
 static void register_test(struct ccanlint *test, ...)
 static void register_test(struct ccanlint *test, ...)
 {
 {
 	va_list ap;
 	va_list ap;
-	struct ccanlint *depends; 
+	struct ccanlint *depends;
 	struct dependent *dchild;
 	struct dependent *dchild;
 
 
-	list_add(&tests, &test->list);
+	if (!test->total_score)
+		list_add(&compulsory_tests, &test->list);
+	else
+		list_add(&normal_tests, &test->list);
+
 	va_start(ap, test);
 	va_start(ap, test);
 	/* Careful: we might have been initialized by a dependent. */
 	/* Careful: we might have been initialized by a dependent. */
 	if (test->dependencies.n.next == NULL)
 	if (test->dependencies.n.next == NULL)
 		list_head_init(&test->dependencies);
 		list_head_init(&test->dependencies);
 
 
-	//dependant(s) args (if any), last one is NULL
+	//dependent(s) args (if any), last one is NULL
 	while ((depends = va_arg(ap, struct ccanlint *)) != NULL) {
 	while ((depends = va_arg(ap, struct ccanlint *)) != NULL) {
 		dchild = malloc(sizeof(*dchild));
 		dchild = malloc(sizeof(*dchild));
 		dchild->dependent = test;
 		dchild->dependent = test;
@@ -133,6 +147,23 @@ static void register_test(struct ccanlint *test, ...)
 	va_end(ap);
 	va_end(ap);
 }
 }
 
 
+/**
+ * get_next_test - retrieves the next test to be processed
+ **/
+static inline struct ccanlint *get_next_test(struct list_head *test)
+{
+	struct ccanlint *i;
+
+	if (list_empty(test))
+		return NULL;
+
+	list_for_each(test, i, list) {
+		if (i->num_depends == 0)
+			return i;
+	}
+	errx(1, "Can't make process; test dependency cycle");
+}
+
 static void init_tests(void)
 static void init_tests(void)
 {
 {
 	const struct ccanlint *i;
 	const struct ccanlint *i;
@@ -144,7 +175,19 @@ static void init_tests(void)
 	if (!verbose)
 	if (!verbose)
 		return;
 		return;
 
 
-	list_for_each(&tests, i, list) {
+	printf("\nCompulsory Tests\n");
+	list_for_each(&compulsory_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);
+		}
+	}
+
+	printf("\nNormal Tests\n");
+	list_for_each(&normal_tests, i, list) {
 		printf("%s depends on %u others\n", i->name, i->num_depends);
 		printf("%s depends on %u others\n", i->name, i->num_depends);
 		if (!list_empty(&i->dependencies)) {
 		if (!list_empty(&i->dependencies)) {
 			const struct dependent *d;
 			const struct dependent *d;
@@ -161,7 +204,7 @@ int main(int argc, char *argv[])
 	bool summary = false;
 	bool summary = false;
 	unsigned int score, total_score;
 	unsigned int score, total_score;
 	struct manifest *m;
 	struct manifest *m;
-	const struct ccanlint *i;
+	struct ccanlint *i;
 
 
 	/* I'd love to use long options, but that's not standard. */
 	/* I'd love to use long options, but that's not standard. */
 	/* FIXME: getopt_long ccan package? */
 	/* FIXME: getopt_long ccan package? */
@@ -192,18 +235,19 @@ int main(int argc, char *argv[])
 	/* If you don't pass the compulsory tests, you don't even get a score */
 	/* If you don't pass the compulsory tests, you don't even get a score */
 	if (verbose)
 	if (verbose)
 		printf("Compulsory tests:\n");
 		printf("Compulsory tests:\n");
-	list_for_each(&tests, i, list)
-		if (!i->total_score)
-			if (!run_test(i, summary, &score, &total_score, m))
-				exit(1);
+
+	while ((i = get_next_test(&compulsory_tests)) != NULL) {
+		if (!run_test(i, summary, &score, &total_score, m))
+			exit(1);
+	}
 
 
 	if (verbose)
 	if (verbose)
 		printf("\nNormal tests:\n");
 		printf("\nNormal tests:\n");
 	score = total_score = 0;
 	score = total_score = 0;
-	list_for_each(&tests, i, list)
+	while ((i = get_next_test(&normal_tests)) != NULL) {
 		if (i->total_score)
 		if (i->total_score)
 			run_test(i, summary, &score, &total_score, m);
 			run_test(i, summary, &score, &total_score, m);
-
+	}
 	printf("Total score: %u/%u\n", score, total_score);
 	printf("Total score: %u/%u\n", score, total_score);
 
 
 	return 0;
 	return 0;