Browse Source

ccanlint: add ccanlint section to _info

This supersedes the previous Fails: section, into a more general set of
lines of form:

      <testname> <option>...

With the special <option> "FAIL" to mean we know we fail this test.
We accept options to valgrind-tests; in particular tdb2 wants
--partial-loads-ok=yes passed to valgrind.
Rusty Russell 15 years ago
parent
commit
a791eb1e4c

+ 3 - 1
ccan/tdb/_info

@@ -65,7 +65,9 @@
  *
  *
  * License: LGPLv3 (or later)
  * License: LGPLv3 (or later)
  *
  *
- * Fails: valgrind-tests // valgrind breaks fcntl locks.
+ * Ccanlint:
+ *	// valgrind breaks fcntl locks.
+ *	valgrind-tests FAIL
  */
  */
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {

+ 3 - 2
ccan/tdb2/_info

@@ -64,8 +64,9 @@
  *
  *
  * License: LGPLv3 (or later)
  * License: LGPLv3 (or later)
  *
  *
- * Fails:
- *	valgrind-tests // hash needs --partial-loads-ok=yes.
+ * Ccanlint:
+ *	// hash fails because it accesses data in 4 byte quantities for speed.
+ *	valgrind-tests --partial-loads-ok=yes
  */
  */
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {

+ 50 - 11
tools/ccanlint/ccanlint.c

@@ -344,24 +344,64 @@ static char *list_tests(void *arg)
 	exit(0);
 	exit(0);
 }
 }
 
 
-static char *strip(const void *ctx, const char *line)
+/* Remove empty lines. */
+static char **collapse(char **lines, unsigned int *nump)
 {
 {
-	line += strcspn(line, IDENT_CHARS "-");
-	return talloc_strndup(ctx, line, strspn(line, IDENT_CHARS "-"));
+	unsigned int i, j;
+	for (i = j = 0; lines[i]; i++) {
+		if (lines[i][0])
+			lines[j++] = lines[i];
+	}
+	if (nump)
+		*nump = j;
+	return lines;
 }
 }
 
 
-static void add_info_fails(struct ccan_file *info)
+static void add_info_options(struct ccan_file *info, bool mark_fails)
 {
 {
 	struct doc_section *d;
 	struct doc_section *d;
 	unsigned int i;
 	unsigned int i;
+	struct ccanlint *test;
 
 
 	list_for_each(get_ccan_file_docs(info), d, list) {
 	list_for_each(get_ccan_file_docs(info), d, list) {
-		if (!streq(d->type, "fails"))
+		if (!streq(d->type, "ccanlint"))
 			continue;
 			continue;
 
 
-		for (i = 0; i < d->num_lines; i++)
-			btree_insert(info_exclude, strip(info, d->lines[i]));
-		break;
+		for (i = 0; i < d->num_lines; i++) {
+			char **words = collapse(strsplit(d, d->lines[i], " \t",
+							 NULL), NULL);
+			if (!words[0])
+				continue;
+
+			if (strncmp(words[0], "//", 2) == 0)
+				continue;
+
+			test = find_test(words[0]);
+			if (!test) {
+				warnx("%s: unknown ccanlint test '%s'",
+				      info->fullname, words[0]);
+				continue;
+			}
+
+			if (!words[1]) {
+				warnx("%s: no argument to test '%s'",
+				      info->fullname, words[0]);
+				continue;
+			}
+
+			/* Known failure? */
+			if (strcasecmp(words[1], "FAIL") == 0) {
+				if (mark_fails)
+					btree_insert(info_exclude, words[0]);
+			} else {
+				if (!test->takes_options)
+					warnx("%s: %s doesn't take options",
+					      info->fullname, words[0]);
+				/* Copy line exactly into options. */
+				test->options = strstr(d->lines[i], words[0])
+					+ strlen(words[0]);
+			}
+		}
 	}
 	}
 }
 }
 
 
@@ -469,9 +509,8 @@ int main(int argc, char *argv[])
 		}
 		}
 	}
 	}
 
 
-	/* --target overrides _info excludes */
-	if (!target)
-		add_info_fails(m->info_file);
+	/* --target overrides known FAIL from _info */
+	add_info_options(m->info_file, !target);
 
 
 	while ((i = get_next_test(&normal_tests)) != NULL)
 	while ((i = get_next_test(&normal_tests)) != NULL)
 		run_test(i, summary, &score, &total_score, m);
 		run_test(i, summary, &score, &total_score, m);

+ 5 - 0
tools/ccanlint/ccanlint.h

@@ -82,6 +82,11 @@ struct ccanlint {
 	/* Can we do something about it? (NULL if not) */
 	/* Can we do something about it? (NULL if not) */
 	void (*handle)(struct manifest *m, struct score *score);
 	void (*handle)(struct manifest *m, struct score *score);
 
 
+	/* Options from _info. */
+	char *options;
+	/* If not set, we'll give an error if they try to set options. */
+	bool takes_options;
+
 	/* Internal use fields: */
 	/* Internal use fields: */
 	/* Who depends on us? */
 	/* Who depends on us? */
 	struct list_head dependencies;
 	struct list_head dependencies;

+ 5 - 3
tools/ccanlint/tests/run_tests_valgrind.c

@@ -42,11 +42,12 @@ static void do_run_tests_vg(struct manifest *m,
 		list_for_each(list, i, list) {
 		list_for_each(list, i, list) {
 			score->total++;
 			score->total++;
 			if (run_command(score, timeleft, &cmdout,
 			if (run_command(score, timeleft, &cmdout,
-					"valgrind -q --error-exitcode=100 %s",
+					"valgrind -q --error-exitcode=100%s %s",
+					run_tests_vg.options ?
+					run_tests_vg.options : "",
 					i->compiled)) {
 					i->compiled)) {
 				score->score++;
 				score->score++;
 			} else {
 			} else {
-				score->error = "Running under valgrind";
 				score_file_error(score, i, 0, cmdout);
 				score_file_error(score, i, 0, cmdout);
 			}
 			}
 		}
 		}
@@ -79,7 +80,8 @@ struct ccanlint run_tests_vg = {
 	.name = "Module's run and api tests succeed under valgrind",
 	.name = "Module's run and api tests succeed under valgrind",
 	.can_run = can_run_vg,
 	.can_run = can_run_vg,
 	.check = do_run_tests_vg,
 	.check = do_run_tests_vg,
-	.handle = run_under_debugger_vg
+	.handle = run_under_debugger_vg,
+	.takes_options = true
 };
 };
 
 
 REGISTER_TEST(run_tests_vg, &run_tests, NULL);
 REGISTER_TEST(run_tests_vg, &run_tests, NULL);