From: Rusty Russell Date: Tue, 1 Mar 2011 07:20:32 +0000 (+1030) Subject: ccanlint: check for #ifdef X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=9450cb3c1dff76e09305d18687291bce4221e9b6 ccanlint: check for #ifdef Old habits die hard; it's better to use #if than #ifdef ; they're similar, because undefined identifiers evaluate to zero, but with GCC's -Wundef flag you can detect mis-spelled or missing features with #if. autoconf-style config.h leave unset features undefined, so this works for those config.h too. --- diff --git a/tools/ccanlint/tests/hash_if.c b/tools/ccanlint/tests/hash_if.c new file mode 100644 index 00000000..3eefd1fd --- /dev/null +++ b/tools/ccanlint/tests/hash_if.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void check_hash_if(struct manifest *m, + bool keep, + unsigned int *timeleft, struct score *score) +{ + struct list_head *list; + const char *explanation = + "\n\t(#if works like #ifdef, but with gcc's -Wundef, we can detect\n" + "\tmistyped or unknown configuration options)"; + + foreach_ptr(list, &m->c_files, &m->h_files, + &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); + + for (i = 0; lines[i]; i++) { + const char *line = lines[i]; + char *sym; + + if (!get_token(&line, "#")) + continue; + if (!(get_token(&line, "if") + && get_token(&line, "defined") + && get_token(&line, "(")) + && !get_token(&line, "ifdef")) + continue; + + sym = get_symbol_token(lines, &line); + if (!sym || !strstarts(sym, "HAVE_")) + continue; + score_file_error(score, f, i+1, + "%s should be tested with #if" + "%s", + sym, explanation); + explanation = ""; + } + } + } + + if (!score->error) { + score->pass = true; + score->score = score->total; + } +} + +struct ccanlint hash_if = { + .key = "hash_if", + .name = "Features are checked with #if not #ifdef", + .check = check_hash_if, + .needs = "" +}; + +REGISTER_TEST(hash_if);