Browse Source

ccanlint: remove -Werror, use output of compile command to detect warnings.

This means we can pass various compulation tests, but deduct points if
they get warnings.
Rusty Russell 15 years ago
parent
commit
85c347709c

+ 3 - 3
Makefile-ccan

@@ -2,9 +2,9 @@
 # For simple projects you could just do:
 #	SRCFILES += $(wildcard ccan/*/*.c)
 
-CCAN_CFLAGS=-g -O3 -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror
-#CCAN_CFLAGS=-g -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror
-CFLAGS = $(CCAN_CFLAGS) -I. $(DEPGEN)
+#CCAN_CFLAGS=-g -O3 -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations
+CCAN_CFLAGS=-g -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations
+CFLAGS = $(CCAN_CFLAGS) -I. $(DEPGEN) -Werror
 
 
 default: libccan.a

+ 1 - 1
config.h

@@ -1,6 +1,6 @@
 /* Generated by CCAN configurator */
 #define CCAN_COMPILER "cc"
-#define CCAN_CFLAGS "-g -O3 -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror"
+#define CCAN_CFLAGS "-g -Wall -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations"
 
 #define HAVE_ALIGNOF 1
 #define HAVE_ATTRIBUTE_COLD 1

+ 12 - 4
tools/ccanlint/compulsory_tests/build_objs.c

@@ -26,26 +26,34 @@ static void check_objs_build(struct manifest *m,
 			     unsigned int *timeleft, struct score *score)
 {
 	struct ccan_file *i;
+	bool errors = false, warnings = false;
 
 	if (list_empty(&m->c_files))
 		score->total = 0;
+	else
+		score->total = 2;
 
 	list_for_each(&m->c_files, i, list) {
 		char *output;
 		char *fullfile = talloc_asprintf(m, "%s/%s", m->dir, i->name);
 
 		i->compiled = maybe_temp_file(m, "", keep, fullfile);
-		if (!compile_object(m, fullfile, ccan_dir, "", i->compiled,
+		if (!compile_object(score, fullfile, ccan_dir, "", i->compiled,
 				    &output)) {
 			talloc_free(i->compiled);
 			score->error = "Compiling object files";
 			score_file_error(score, i, 0, output);
+			errors = true;
+		} else if (!streq(output, "")) {
+			score->error = "Compiling object files gave warnings";
+			score_file_error(score, i, 0, output);
+			warnings = true;
 		}
-		talloc_free(output);
 	}
-	if (!score->error) {
+
+	if (!errors) {
 		score->pass = true;
-		score->score = score->total;
+		score->score = score->total - warnings;
 	}
 }
 

+ 19 - 14
tools/ccanlint/tests/compile_test_helpers.c

@@ -21,18 +21,14 @@ static const char *can_run(struct manifest *m)
 	return NULL;
 }
 
-static char *compile(struct manifest *m,
-		     bool keep,
-		     struct ccan_file *cfile)
+static bool compile(struct manifest *m,
+		    bool keep,
+		    struct ccan_file *cfile,
+		    char **output)
 {
-	char *output;
 	cfile->compiled = maybe_temp_file(m, ".o", keep, cfile->fullname);
-	if (compile_object(m, cfile->fullname, ccan_dir, "",
-			   cfile->compiled, &output)) {
-		talloc_free(output);
-		return NULL;
-	}
-	return output;
+	return compile_object(m, cfile->fullname, ccan_dir, "",
+			      cfile->compiled, output);
 }
 
 static void do_compile_test_helpers(struct manifest *m,
@@ -41,21 +37,30 @@ static void do_compile_test_helpers(struct manifest *m,
 				    struct score *score)
 {
 	struct ccan_file *i;
+	bool errors = false, warnings = false;
 
 	if (list_empty(&m->other_test_c_files))
 		score->total = 0;
+	else
+		score->total = 2;
 
 	list_for_each(&m->other_test_c_files, i, list) {
-		char *cmdout = compile(m, keep, i);
-		if (cmdout) {
+		char *cmdout;
+
+		if (!compile(m, keep, i, &cmdout)) {
+			errors = true;
 			score->error = "Failed to compile helper C files";
 			score_file_error(score, i, 0, cmdout);
+		} else if (!streq(cmdout, "")) {
+			warnings = true;
+			score->error = "Helper C files gave warnings";
+			score_file_error(score, i, 0, cmdout);
 		}
 	}
 
-	if (!score->error) {
+	if (!errors) {
 		score->pass = true;
-		score->score = score->total;
+		score->score = score->total - warnings;
 	}
 }
 

+ 37 - 40
tools/ccanlint/tests/compile_tests.c

@@ -2,6 +2,7 @@
 #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>
@@ -61,25 +62,22 @@ static char *lib_list(const struct manifest *m)
 	return ret;
 }
 
-static char *compile(const void *ctx,
-		     struct manifest *m,
-		     struct ccan_file *file,
-		     bool fail,
-		     bool link_with_module,
-		     bool keep)
+static bool compile(const void *ctx,
+		    struct manifest *m,
+		    struct ccan_file *file,
+		    bool fail,
+		    bool link_with_module,
+		    bool keep, char **output)
 {
-	char *errmsg;
-
 	file->compiled = maybe_temp_file(ctx, "", keep, file->fullname);
 	if (!compile_and_link(ctx, file->fullname, ccan_dir,
 			      obj_list(m, link_with_module),
 			      fail ? "-DFAIL" : "",
-			      lib_list(m), file->compiled, &errmsg)) {
+			      lib_list(m), file->compiled, output)) {
 		talloc_free(file->compiled);
-		return errmsg;
+		return false;
 	}
-	talloc_free(errmsg);
-	return NULL;
+	return true;
 }
 
 static void do_compile_tests(struct manifest *m,
@@ -88,44 +86,42 @@ static void do_compile_tests(struct manifest *m,
 {
 	char *cmdout;
 	struct ccan_file *i;
-
-	list_for_each(&m->compile_ok_tests, i, list) {
-		cmdout = compile(score, m, i, false, false, keep);
-		if (cmdout) {
-			score->error = "Failed to compile tests";
-			score_file_error(score, i, 0, cmdout);
-		}
-	}
-
-	list_for_each(&m->run_tests, i, list) {
-		cmdout = compile(score, m, i, false, false, keep);
-		if (cmdout) {
-			score->error = "Failed to compile tests";
-			score_file_error(score, i, 0, cmdout);
-		}
-	}
-
-	list_for_each(&m->api_tests, i, list) {
-		cmdout = compile(score, m, i, false, true, keep);
-		if (cmdout) {
-			score->error = "Failed to compile tests";
-			score_file_error(score, i, 0, cmdout);
+	struct list_head *list;
+	bool errors = false, warnings = false;
+
+	foreach_ptr(list, &m->compile_ok_tests, &m->run_tests, &m->api_tests) {
+		list_for_each(list, i, list) {
+			if (!compile(score, m, i, false, list == &m->api_tests,
+				     keep, &cmdout)) {
+				score->error = "Failed to compile tests";
+				score_file_error(score, i, 0, cmdout);
+				errors = true;
+			} else if (!streq(cmdout, "")) {
+				score->error = "Test compiled with warnings";
+				score_file_error(score, i, 0, cmdout);
+				warnings = true;
+			}
 		}
 	}
 
 	/* The compile fail tests are a bit weird, handle them separately */
-	if (score->error)
+	if (errors)
 		return;
 
+	/* For historical reasons, "fail" often means "gives warnings" */
 	list_for_each(&m->compile_fail_tests, i, list) {
-		cmdout = compile(score, m, i, false, false, false);
-		if (cmdout) {
+		if (!compile(score, m, i, false, false, false, &cmdout)) {
 			score->error = "Failed to compile without -DFAIL";
 			score_file_error(score, i, 0, cmdout);
 			return;
 		}
-		cmdout = compile(score, m, i, true, false, false);
-		if (!cmdout) {
+		if (!streq(cmdout, "")) {
+			score->error = "Compile with warnigns without -DFAIL";
+			score_file_error(score, i, 0, cmdout);
+			return;
+		}
+		if (compile(score, m, i, true, false, false, &cmdout)
+		    && streq(cmdout, "")) {
 			score->error = "Compiled successfully with -DFAIL?";
 			score_file_error(score, i, 0, NULL);
 			return;
@@ -133,7 +129,8 @@ static void do_compile_tests(struct manifest *m,
 	}
 
 	score->pass = true;
-	score->score = score->total;
+	score->total = 2;
+	score->score = 1 + !warnings;
 }
 
 struct ccanlint compile_tests = {

+ 117 - 62
tools/ccanlint/tests/examples_compile.c

@@ -111,23 +111,20 @@ static char *lib_list(const struct manifest *m)
 	return ret;
 }
 
-static char *compile(const void *ctx,
-		     struct manifest *m,
-		     struct ccan_file *file,
-		     bool keep)
+static bool compile(const void *ctx,
+		    struct manifest *m,
+		    struct ccan_file *file,
+		    bool keep, char **output)
 {
-	char *errmsg;
-
 	file->compiled = maybe_temp_file(ctx, "", keep, file->fullname);
 	if (!compile_and_link(ctx, file->fullname, ccan_dir,
 			      obj_list(m, file),
-			      "", lib_list(m), file->compiled, &errmsg)) {
+			      "", lib_list(m), file->compiled, output)) {
 		talloc_free(file->compiled);
 		file->compiled = NULL;
-		return errmsg;
+		return false;
 	}
-	talloc_free(errmsg);
-	return NULL;
+	return true;
 }
 
 static char *start_main(char *ret, const char *why)
@@ -383,7 +380,7 @@ static char *mangle(struct manifest *m, char **lines)
 		ret = talloc_asprintf_append(ret,
 					     "/* Get rid of unused warnings"
 					     " by printing addresses of"
-					     " static funcs. */");
+					     " static funcs. */\n");
 		if (!fake_function) {
 			ret = talloc_asprintf_append(ret,
 						     "int use_funcs(void);\n"
@@ -448,90 +445,148 @@ static bool has_expected_output(char **lines)
 	return false;
 }
 
+static unsigned int try_compiling(struct manifest *m,
+				  struct ccan_file *i,
+				  char **prev,
+				  bool keep,
+				  struct ccan_file *mangled[3],
+				  bool res[3],
+				  char *err[3],
+				  char **lines[3])
+{
+	unsigned int num;
+
+	/* Try standalone. */
+	mangled[0] = i;
+	res[0] = compile(i, m, mangled[0], keep, &err[0]);
+	lines[0] = get_ccan_file_lines(i);
+	if (res[0] && streq(err[0], ""))
+		return 1;
+
+	if (prev) {
+		lines[1] = combine(i, get_ccan_file_lines(i), prev);
+
+		mangled[1] = mangle_example(m, i, lines[1], keep);
+		res[1] = compile(i, m, mangled[1], keep, &err[1]);
+		if (res[1] && streq(err[1], "")) {
+			return 2;
+		}
+		num = 2;
+	} else
+		num = 1;
+
+	/* Try standalone. */
+	lines[num] = get_ccan_file_lines(i);
+	mangled[num] = mangle_example(m, i, lines[num], keep);
+	res[num] = compile(i, m, mangled[num], keep, &err[num]);
+
+	return num+1;
+}
+
 static void build_examples(struct manifest *m, bool keep,
 			   unsigned int *timeleft, struct score *score)
 {
 	struct ccan_file *i;
 	char **prev = NULL;
+	bool warnings = false;
 
 	score->total = 0;
 	score->pass = true;
 
 	list_for_each(&m->examples, i, list) {
-		char *ret, *ret1, *ret2 = NULL;
-		struct ccan_file *mangle1, *mangle2 = NULL;
-		char *err;
+		char *err[3];
+		struct ccan_file *file[3] = { NULL, NULL, NULL };
+		bool res[3];
+		unsigned num, j;
+		char **lines[3];
+		char *error;
 
 		score->total++;
+
 		/* Simplify our dumb parsing. */
 		strip_leading_whitespace(get_ccan_file_lines(i));
-		ret = compile(i, m, i, keep);
-		if (!ret) {
-			char **lines = get_ccan_file_lines(i);
-			if (!has_expected_output(lines))
-				prev = lines;
-			score->score++;
-			continue;
-		}
 
-		if (prev) {
-			char **new = combine(i, get_ccan_file_lines(i), prev);
+		num = try_compiling(m, i, prev, keep, file, res, err, lines);
 
-			mangle2 = mangle_example(m, i, new, keep);
-			ret2 = compile(i, m, mangle2, keep);
-			if (!ret2) {
-				if (!has_expected_output(new))
-					prev = new;
+		/* First look for a compile without any warnings. */
+		for (j = 0; j < num; j++) {
+			if (res[j] && streq(err[j], "")) {
+				if (!has_expected_output(lines[j]))
+					prev = lines[j];
 				score->score++;
-				continue;
+				goto next;
 			}
 		}
 
-		/* Try standalone. */
-		mangle1 = mangle_example(m, i, get_ccan_file_lines(i), keep);
-		ret1 = compile(i, m, mangle1, keep);
-		if (!ret1) {
-			char **lines = get_ccan_file_lines(i);
-			if (!has_expected_output(lines))
-				prev = lines;
-			score->score++;
-			continue;
+		/* Now accept anything which succeeded. */
+		for (j = 0; j < num; j++) {
+			if (res[j]) {
+				if (!has_expected_output(lines[j]))
+					prev = lines[j];
+				score->score++;
+				warnings = true;
+				score->error = "Compiling extracted example"
+					" gave warnings";
+				score_file_error(score, file[j], 0, err[j]);
+				goto next;
+			}
 		}
 
 		score->pass = false;
 		score->error = "Compiling extracted examples failed";
 		if (!verbose) {
-			if (mangle2) 
-				err = "Standalone, adding headers, "
+			if (num == 3)
+				error = "Standalone, adding headers, "
 					"and including previous "
 					"example all failed";
 			else
-				err = "Standalone compile and"
+				error = "Standalone compile and"
 					" adding headers both failed";
 		} else {
-			err = talloc_asprintf(score,
-					      "Standalone example:\n"
-					      "%s\n"
-					      "Errors: %s\n\n"
-					      "Adding headers, wrappers:\n"
-					      "%s\n"
-					      "Errors: %s\n\n",
-					      get_ccan_file_contents(i),
-					      ret,
-					      get_ccan_file_contents(mangle1),
-					      ret1);
-
-			if (mangle2)
-				err = talloc_asprintf_append(err, 
-				       "Combining with previous example:\n"
-				       "%s\n"
-				       "Errors: %s\n\n",
-				       get_ccan_file_contents(mangle2),
-				       ret2);
+			if (num == 3) {
+				error = talloc_asprintf(score,
+				      "Standalone example:\n"
+				      "%s\n"
+				      "Errors: %s\n\n"
+				      "Combining with previous example:\n"
+				      "%s\n"
+				      "Errors: %s\n\n"
+				      "Adding headers, wrappers:\n"
+				      "%s\n"
+				      "Errors: %s\n\n",
+				      get_ccan_file_contents(file[0]),
+				      err[0],
+				      get_ccan_file_contents(file[1]),
+				      err[1],
+				      get_ccan_file_contents(file[2]),
+				      err[2]);
+			} else {
+				error = talloc_asprintf(score,
+				      "Standalone example:\n"
+				      "%s\n"
+				      "Errors: %s\n\n"
+				      "Adding headers, wrappers:\n"
+				      "%s\n"
+				      "Errors: %s\n\n",
+				      get_ccan_file_contents(file[0]),
+				      err[0],
+				      get_ccan_file_contents(file[1]),
+				      err[1]);
+			}
 		}
-		score_file_error(score, i, 0, err);
+		score_file_error(score, i, 0, error);
 		/* This didn't work, so not a candidate for combining. */
 		prev = NULL;
+
+	next:
+		;
+	}
+
+	/* An extra point if they all compiled without warnings. */
+	if (!list_empty(&m->examples)) {
+		score->total++;
+		if (!warnings)
+			score->score++;
 	}
 }
 

+ 1 - 1
tools/configurator/configurator.c

@@ -12,7 +12,7 @@
 #include <string.h>
 
 #define DEFAULT_COMPILER "cc"
-#define DEFAULT_FLAGS "-g -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition -Werror"
+#define DEFAULT_FLAGS "-g -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition"
 
 #define OUTPUT_FILE "configurator.out"
 #define INPUT_FILE "configuratortest.c"