diff options
19 files changed, 321 insertions, 125 deletions
diff --git a/tools/ccanlint/ccanlint.h b/tools/ccanlint/ccanlint.h index 9f15ef39..827fba14 100644 --- a/tools/ccanlint/ccanlint.h +++ b/tools/ccanlint/ccanlint.h @@ -17,6 +17,12 @@ 4 == Describe every action. */ extern int verbose; +enum compile_type { + COMPILE_NORMAL, + COMPILE_NOFEAT, + COMPILE_TYPES +}; + struct manifest { char *dir; /* The module name, ie. final element of dir name */ @@ -26,7 +32,7 @@ struct manifest { /* Linked off deps. */ struct list_node list; /* Where our final compiled output is */ - char *compiled; + char *compiled[COMPILE_TYPES]; struct list_head c_files; struct list_head h_files; @@ -174,7 +180,7 @@ struct ccan_file { struct list_head *doc_sections; /* If this file gets compiled (eg. .C file to .o file), result here. */ - char *compiled; + char *compiled[COMPILE_TYPES]; /* Compiled with coverage information. */ char *cov_compiled; diff --git a/tools/ccanlint/compulsory_tests/build.h b/tools/ccanlint/compulsory_tests/build.h index 0e2f7e65..04140bf9 100644 --- a/tools/ccanlint/compulsory_tests/build.h +++ b/tools/ccanlint/compulsory_tests/build.h @@ -1,7 +1,10 @@ #ifndef CCANLINT_BUILD_H #define CCANLINT_BUILD_H -char *build_module(struct manifest *m, bool keep, char **errstr); -char *build_submodule(struct manifest *m); +char *build_module(struct manifest *m, bool keep, enum compile_type ctype, + char **errstr); +char *build_submodule(struct manifest *m, const char *flags, + enum compile_type ctype); void build_objects(struct manifest *m, - bool keep, struct score *score, const char *flags); + bool keep, struct score *score, const char *flags, + enum compile_type ctype); #endif /* CCANLINT_BUILD_H */ diff --git a/tools/ccanlint/compulsory_tests/depends_build.c b/tools/ccanlint/compulsory_tests/depends_build.c index 8bce5544..ea5c3926 100644 --- a/tools/ccanlint/compulsory_tests/depends_build.c +++ b/tools/ccanlint/compulsory_tests/depends_build.c @@ -28,7 +28,9 @@ static bool expect_obj_file(struct manifest *m) return !list_empty(&m->c_files); } -static char *build_subdir_objs(struct manifest *m) +static char *build_subdir_objs(struct manifest *m, + const char *flags, + enum compile_type ctype) { struct ccan_file *i; @@ -36,11 +38,11 @@ static char *build_subdir_objs(struct manifest *m) char *fullfile = talloc_asprintf(m, "%s/%s", m->dir, i->name); char *output; - i->compiled = maybe_temp_file(m, "", false, fullfile); - if (!compile_object(m, fullfile, ccan_dir, compiler, cflags, - i->compiled, &output)) { - talloc_free(i->compiled); - i->compiled = NULL; + i->compiled[ctype] = maybe_temp_file(m, "", false, fullfile); + if (!compile_object(m, fullfile, ccan_dir, compiler, flags, + i->compiled[ctype], &output)) { + talloc_free(i->compiled[ctype]); + i->compiled[ctype] = NULL; return talloc_asprintf(m, "Dependency %s" " did not build:\n%s", @@ -50,11 +52,12 @@ static char *build_subdir_objs(struct manifest *m) return NULL; } -char *build_submodule(struct manifest *m) +char *build_submodule(struct manifest *m, const char *flags, + enum compile_type ctype) { char *errstr; - if (m->compiled) + if (m->compiled[ctype]) return NULL; if (!expect_obj_file(m)) @@ -63,12 +66,12 @@ char *build_submodule(struct manifest *m) if (verbose >= 2) printf(" Building dependency %s\n", m->dir); - errstr = build_subdir_objs(m); + errstr = build_subdir_objs(m, flags, ctype); if (errstr) return errstr; - m->compiled = build_module(m, false, &errstr); - if (!m->compiled) + m->compiled[ctype] = build_module(m, false, ctype, &errstr); + if (!m->compiled[ctype]) return errstr; return NULL; } @@ -80,7 +83,7 @@ static void check_depends_built(struct manifest *m, struct manifest *i; list_for_each(&m->deps, i, list) { - char *errstr = build_submodule(i); + char *errstr = build_submodule(i, cflags, COMPILE_NORMAL); if (errstr) { score->error = talloc_asprintf(score, diff --git a/tools/ccanlint/compulsory_tests/depends_exist.c b/tools/ccanlint/compulsory_tests/depends_exist.c index a90a7196..c283f2a4 100644 --- a/tools/ccanlint/compulsory_tests/depends_exist.c +++ b/tools/ccanlint/compulsory_tests/depends_exist.c @@ -33,6 +33,7 @@ static bool add_dep(struct manifest *m, const char *dep, struct score *score) return true; } +/* FIXME: check this is still true once we reduce features. */ static void check_depends_exist(struct manifest *m, bool keep, unsigned int *timeleft, struct score *score) @@ -47,7 +48,8 @@ static void check_depends_exist(struct manifest *m, if (safe_mode) deps = get_safe_ccan_deps(m, m->dir, true); else - deps = get_deps(m, m->dir, true, &m->info_file->compiled); + deps = get_deps(m, m->dir, true, + &m->info_file->compiled[COMPILE_NORMAL]); for (i = 0; deps[i]; i++) { if (!strstarts(deps[i], "ccan/")) diff --git a/tools/ccanlint/compulsory_tests/module_builds.c b/tools/ccanlint/compulsory_tests/module_builds.c index 40a345e5..23985d2c 100644 --- a/tools/ccanlint/compulsory_tests/module_builds.c +++ b/tools/ccanlint/compulsory_tests/module_builds.c @@ -22,24 +22,28 @@ static const char *can_build(struct manifest *m) return NULL; } -static char *obj_list(const struct manifest *m) +static char *obj_list(const struct manifest *m, enum compile_type ctype) { char *list = talloc_strdup(m, ""); struct ccan_file *i; /* Objects from all the C files. */ list_for_each(&m->c_files, i, list) - list = talloc_asprintf_append(list, "%s ", i->compiled); + list = talloc_asprintf_append(list, "%s ", + i->compiled[ctype]); return list; } -char *build_module(struct manifest *m, bool keep, char **errstr) +char *build_module(struct manifest *m, bool keep, + enum compile_type ctype, char **errstr) { - char *name = link_objects(m, m->basename, false, obj_list(m), errstr); + char *name = link_objects(m, m->basename, false, obj_list(m, ctype), + errstr); if (name) { if (keep) { char *realname = talloc_asprintf(m, "%s.o", m->dir); + assert(ctype == COMPILE_NORMAL); /* We leave this object file around, all built. */ if (!move_file(name, realname)) err(1, "Renaming %s to %s", name, realname); @@ -63,8 +67,9 @@ static void do_build(struct manifest *m, return; } - m->compiled = build_module(m, keep, &errstr); - if (!m->compiled) { + m->compiled[COMPILE_NORMAL] + = build_module(m, keep, COMPILE_NORMAL, &errstr); + if (!m->compiled[COMPILE_NORMAL]) { score_file_error(score, NULL, 0, "%s", errstr); return; } diff --git a/tools/ccanlint/compulsory_tests/module_links.c b/tools/ccanlint/compulsory_tests/module_links.c index 9c1bce79..0bf98215 100644 --- a/tools/ccanlint/compulsory_tests/module_links.c +++ b/tools/ccanlint/compulsory_tests/module_links.c @@ -28,9 +28,10 @@ static char *obj_list(const struct manifest *m) /* Other CCAN deps. */ list_for_each(&m->deps, i, list) { - if (i->compiled) + if (i->compiled[COMPILE_NORMAL]) list = talloc_asprintf_append(list, "%s ", - i->compiled); + i->compiled + [COMPILE_NORMAL]); } return list; } @@ -38,7 +39,8 @@ static char *obj_list(const struct manifest *m) static char *lib_list(const struct manifest *m) { unsigned int i, num; - char **libs = get_libs(m, ".", &num, &m->info_file->compiled); + char **libs = get_libs(m, ".", + &num, &m->info_file->compiled[COMPILE_NORMAL]); char *ret = talloc_strdup(m, ""); for (i = 0; i < num; i++) diff --git a/tools/ccanlint/compulsory_tests/objects_build.c b/tools/ccanlint/compulsory_tests/objects_build.c index 46fdbd45..2132b173 100644 --- a/tools/ccanlint/compulsory_tests/objects_build.c +++ b/tools/ccanlint/compulsory_tests/objects_build.c @@ -23,7 +23,8 @@ static const char *can_build(struct manifest *m) } void build_objects(struct manifest *m, - bool keep, struct score *score, const char *flags) + bool keep, struct score *score, const char *flags, + enum compile_type ctype) { struct ccan_file *i; bool errors = false, warnings = false; @@ -37,10 +38,10 @@ void build_objects(struct manifest *m, char *output; char *fullfile = talloc_asprintf(m, "%s/%s", m->dir, i->name); - i->compiled = maybe_temp_file(m, "", keep, fullfile); + i->compiled[ctype] = maybe_temp_file(m, "", keep, fullfile); if (!compile_object(score, fullfile, ccan_dir, compiler, flags, - i->compiled, &output)) { - talloc_free(i->compiled); + i->compiled[ctype], &output)) { + talloc_free(i->compiled[ctype]); score_file_error(score, i, 0, "Compiling object files:\n%s", output); @@ -64,7 +65,7 @@ static void check_objs_build(struct manifest *m, bool keep, unsigned int *timeleft, struct score *score) { - build_objects(m, keep, score, cflags); + build_objects(m, keep, score, cflags, COMPILE_NORMAL); } struct ccanlint objects_build = { diff --git a/tools/ccanlint/file_analysis.c b/tools/ccanlint/file_analysis.c index d55e2b8c..91eb10a7 100644 --- a/tools/ccanlint/file_analysis.c +++ b/tools/ccanlint/file_analysis.c @@ -81,7 +81,7 @@ struct ccan_file *new_ccan_file(const void *ctx, const char *dir, char *name) f->lines = NULL; f->line_info = NULL; f->doc_sections = NULL; - f->compiled = NULL; + f->compiled[COMPILE_NORMAL] = f->compiled[COMPILE_NOFEAT] = NULL; f->name = talloc_steal(f, name); f->fullname = talloc_asprintf(f, "%s/%s", dir, f->name); f->contents = NULL; @@ -229,7 +229,7 @@ struct manifest *get_manifest(const void *ctx, const char *dir) m = talloc_linked(ctx, talloc(NULL, struct manifest)); m->info_file = NULL; - m->compiled = NULL; + m->compiled[COMPILE_NORMAL] = m->compiled[COMPILE_NOFEAT] = NULL; m->dir = talloc_steal(m, canon_dir); list_head_init(&m->c_files); list_head_init(&m->h_files); diff --git a/tools/ccanlint/tests/depends_build_without_features.c b/tools/ccanlint/tests/depends_build_without_features.c new file mode 100644 index 00000000..65728fc8 --- /dev/null +++ b/tools/ccanlint/tests/depends_build_without_features.c @@ -0,0 +1,59 @@ +#include <tools/ccanlint/ccanlint.h> +#include <tools/tools.h> +#include <ccan/talloc/talloc.h> +#include <ccan/str/str.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <err.h> +#include <string.h> +#include <ctype.h> +#include "../compulsory_tests/build.h" + +static const char *can_build(struct manifest *m) +{ + if (safe_mode) + return "Safe mode enabled"; + return NULL; +} + +static void check_depends_built_without_features(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) +{ + struct manifest *i; + char *flags; + + flags = talloc_asprintf(score, "%s -I.", cflags); + + list_for_each(&m->deps, 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; + } + } + + score->pass = true; + score->score = score->total; +} + +struct ccanlint depends_build_without_features = { + .key = "depends_build_without_features", + .name = "Module's CCAN dependencies can be found or built (reduced features)", + .check = check_depends_built_without_features, + .can_run = can_build, + .needs = "depends_exist" +}; + +REGISTER_TEST(depends_build_without_features); diff --git a/tools/ccanlint/tests/examples_compile.c b/tools/ccanlint/tests/examples_compile.c index 646e5ae3..35e45ca0 100644 --- a/tools/ccanlint/tests/examples_compile.c +++ b/tools/ccanlint/tests/examples_compile.c @@ -51,7 +51,7 @@ static void add_dep(struct manifest ***deps, const char *basename) m = get_manifest(*deps, talloc_asprintf(*deps, "%s/ccan/%s", ccan_dir, basename)); - errstr = build_submodule(m); + errstr = build_submodule(m, cflags, COMPILE_NORMAL); if (errstr) errx(1, "%s", errstr); @@ -62,7 +62,8 @@ static void add_dep(struct manifest ***deps, const char *basename) if (m->info_file) { char **infodeps; - infodeps = get_deps(m, m->dir, false, &m->info_file->compiled); + infodeps = get_deps(m, m->dir, false, + &m->info_file->compiled[COMPILE_NORMAL]); for (i = 0; infodeps[i]; i++) { if (strstarts(infodeps[i], "ccan/")) @@ -96,19 +97,23 @@ static char *example_obj_list(struct manifest *m, struct ccan_file *f) list = talloc_strdup(f, ""); for (i = 0; i < talloc_get_size(deps) / sizeof(*deps); i++) { - if (deps[i]->compiled) + if (deps[i]->compiled[COMPILE_NORMAL]) list = talloc_asprintf_append(list, " %s", - deps[i]->compiled); + deps[i]->compiled + [COMPILE_NORMAL]); } return list; } +/* FIXME: Test with reduced features! */ static char *lib_list(const struct manifest *m) { unsigned int i, num; - char **libs = get_libs(m, m->dir, &num, &m->info_file->compiled); + char **libs; char *ret = talloc_strdup(m, ""); + libs = get_libs(m, m->dir, &num, + &m->info_file->compiled[COMPILE_NORMAL]); for (i = 0; i < num; i++) ret = talloc_asprintf_append(ret, "-l%s ", libs[i]); return ret; @@ -119,16 +124,18 @@ static bool compile(const void *ctx, struct ccan_file *file, bool keep, char **output) { - file->compiled = maybe_temp_file(ctx, "", keep, file->fullname); + file->compiled[COMPILE_NORMAL] + = maybe_temp_file(ctx, "", keep, file->fullname); if (!compile_and_link(ctx, file->fullname, ccan_dir, example_obj_list(m, file), compiler, cflags, - lib_list(m), file->compiled, output)) { + lib_list(m), file->compiled[COMPILE_NORMAL], + output)) { /* Don't keep failures. */ if (keep) - unlink(file->compiled); - talloc_free(file->compiled); - file->compiled = NULL; + unlink(file->compiled[COMPILE_NORMAL]); + talloc_free(file->compiled[COMPILE_NORMAL]); + file->compiled[COMPILE_NORMAL] = NULL; return false; } return true; diff --git a/tools/ccanlint/tests/examples_run.c b/tools/ccanlint/tests/examples_run.c index 5c06c263..4b881724 100644 --- a/tools/ccanlint/tests/examples_run.c +++ b/tools/ccanlint/tests/examples_run.c @@ -209,7 +209,7 @@ static char *unexpected(struct ccan_file *i, const char *input, unsigned int default_time = default_timeout_ms; cmd = talloc_asprintf(i, "echo '%s' | %s %s", - input, i->compiled, input); + input, i->compiled[COMPILE_NORMAL], input); output = run_with_timeout(i, cmd, &ok, &default_time); if (!ok) @@ -248,7 +248,7 @@ static void run_examples(struct manifest *m, bool keep, linenum++, expect = find_expect(i, lines, &input, &exact, &linenum)) { - if (i->compiled == NULL) + if (i->compiled[COMPILE_NORMAL] == NULL) continue; score->total++; @@ -268,6 +268,7 @@ static void run_examples(struct manifest *m, bool keep, } } +/* FIXME: Test with reduced features, valgrind! */ struct ccanlint examples_run = { .key = "examples_run", .name = "Module examples with expected output give that output", diff --git a/tools/ccanlint/tests/objects_build_without_features.c b/tools/ccanlint/tests/objects_build_without_features.c index f30bde4e..8174541c 100644 --- a/tools/ccanlint/tests/objects_build_without_features.c +++ b/tools/ccanlint/tests/objects_build_without_features.c @@ -8,7 +8,7 @@ static void check_objs_build_without_features(struct manifest *m, struct score *score) { const char *flags = talloc_asprintf(score, "-I. %s", cflags); - build_objects(m, keep, score, flags); + build_objects(m, keep, score, flags, COMPILE_NOFEAT); } struct ccanlint objects_build_without_features = { diff --git a/tools/ccanlint/tests/tests_compile.c b/tools/ccanlint/tests/tests_compile.c index 6c0f9d34..8a833053 100644 --- a/tools/ccanlint/tests/tests_compile.c +++ b/tools/ccanlint/tests/tests_compile.c @@ -23,8 +23,8 @@ static const char *can_build(struct manifest *m) return NULL; } -/* FIXME: Merge this into one place. */ -static char *obj_list(const struct manifest *m, bool link_with_module) +static char *obj_list(const struct manifest *m, bool link_with_module, + enum compile_type ctype) { char *list = talloc_strdup(m, ""); struct ccan_file *i; @@ -32,27 +32,30 @@ static char *obj_list(const struct manifest *m, bool link_with_module) /* Objects from any other C files. */ list_for_each(&m->other_test_c_files, i, list) - list = talloc_asprintf_append(list, " %s", i->compiled); + list = talloc_asprintf_append(list, " %s", + i->compiled[ctype]); /* Our own object files. */ if (link_with_module) list_for_each(&m->c_files, i, list) - list = talloc_asprintf_append(list, " %s", i->compiled); + list = talloc_asprintf_append(list, " %s", + i->compiled[ctype]); /* Other ccan modules. */ list_for_each(&m->deps, subm, list) { - if (subm->compiled) + if (subm->compiled[ctype]) list = talloc_asprintf_append(list, " %s", - subm->compiled); + subm->compiled[ctype]); } return list; } -static char *lib_list(const struct manifest *m) +static char *lib_list(const struct manifest *m, enum compile_type ctype) { unsigned int i, num; - char **libs = get_libs(m, m->dir, &num, &m->info_file->compiled); + char **libs = get_libs(m, m->dir, &num, + &m->info_file->compiled[ctype]); char *ret = talloc_strdup(m, ""); for (i = 0; i < num; i++) @@ -63,26 +66,34 @@ static char *lib_list(const struct manifest *m) static bool compile(const void *ctx, struct manifest *m, struct ccan_file *file, - const char *flags, bool fail, bool link_with_module, - bool keep, char **output) + bool keep, + enum compile_type ctype, + char **output) { - char *f = talloc_asprintf(ctx, "%s%s%s", - flags, fail ? "-DFAIL " : "", cflags); + char *fname, *flags; + + flags = talloc_asprintf(ctx, "%s%s%s", + fail ? "-DFAIL " : "", + cflags, + ctype == COMPILE_NOFEAT ? " -I." : ""); - file->compiled = maybe_temp_file(ctx, "", keep, file->fullname); + fname = maybe_temp_file(ctx, "", keep, file->fullname); if (!compile_and_link(ctx, file->fullname, ccan_dir, - obj_list(m, link_with_module), compiler, f, - lib_list(m), file->compiled, output)) { - talloc_free(file->compiled); + obj_list(m, link_with_module, ctype), compiler, + flags, lib_list(m, ctype), fname, output)) { + talloc_free(fname); return false; } + + file->compiled[ctype] = fname; return true; } static void compile_tests(struct manifest *m, bool keep, - struct score *score, const char *incl) + struct score *score, + enum compile_type ctype) { char *cmdout; struct ccan_file *i; @@ -91,8 +102,9 @@ static void compile_tests(struct manifest *m, bool keep, foreach_ptr(list, &m->compile_ok_tests, &m->run_tests, &m->api_tests) { list_for_each(list, i, list) { - if (!compile(score, m, i, incl, false, - list == &m->api_tests, keep, &cmdout)) { + if (!compile(score, m, i, false, + list == &m->api_tests, keep, + ctype, &cmdout)) { score_file_error(score, i, 0, "Compile failed:\n%s", cmdout); @@ -112,7 +124,8 @@ static void compile_tests(struct manifest *m, bool keep, /* For historical reasons, "fail" often means "gives warnings" */ list_for_each(&m->compile_fail_tests, i, list) { - if (!compile(score, m, i, incl, false, false, false, &cmdout)) { + if (!compile(score, m, i, false, false, false, + ctype, &cmdout)) { score_file_error(score, i, 0, "Compile without -DFAIL failed:\n%s", cmdout); @@ -125,7 +138,8 @@ static void compile_tests(struct manifest *m, bool keep, cmdout); return; } - if (compile(score, m, i, incl, true, false, false, &cmdout) + if (compile(score, m, i, true, false, false, + ctype, &cmdout) && streq(cmdout, "")) { score_file_error(score, i, 0, "Compiled successfully with -DFAIL?"); @@ -142,7 +156,7 @@ static void do_compile_tests(struct manifest *m, bool keep, unsigned int *timeleft, struct score *score) { - return compile_tests(m, keep, score, ""); + compile_tests(m, keep, score, COMPILE_NORMAL); } struct ccanlint tests_compile = { @@ -167,7 +181,7 @@ static void do_compile_tests_without_features(struct manifest *m, unsigned int *timeleft, struct score *score) { - compile_tests(m, keep, score, "-I. "); + compile_tests(m, keep, score, COMPILE_NOFEAT); } struct ccanlint tests_compile_without_features = { @@ -175,6 +189,6 @@ struct ccanlint tests_compile_without_features = { .name = "Module tests compile (without features)", .check = do_compile_tests_without_features, .can_run = features_reduced, - .needs = "tests_compile reduce_features" + .needs = "tests_helpers_compile_without_features reduce_features" }; REGISTER_TEST(tests_compile_without_features); diff --git a/tools/ccanlint/tests/tests_compile_coverage.c b/tools/ccanlint/tests/tests_compile_coverage.c index 4e356099..89c786e2 100644 --- a/tools/ccanlint/tests/tests_compile_coverage.c +++ b/tools/ccanlint/tests/tests_compile_coverage.c @@ -60,16 +60,18 @@ static char *obj_list(const struct manifest *m, const char *modobjs) /* Objects from any other C files. */ list_for_each(&m->other_test_c_files, i, list) - list = talloc_asprintf_append(list, " %s", i->compiled); + list = talloc_asprintf_append(list, " %s", + i->compiled[COMPILE_NORMAL]); if (modobjs) list = talloc_append_string(list, modobjs); /* Other ccan modules (don't need coverage versions of those). */ list_for_each(&m->deps, subm, list) { - if (subm->compiled) + if (subm->compiled[COMPILE_NORMAL]) list = talloc_asprintf_append(list, " %s", - subm->compiled); + subm->compiled + [COMPILE_NORMAL]); } return list; @@ -78,7 +80,8 @@ static char *obj_list(const struct manifest *m, const char *modobjs) static char *lib_list(const struct manifest *m) { unsigned int i, num; - char **libs = get_libs(m, m->dir, &num, &m->info_file->compiled); + char **libs = get_libs(m, m->dir, &num, + &m->info_file->compiled[COMPILE_NORMAL]); char *ret = talloc_strdup(m, ""); for (i = 0; i < num; i++) diff --git a/tools/ccanlint/tests/tests_coverage.c b/tools/ccanlint/tests/tests_coverage.c index a8da103f..26be8553 100644 --- a/tools/ccanlint/tests/tests_coverage.c +++ b/tools/ccanlint/tests/tests_coverage.c @@ -138,7 +138,8 @@ static void do_run_coverage_tests(struct manifest *m, bool ran_some = false; /* This tells gcov where we put those .gcno files. */ - outdir = talloc_dirname(score, m->info_file->compiled); + outdir = talloc_dirname(score, + m->info_file->compiled[COMPILE_NORMAL]); covcmd = talloc_asprintf(m, "gcov %s -o %s", full_gcov ? "" : "-n", outdir); diff --git a/tools/ccanlint/tests/tests_helpers_compile.c b/tools/ccanlint/tests/tests_helpers_compile.c index 7aad1dcb..d7c8f0ae 100644 --- a/tools/ccanlint/tests/tests_helpers_compile.c +++ b/tools/ccanlint/tests/tests_helpers_compile.c @@ -13,6 +13,7 @@ #include <err.h> #include <string.h> #include <ctype.h> +#include "reduce_features.h" static const char *can_run(struct manifest *m) { @@ -24,17 +25,21 @@ static const char *can_run(struct manifest *m) static bool compile(struct manifest *m, bool keep, struct ccan_file *cfile, + const char *flags, + enum compile_type ctype, char **output) { - cfile->compiled = maybe_temp_file(m, ".o", keep, cfile->fullname); - return compile_object(m, cfile->fullname, ccan_dir, compiler, cflags, - cfile->compiled, output); + cfile->compiled[ctype] = maybe_temp_file(m, ".o", keep, cfile->fullname); + return compile_object(m, cfile->fullname, ccan_dir, compiler, flags, + cfile->compiled[ctype], output); } -static void do_compile_test_helpers(struct manifest *m, - bool keep, - unsigned int *timeleft, - struct score *score) +static void compile_test_helpers(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score, + const char *flags, + enum compile_type ctype) { struct ccan_file *i; bool errors = false, warnings = false; @@ -47,7 +52,7 @@ static void do_compile_test_helpers(struct manifest *m, list_for_each(&m->other_test_c_files, i, list) { char *cmdout; - if (!compile(m, keep, i, &cmdout)) { + if (!compile(m, keep, i, flags, ctype, &cmdout)) { errors = true; score_file_error(score, i, 0, "Compile failed:\n%s", cmdout); @@ -64,6 +69,15 @@ static void do_compile_test_helpers(struct manifest *m, } } +static void do_compile_test_helpers(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) +{ + compile_test_helpers(m, keep, timeleft, score, cflags, + COMPILE_NORMAL); +} + struct ccanlint tests_helpers_compile = { .key = "tests_helpers_compile", .name = "Module test helper objects compile", @@ -73,3 +87,32 @@ struct ccanlint tests_helpers_compile = { }; REGISTER_TEST(tests_helpers_compile); + +static const char *features_reduced(struct manifest *m) +{ + if (features_were_reduced) + return NULL; + return "No features to turn off"; +} + +static void do_compile_test_helpers_without_features(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) +{ + char *flags; + + flags = talloc_asprintf(score, "%s -I.", cflags); + + compile_test_helpers(m, keep, timeleft, score, flags, + COMPILE_NOFEAT); +} + +struct ccanlint tests_helpers_compile_without_features = { + .key = "tests_helpers_compile_without_features", + .name = "Module tests helpers compile (without features)", + .check = do_compile_test_helpers_without_features, + .can_run = features_reduced, + .needs = "depends_build_without_features tests_exist" +}; +REGISTER_TEST(tests_helpers_compile_without_features); diff --git a/tools/ccanlint/tests/tests_pass.c b/tools/ccanlint/tests/tests_pass.c index 15df1ed6..cbf01fd4 100644 --- a/tools/ccanlint/tests/tests_pass.c +++ b/tools/ccanlint/tests/tests_pass.c @@ -49,10 +49,9 @@ static const char *concat(struct score *score, char *bits[]) static bool run_test(void *ctx, struct manifest *m, unsigned int *timeleft, char **cmdout, - struct ccan_file *i, - bool use_valgrind) + struct ccan_file *i) { - if (use_valgrind) { + if (do_valgrind) { const char *options; options = concat(ctx, per_file_options(&tests_pass_valgrind, i)); @@ -62,8 +61,8 @@ static bool run_test(void *ctx, * unreadable by humans *and* doesn't support * children reporting. */ i->valgrind_log = talloc_asprintf(m, - "%s.valgrind-log", - i->compiled); + "%s.valgrind-log", + i->compiled[COMPILE_NORMAL]); talloc_set_destructor(i->valgrind_log, unlink_file_destructor); @@ -73,18 +72,19 @@ static bool run_test(void *ctx, " --log-fd=3 %s %s" " 3> %s", options, - i->compiled, i->valgrind_log); + i->compiled[COMPILE_NORMAL], + i->valgrind_log); } } - return run_command(m, timeleft, cmdout, "%s", i->compiled); + return run_command(m, timeleft, cmdout, "%s", + i->compiled[COMPILE_NORMAL]); } -static void run_tests(struct manifest *m, - bool keep, - unsigned int *timeleft, - struct score *score, - bool use_valgrind) +static void do_run_tests(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) { struct list_head *list; struct ccan_file *i; @@ -94,8 +94,7 @@ static void run_tests(struct manifest *m, foreach_ptr(list, &m->run_tests, &m->api_tests) { list_for_each(list, i, list) { score->total++; - if (run_test(score, m, timeleft, &cmdout, i, - use_valgrind)) + if (run_test(score, m, timeleft, &cmdout, i)) score->score++; else score_file_error(score, i, 0, "%s", cmdout); @@ -106,21 +105,6 @@ static void run_tests(struct manifest *m, score->pass = true; } -static void do_run_tests(struct manifest *m, - bool keep, - unsigned int *timeleft, - struct score *score) -{ - run_tests(m, keep, timeleft, score, do_valgrind); -} - -static void do_run_tests_without_features(struct manifest *m, - bool keep, - unsigned int *timeleft, - struct score *score) -{ - run_tests(m, keep, timeleft, score, false); -} /* Gcc's warn_unused_result is fascist bullshit. */ #define doesnt_matter() @@ -136,7 +120,7 @@ static void run_under_debugger(struct manifest *m, struct score *score) return; command = talloc_asprintf(m, "gdb -ex 'break tap.c:139' -ex 'run' %s", - first->file->compiled); + first->file->compiled[COMPILE_NORMAL]); if (system(command)) doesnt_matter(); } @@ -151,13 +135,3 @@ struct ccanlint tests_pass = { }; REGISTER_TEST(tests_pass); - -struct ccanlint tests_pass_without_features = { - .key = "tests_pass_without_features", - .name = "Module's run and api tests pass (without features)", - .check = do_run_tests_without_features, - .handle = run_under_debugger, - .needs = "tests_compile_without_features" -}; - -REGISTER_TEST(tests_pass_without_features); diff --git a/tools/ccanlint/tests/tests_pass_valgrind.c b/tools/ccanlint/tests/tests_pass_valgrind.c index 64cb29e2..81814377 100644 --- a/tools/ccanlint/tests/tests_pass_valgrind.c +++ b/tools/ccanlint/tests/tests_pass_valgrind.c @@ -246,7 +246,7 @@ static void run_under_debugger_vg(struct manifest *m, struct score *score) concat(score, per_file_options(&tests_pass_valgrind, first->file)), - first->file->compiled); + first->file->compiled[COMPILE_NORMAL]); if (system(command)) doesnt_matter(); } diff --git a/tools/ccanlint/tests/tests_pass_without_features.c b/tools/ccanlint/tests/tests_pass_without_features.c new file mode 100644 index 00000000..4ce33755 --- /dev/null +++ b/tools/ccanlint/tests/tests_pass_without_features.c @@ -0,0 +1,72 @@ +#include <tools/ccanlint/ccanlint.h> +#include <tools/tools.h> +#include <ccan/talloc/talloc.h> +#include <ccan/str/str.h> +#include <ccan/foreach/foreach.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <err.h> +#include <string.h> +#include <ctype.h> + +/* We don't do these under valgrind: too slow! */ +static void do_run_tests_no_features(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) +{ + struct list_head *list; + struct ccan_file *i; + char *cmdout; + + score->total = 0; + foreach_ptr(list, &m->run_tests, &m->api_tests) { + list_for_each(list, i, list) { + score->total++; + if (run_command(m, timeleft, &cmdout, "%s", + i->compiled[COMPILE_NOFEAT])) + score->score++; + else + score_file_error(score, i, 0, "%s", cmdout); + } + } + + if (score->score == score->total) + score->pass = true; +} + +/* Gcc's warn_unused_result is fascist bullshit. */ +#define doesnt_matter() + +static void run_under_debugger(struct manifest *m, struct score *score) +{ + char *command; + struct file_error *first; + + first = list_top(&score->per_file_errors, struct file_error, list); + + if (!ask("Should I run the first failing test under the debugger?")) + return; + + command = talloc_asprintf(m, "gdb -ex 'break tap.c:139' -ex 'run' %s", + first->file->compiled + [COMPILE_NOFEAT]); + if (system(command)) + doesnt_matter(); +} + +struct ccanlint tests_pass_without_features = { + .key = "tests_pass_without_features", + .name = "Module's run and api tests pass (without features)", + .check = do_run_tests_no_features, + .handle = run_under_debugger, + .needs = "tests_compile_without_features" +}; + +REGISTER_TEST(tests_pass_without_features); |