Browse Source

tools: Consolidate gcov handling

At the moment, invocation of the 'gcov' tool for coverage analysis
from ccanlint is put directly into the tests_compile_coverage.c and
tests_coverage.c files.  This makes it awkard to extend.

So, this patch moves the invocation of gcov into a new tools/gcov.v
file, analagous to tools/compile.c.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
David Gibson 9 years ago
parent
commit
bcb956d9af
4 changed files with 47 additions and 16 deletions
  1. 1 10
      tools/ccanlint/tests/tests_compile_coverage.c
  2. 4 6
      tools/ccanlint/tests/tests_coverage.c
  3. 36 0
      tools/gcov.c
  4. 6 0
      tools/tools.h

+ 1 - 10
tools/ccanlint/tests/tests_compile_coverage.c

@@ -19,16 +19,7 @@
 /* Note: we already test safe_mode in run_tests.c */
 static const char *can_run_coverage(struct manifest *m)
 {
-#ifdef __GNUC__
-	unsigned int timeleft = default_timeout_ms;
-	char *output;
-
-	if (!run_command(m, &timeleft, &output, "gcov -h"))
-		return tal_fmt(m, "No gcov support: %s", output);
-	return NULL;
-#else
-	return "No coverage support for this compiler";
-#endif
+	return gcov_unavailable(m);
 }
 
 static char *cflags_list(const struct manifest *m)

+ 4 - 6
tools/ccanlint/tests/tests_coverage.c

@@ -138,7 +138,7 @@ static void do_run_coverage_tests(struct manifest *m,
 {
 	struct ccan_file *i;
 	char *cmdout, *outdir;
-	char *covcmd;
+	char *covargs;
 	bool full_gcov = (verbose > 1);
 	struct list_head *list;
 	bool ran_some = false;
@@ -146,16 +146,14 @@ static void do_run_coverage_tests(struct manifest *m,
 	/* This tells gcov where we put those .gcno files. */
 	outdir = path_dirname(score,
 			      m->info_file->compiled[COMPILE_NORMAL]);
-	covcmd = tal_fmt(m, "gcov %s -o %s",
-			 full_gcov ? "" : "-n",
-			 outdir);
+	covargs = tal_fmt(m, "%s -o %s", full_gcov ? "" : "-n", outdir);
 
 	/* Run them all. */
 	foreach_ptr(list, &m->run_tests, &m->api_tests) {
 		list_for_each(list, i, list) {
 			if (run_command(score, timeleft, &cmdout,
 					"%s", i->compiled[COMPILE_COVERAGE])) {
-				tal_append_fmt(&covcmd, " %s", i->fullname);
+				tal_append_fmt(&covargs, " %s", i->fullname);
 			} else {
 				score_file_error(score, i, 0,
 						 "Running test with coverage"
@@ -174,7 +172,7 @@ static void do_run_coverage_tests(struct manifest *m,
 	}
 
 	/* Now run gcov: we want output even if it succeeds. */
-	if (!run_command(score, timeleft, &cmdout, "%s", covcmd)) {
+	if (!run_gcov(score, timeleft, &cmdout, "%s", covargs)) {
 		score->error = tal_fmt(score, "Running gcov: %s", cmdout);
 		return;
 	}

+ 36 - 0
tools/gcov.c

@@ -0,0 +1,36 @@
+#include "tools.h"
+#include <stdlib.h>
+#include <stdarg.h>
+
+bool run_gcov(const void *ctx, unsigned int *time_ms, char **output,
+	      const char *fmt, ...)
+{
+	char *args;
+	va_list ap;
+	bool rc;
+
+	va_start(ap, fmt);
+	args = tal_vfmt(ctx, fmt, ap);
+	rc = run_command(ctx, time_ms, output, "gcov %s", args);
+	tal_free(args);
+	return rc;
+}
+
+const char *gcov_unavailable(void *ctx)
+{
+	const char *err = NULL;
+
+#ifdef __GNUC__
+	unsigned int timeleft = default_timeout_ms;
+	char *output;
+
+	if (!run_gcov(ctx, &timeleft, &output, "-h")) {
+		err = tal_fmt(ctx, "No gcov support: %s", output);
+		tal_free(output);
+	}
+#else
+	err = "No coverage support for this compiler";
+#endif
+
+	return err;
+}

+ 6 - 0
tools/tools.h

@@ -101,4 +101,10 @@ extern const unsigned int default_timeout_ms;
 
 /* Get ccan/ top dir, given a directory within it. */
 const char *find_ccan_dir(const char *base);
+
+/* Run gcov coverage tool */
+const char *gcov_unavailable(void *ctx);
+bool run_gcov(const void *ctx, unsigned int *time_ms, char **output,
+	      const char *fmt, ...);
+
 #endif /* CCAN_TOOLS_H */