#include <tools/ccanlint/ccanlint.h>
#include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/grab_file/grab_file.h>
#include <ccan/str/str.h>
+#include <ccan/tal/path/path.h>
+#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/foreach/foreach.h>
#include <sys/types.h>
#include <sys/stat.h>
static void analyze_coverage(struct manifest *m, bool full_gcov,
const char *output, struct score *score)
{
- char **lines = strsplit(score, output, "\n", NULL);
+ char **lines = tal_strsplit(score, output, "\n", STR_EMPTY_OK);
float covered_lines = 0.0;
unsigned int i, total_lines = 0;
bool lines_matter = false;
/*
- Output looks like:
+ Output looks like: (gcov 4.6.3)
File '../../../ccan/tdb2/private.h'
Lines executed:0.00% of 8
/home/ccan/ccan/tdb2/test/run-simple-delete.c:creating 'run-simple-delete.c.gcov'
File '../../../ccan/tdb2/tdb.c'
Lines executed:0.00% of 450
+
+ For gcov 4.7.2:
+
+ File '/home/dwg/src/ccan/ccan/rfc822/test/run-check-check.c'
+ Lines executed:100.00% of 19
+ Creating 'run-check-check.c.gcov'
*/
for (i = 0; lines[i]; i++) {
errx(1, "Could not parse line '%s'", lines[i]);
total_lines += of;
covered_lines += ex / 100.0 * of;
- } else if (full_gcov && strstr(lines[i], ":creating '")) {
+ } else if (full_gcov
+ && (strstr(lines[i], ":creating '")
+ || strstarts(lines[i], "Creating '"))) {
char *file, *filename, *apostrophe;
apostrophe = strchr(lines[i], '\'');
filename = apostrophe + 1;
apostrophe = strchr(filename, '\'');
*apostrophe = '\0';
if (lines_matter) {
- file = grab_file(score, filename, NULL);
+ file = grab_file(score, filename);
if (!file) {
- score->error = talloc_asprintf(score,
- "Reading %s",
- filename);
+ score->error = tal_fmt(score,
+ "Reading %s",
+ filename);
return;
}
printf("%s", file);
score->pass = true;
+ if (verbose > 1)
+ printf("%u of %u lines covered\n",
+ (unsigned)covered_lines, total_lines);
+
/* Nothing covered? We can't tell if there's a source file which
* was never executed, or there really is no code to execute, so
* assume the latter: this test deserves no score. */
}
static void do_run_coverage_tests(struct manifest *m,
- bool keep,
unsigned int *timeleft, struct score *score)
{
struct ccan_file *i;
char *covcmd;
bool full_gcov = (verbose > 1);
struct list_head *list;
+ bool ran_some = false;
/* This tells gcov where we put those .gcno files. */
- outdir = talloc_dirname(score, m->info_file->compiled);
- covcmd = talloc_asprintf(m, "gcov %s -o %s",
- full_gcov ? "" : "-n",
- outdir);
-
- /* Unlink these files afterwards. */
- if (!keep) {
- talloc_set_destructor(talloc_asprintf(score,
- "%s/run.gcno", outdir),
- unlink_file_destructor);
- talloc_set_destructor(talloc_asprintf(score,
- "%s/run.gcda", outdir),
- unlink_file_destructor);
- }
+ outdir = path_dirname(score,
+ m->info_file->compiled[COMPILE_NORMAL]);
+ covcmd = tal_fmt(m, "gcov %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->cov_compiled)) {
- covcmd = talloc_asprintf_append(covcmd, " %s",
- i->fullname);
+ "%s", i->compiled[COMPILE_COVERAGE])) {
+ tal_append_fmt(&covcmd, " %s", i->fullname);
} else {
score_file_error(score, i, 0,
"Running test with coverage"
" failed: %s", cmdout);
return;
}
+ ran_some = true;
}
}
+ /* No tests at all? 0 out of 0 for you... */
+ if (!ran_some) {
+ score->total = score->score = 0;
+ score->pass = true;
+ return;
+ }
+
/* Now run gcov: we want output even if it succeeds. */
if (!run_command(score, timeleft, &cmdout, "%s", covcmd)) {
- score->error = talloc_asprintf(score, "Running gcov: %s",
- cmdout);
+ score->error = tal_fmt(score, "Running gcov: %s", cmdout);
return;
}