ccanlint: keep separate array of compiled versions.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 30 Aug 2011 04:27:08 +0000 (13:57 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 30 Aug 2011 04:27:08 +0000 (13:57 +0930)
Rather than mug the old ->compiled version when we reduce features,
keep both in the structure.  This makes it clear that we are using the
right version (we weren't in all cases, in particular we weren't
recompiling the test helpers correctly.

19 files changed:
tools/ccanlint/ccanlint.h
tools/ccanlint/compulsory_tests/build.h
tools/ccanlint/compulsory_tests/depends_build.c
tools/ccanlint/compulsory_tests/depends_exist.c
tools/ccanlint/compulsory_tests/module_builds.c
tools/ccanlint/compulsory_tests/module_links.c
tools/ccanlint/compulsory_tests/objects_build.c
tools/ccanlint/file_analysis.c
tools/ccanlint/tests/depends_build_without_features.c [new file with mode: 0644]
tools/ccanlint/tests/examples_compile.c
tools/ccanlint/tests/examples_run.c
tools/ccanlint/tests/objects_build_without_features.c
tools/ccanlint/tests/tests_compile.c
tools/ccanlint/tests/tests_compile_coverage.c
tools/ccanlint/tests/tests_coverage.c
tools/ccanlint/tests/tests_helpers_compile.c
tools/ccanlint/tests/tests_pass.c
tools/ccanlint/tests/tests_pass_valgrind.c
tools/ccanlint/tests/tests_pass_without_features.c [new file with mode: 0644]

index 9f15ef39062060304fbb09df45151a162a717a79..827fba141ff1c3908a790df7f793cc5f1ae43755 100644 (file)
    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;
index 0e2f7e659b15b2604a15aa07aef1523ccbda86fe..04140bf9bc68d74348bd22004682f75c484d75ae 100644 (file)
@@ -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 */
index 8bce5544832aa630c2ef93a838019a07d0da2c7d..ea5c39269bd183f8f25c965401e0ea834f7ff01a 100644 (file)
@@ -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,
index a90a7196e6172adabdabef1ea799baf3211b678c..c283f2a4b11b7b3919c60504ef452b9daded22da 100644 (file)
@@ -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/"))
index 40a345e5da8a8c0ae6003655722e9167103fb3de..23985d2cc1e2c23d036967a10bf0e348938ac199 100644 (file)
@@ -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;
        }
index 9c1bce79d9e608c31e6b1fefefc38a56fb72f9bc..0bf9821555d70b53c98f6c767b8b36726b58bc72 100644 (file)
@@ -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++)
index 46fdbd4592ea5561ad350ac9ca3571de297b44b0..2132b17388687dfc2e566b4294c17c44cf46957d 100644 (file)
@@ -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 = {
index d55e2b8c12bebd7b4d4062ed93b1d7350ae8216e..91eb10a7253e5f1de93211bfd8ad4b890834d9c8 100644 (file)
@@ -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 (file)
index 0000000..65728fc
--- /dev/null
@@ -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);
index 646e5ae3325a575f94e83ab496fcef66792016a6..35e45ca03f26116b5584a34c5486cbc0a5d387a3 100644 (file)
@@ -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;
index 5c06c263e5228ebc0fffaf9e19abdc9ce6f7503e..4b881724d35a3d359d933739009d2d45fac0febd 100644 (file)
@@ -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",
index f30bde4ed52f110b0cbd2144144dc1798628012a..8174541cd51271680dcff50d9a123489fdf73b33 100644 (file)
@@ -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 = {
index 6c0f9d34274195855fafc4715972a717f37b48bd..8a833053e9d3c9e698aa573a228fb41a20bdf507 100644 (file)
@@ -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);
index 4e35609913b7374d86847cf7fac01cc29bbc73f7..89c786e2a6ec36301c92afb63539503dde48a448 100644 (file)
@@ -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++)
index a8da103f045fed21280625a1bbf9c4c4e44814c8..26be85534d0392a4069ebad42d99c06440ed7fa6 100644 (file)
@@ -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);
index 7aad1dcb9291b48a96bce6688af2291dcc016fa9..d7c8f0ae75ccd7282c0c39726ee639f04f8a7ee1 100644 (file)
@@ -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);
index 15df1ed69e7cefc8315a780cf47d3904732ab76d..cbf01fd4e13e9b83df06378d97b276e2fdddc9f0 100644 (file)
@@ -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);
index 64cb29e21c438ef8e1c59fd744188413b395a608..818143777e2571e934bc59e98d215a1b3bf7bfcf 100644 (file)
@@ -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 (file)
index 0000000..4ce3375
--- /dev/null
@@ -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);