From: Rusty Russell Date: Mon, 12 Nov 2012 06:34:24 +0000 (+1030) Subject: ccanlint: add testdepends support. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=453fdc02ce54ff965f9971a3bfd0e1a79b6c98f9 ccanlint: add testdepends support. Signed-off-by: Rusty Russell --- diff --git a/tools/ccanlint/tests/depends_accurate.c b/tools/ccanlint/tests/depends_accurate.c index 986fb3bc..0ed1e654 100644 --- a/tools/ccanlint/tests/depends_accurate.c +++ b/tools/ccanlint/tests/depends_accurate.c @@ -16,7 +16,7 @@ #include #include -static bool has_dep(struct manifest *m, const char *depname) +static bool has_dep(struct manifest *m, bool test_depend, const char *depname) { struct manifest *i; @@ -28,45 +28,63 @@ static bool has_dep(struct manifest *m, const char *depname) if (streq(i->basename, depname)) return true; } + + if (test_depend) { + list_for_each(&m->test_deps, i, list) { + if (streq(i->basename, depname)) + return true; + } + } + return false; } +static void check_dep_includes(struct manifest *m, struct score *score, + struct ccan_file *f, bool test_depend) +{ + unsigned int i; + char **lines = get_ccan_file_lines(f); + struct line_info *li = get_ccan_line_info(f); + + for (i = 0; lines[i]; i++) { + char *mod; + if (!strreg(f, lines[i], + "^[ \t]*#[ \t]*include[ \t]*[<\"]" + "ccan/+([^/]+)/", &mod)) + continue; + + if (has_dep(m, test_depend, mod)) + continue; + + /* FIXME: we can't be sure about + * conditional includes, so don't + * complain. */ + if (!li[i].cond) { + score_file_error(score, f, i+1, + "%s not listed in _info", mod); + } + } +} + static void check_depends_accurate(struct manifest *m, unsigned int *timeleft, struct score *score) { struct list_head *list; - foreach_ptr(list, &m->c_files, &m->h_files, - &m->run_tests, &m->api_tests, + foreach_ptr(list, &m->c_files, &m->h_files) { + struct ccan_file *f; + + list_for_each(list, f, list) + check_dep_includes(m, score, f, false); + } + + foreach_ptr(list, &m->run_tests, &m->api_tests, &m->compile_ok_tests, &m->compile_fail_tests, &m->other_test_c_files) { struct ccan_file *f; - list_for_each(list, f, list) { - unsigned int i; - char **lines = get_ccan_file_lines(f); - struct line_info *li = get_ccan_line_info(f); - - for (i = 0; lines[i]; i++) { - char *mod; - if (!strreg(f, lines[i], - "^[ \t]*#[ \t]*include[ \t]*[<\"]" - "ccan/+([^/]+)/", &mod)) - continue; - - if (has_dep(m, mod)) - continue; - - /* FIXME: we can't be sure about - * conditional includes, so don't - * complain. */ - if (!li[i].cond) { - score_file_error(score, f, i+1, - "%s not listed in _info", - mod); - } - } - } + list_for_each(list, f, list) + check_dep_includes(m, score, f, true); } if (!score->error) { @@ -79,7 +97,7 @@ struct ccanlint depends_accurate = { .key = "depends_accurate", .name = "Module's CCAN dependencies are the only CCAN files #included", .check = check_depends_accurate, - .needs = "depends_exist" + .needs = "depends_exist test_depends_exist" }; REGISTER_TEST(depends_accurate); diff --git a/tools/ccanlint/tests/depends_build.c b/tools/ccanlint/tests/depends_build.c index e6300a19..b578d4b5 100644 --- a/tools/ccanlint/tests/depends_build.c +++ b/tools/ccanlint/tests/depends_build.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -79,17 +80,24 @@ char *build_submodule(struct manifest *m, const char *flags, static void check_depends_built(struct manifest *m, unsigned int *timeleft, struct score *score) { - struct manifest *i; - - list_for_each(&m->deps, i, list) { - char *errstr = build_submodule(i, cflags, COMPILE_NORMAL); - - if (errstr) { - score->error = talloc_asprintf(score, - "Dependency %s" - " did not build:\n%s", - i->basename, errstr); - return; + struct list_head *list; + + foreach_ptr(list, &m->deps, &m->test_deps) { + struct manifest *i; + list_for_each(list, i, list) { + char *errstr; + + errstr = build_submodule(i, cflags, COMPILE_NORMAL); + + if (errstr) { + score->error = talloc_asprintf(score, + "Dependency %s" + " did not" + " build:\n%s", + i->basename, + errstr); + return; + } } } @@ -102,7 +110,7 @@ struct ccanlint depends_build = { .name = "Module's CCAN dependencies can be found or built", .check = check_depends_built, .can_run = can_build, - .needs = "depends_exist" + .needs = "depends_exist test_depends_exist" }; REGISTER_TEST(depends_build); diff --git a/tools/ccanlint/tests/depends_build_without_features.c b/tools/ccanlint/tests/depends_build_without_features.c index 533f4f31..faa3b21d 100644 --- a/tools/ccanlint/tests/depends_build_without_features.c +++ b/tools/ccanlint/tests/depends_build_without_features.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -27,21 +28,27 @@ static void check_depends_built_without_features(struct manifest *m, unsigned int *timeleft, struct score *score) { + struct list_head *list; struct manifest *i; char *flags; flags = talloc_asprintf(score, "%s %s", cflags, REDUCE_FEATURES_FLAGS); - list_for_each(&m->deps, i, list) { - char *errstr = build_submodule(i, flags, COMPILE_NOFEAT); + foreach_ptr(list, &m->deps, &m->test_deps) { + list_for_each(list, i, list) { + char *errstr = build_submodule(i, flags, + COMPILE_NOFEAT); - if (errstr) { - score->error = talloc_asprintf(score, - "Dependency %s" - " did not build:\n%s", - i->basename, errstr); - return; + if (errstr) { + score->error = talloc_asprintf(score, + "Dependency %s" + " did not" + " build:\n%s", + i->basename, + errstr); + return; + } } } diff --git a/tools/ccanlint/tests/depends_exist.c b/tools/ccanlint/tests/depends_exist.c index d869cbb7..76750fb1 100644 --- a/tools/ccanlint/tests/depends_exist.c +++ b/tools/ccanlint/tests/depends_exist.c @@ -14,7 +14,20 @@ #include #include -static bool add_dep(struct manifest *m, const char *dep, struct score *score) +static bool have_dep(struct manifest *m, const char *dep) +{ + struct manifest *i; + + list_for_each(&m->deps, i, list) + if (streq(i->basename, dep + strlen("ccan/"))) + return true; + + return false; +} + +static bool add_dep(struct manifest *m, + struct list_head *deplist, + const char *dep, struct score *score) { struct stat st; struct manifest *subm; @@ -29,7 +42,7 @@ static bool add_dep(struct manifest *m, const char *dep, struct score *score) return false; } subm = get_manifest(m, dir); - list_add_tail(&m->deps, &subm->list); + list_add_tail(deplist, &subm->list); return true; } @@ -39,11 +52,32 @@ static void check_depends_exist(struct manifest *m, { unsigned int i; char **deps; - char *updir = talloc_strdup(m, m->dir); - bool needs_tap; - if (strrchr(updir, '/')) - *strrchr(updir, '/') = '\0'; + if (safe_mode) + deps = get_safe_ccan_deps(m, m->dir, "depends", true); + else + deps = get_deps(m, m->dir, "depends", true, + get_or_compile_info); + + for (i = 0; deps[i]; i++) { + if (!strstarts(deps[i], "ccan/")) + continue; + + if (!add_dep(m, &m->deps, deps[i], score)) + return; + } + + score->pass = true; + score->score = score->total; +} + +static void check_test_depends_exist(struct manifest *m, + unsigned int *timeleft, + struct score *score) +{ + unsigned int i; + char **deps; + bool needs_tap; /* We may need libtap for testing, unless we're "tap" */ if (streq(m->basename, "tap")) { @@ -55,16 +89,18 @@ static void check_depends_exist(struct manifest *m, } if (safe_mode) - deps = get_safe_ccan_deps(m, m->dir, "depends", true); + deps = get_safe_ccan_deps(m, m->dir, "testdepends", true); else - deps = get_deps(m, m->dir, "depends", true, + deps = get_deps(m, m->dir, "testdepends", true, get_or_compile_info); for (i = 0; deps[i]; i++) { if (!strstarts(deps[i], "ccan/")) continue; - if (!add_dep(m, deps[i], score)) + /* Don't add dependency twice: we can only be on one list! */ + if (!have_dep(m, deps[i]) + && !add_dep(m, &m->test_deps, deps[i], score)) return; if (streq(deps[i], "ccan/tap")) { @@ -72,7 +108,8 @@ static void check_depends_exist(struct manifest *m, } } - if (needs_tap && !add_dep(m, "ccan/tap", score)) { + if (needs_tap && !have_dep(m, "ccan/tap") + && !add_dep(m, &m->test_deps, "ccan/tap", score)) { return; } @@ -89,3 +126,13 @@ struct ccanlint depends_exist = { }; REGISTER_TEST(depends_exist); + +struct ccanlint test_depends_exist = { + .key = "test_depends_exist", + .name = "Module's CCAN test dependencies can be found", + .compulsory = false, + .check = check_test_depends_exist, + .needs = "depends_exist" +}; + +REGISTER_TEST(test_depends_exist); diff --git a/tools/ccanlint/tests/tests_compile.c b/tools/ccanlint/tests/tests_compile.c index 3114f2f1..73b1cb24 100644 --- a/tools/ccanlint/tests/tests_compile.c +++ b/tools/ccanlint/tests/tests_compile.c @@ -42,23 +42,30 @@ char *test_obj_list(const struct manifest *m, bool link_with_module, list = talloc_asprintf_append(list, " %s", i->compiled[own_ctype]); - /* Other ccan modules. */ + /* Other ccan modules (normal depends). */ list_for_each(&m->deps, subm, list) { if (subm->compiled[ctype]) list = talloc_asprintf_append(list, " %s", subm->compiled[ctype]); } + /* Other ccan modules (test depends). */ + list_for_each(&m->test_deps, subm, list) { + if (subm->compiled[ctype]) + list = talloc_asprintf_append(list, " %s", + subm->compiled[ctype]); + } + return list; } -char *lib_list(const struct manifest *m, enum compile_type ctype) +char *test_lib_list(const struct manifest *m, enum compile_type ctype) { unsigned int i; char **libs; char *ret = talloc_strdup(m, ""); - libs = get_libs(m, m->dir, "depends", get_or_compile_info); + libs = get_libs(m, m->dir, "testdepends", get_or_compile_info); for (i = 0; libs[i]; i++) ret = talloc_asprintf_append(ret, "-l%s ", libs[i]); return ret; @@ -84,7 +91,7 @@ static bool compile(const void *ctx, if (!compile_and_link(ctx, file->fullname, ccan_dir, test_obj_list(m, link_with_module, ctype, ctype), - compiler, flags, lib_list(m, ctype), fname, + compiler, flags, test_lib_list(m, ctype), fname, output)) { talloc_free(fname); return false; @@ -111,7 +118,7 @@ static void compile_async(const void *ctx, compile_and_link_async(file, time_ms, file->fullname, ccan_dir, test_obj_list(m, link_with_module, ctype, ctype), - compiler, flags, lib_list(m, ctype), + compiler, flags, test_lib_list(m, ctype), file->compiled[ctype]); } diff --git a/tools/ccanlint/tests/tests_compile.h b/tools/ccanlint/tests/tests_compile.h index 590edded..9c010e31 100644 --- a/tools/ccanlint/tests/tests_compile.h +++ b/tools/ccanlint/tests/tests_compile.h @@ -3,4 +3,4 @@ char *test_obj_list(const struct manifest *m, bool link_with_module, enum compile_type ctype, enum compile_type own_ctype); /* Library list as specified by ctype variant of _info. */ -char *lib_list(const struct manifest *m, enum compile_type ctype); +char *test_lib_list(const struct manifest *m, enum compile_type ctype); diff --git a/tools/ccanlint/tests/tests_compile_coverage.c b/tools/ccanlint/tests/tests_compile_coverage.c index 19ba1ef2..9e13ad93 100644 --- a/tools/ccanlint/tests/tests_compile_coverage.c +++ b/tools/ccanlint/tests/tests_compile_coverage.c @@ -46,7 +46,7 @@ static void cov_compile(const void *ctx, COMPILE_NORMAL, COMPILE_COVERAGE), compiler, flags, - lib_list(m, COMPILE_NORMAL), + test_lib_list(m, COMPILE_NORMAL), file->compiled[COMPILE_COVERAGE]); } diff --git a/tools/manifest.c b/tools/manifest.c index 024eaa42..e368b4ed 100644 --- a/tools/manifest.c +++ b/tools/manifest.c @@ -237,6 +237,7 @@ struct manifest *get_manifest(const void *ctx, const char *dir) list_head_init(&m->examples); list_head_init(&m->mangled_examples); list_head_init(&m->deps); + list_head_init(&m->test_deps); len = strlen(m->dir); while (len && m->dir[len-1] == '/') diff --git a/tools/manifest.h b/tools/manifest.h index ee5ae9df..04f88d9e 100644 --- a/tools/manifest.h +++ b/tools/manifest.h @@ -38,6 +38,7 @@ struct manifest { /* From tests/check_depends_exist.c */ struct list_head deps; + struct list_head test_deps; /* From tests/license_exists.c */ enum license license;