X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ftests%2Fidempotent.c;fp=tools%2Fccanlint%2Ftests%2Fidempotent.c;h=0000000000000000000000000000000000000000;hp=340a0698ac6aecbcb8baf85d231ce4e4d8d978fc;hb=051db34fb275491d4d5dfa5bf7970e8e525766d8;hpb=2926cafb52b9d95646d9dafa877d53f2368d8b2c diff --git a/tools/ccanlint/tests/idempotent.c b/tools/ccanlint/tests/idempotent.c deleted file mode 100644 index 340a0698..00000000 --- a/tools/ccanlint/tests/idempotent.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char explain[] -= "Headers usually start with the C preprocessor lines to prevent multiple\n" - "inclusions. These look like the following:\n" - "#ifndef CCAN__H\n" - "#define CCAN__H\n" - "...\n" - "#endif /* CCAN__H */\n"; - -static void fix_name(char *name) -{ - unsigned int i; - - for (i = 0; name[i]; i++) { - if (isalnum(name[i])) - name[i] = toupper(name[i]); - else - name[i] = '_'; - } -} - -static void handle_idem(struct manifest *m, struct score *score) -{ - struct file_error *e; - - list_for_each(&score->per_file_errors, e, list) { - char *name, *q, *tmpname; - FILE *out; - unsigned int i; - - /* Main header gets CCAN_FOO_H, others CCAN_FOO_XXX_H */ - if (strstarts(e->file->name, m->basename) - || strlen(e->file->name) == strlen(m->basename) + 2) - name = talloc_asprintf(score, "CCAN_%s_H", m->basename); - else - name = talloc_asprintf(score, "CCAN_%s_%s", - m->basename, e->file->name); - fix_name(name); - - q = talloc_asprintf(score, - "Should I wrap %s in #ifndef/#define %s for you?", - e->file->name, name); - if (!ask(q)) - continue; - - tmpname = maybe_temp_file(score, ".h", false, e->file->name); - out = fopen(tmpname, "w"); - if (!out) - err(1, "Opening %s", tmpname); - if (fprintf(out, "#ifndef %s\n#define %s\n", name, name) < 0) - err(1, "Writing %s", tmpname); - - for (i = 0; i < e->file->num_lines; i++) - if (fprintf(out, "%s\n", e->file->lines[i]) < 0) - err(1, "Writing %s", tmpname); - - if (fprintf(out, "#endif /* %s */\n", name) < 0) - err(1, "Writing %s", tmpname); - - if (fclose(out) != 0) - err(1, "Closing %s", tmpname); - - if (!move_file(tmpname, e->file->fullname)) - err(1, "Moving %s to %s", tmpname, e->file->fullname); - } -} - -static bool check_idem(struct ccan_file *f, struct score *score) -{ - struct line_info *line_info; - unsigned int i, first_preproc_line; - const char *line, *sym; - - line_info = get_ccan_line_info(f); - if (f->num_lines < 3) - /* FIXME: We assume small headers probably uninteresting. */ - return true; - - for (i = 0; i < f->num_lines; i++) { - if (line_info[i].type == DOC_LINE - || line_info[i].type == COMMENT_LINE) - continue; - if (line_info[i].type == CODE_LINE) { - score_file_error(score, f, i+1, - "Expect first non-comment line to be" - " #ifndef."); - return false; - } else if (line_info[i].type == PREPROC_LINE) - break; - } - - /* No code at all? Don't complain. */ - if (i == f->num_lines) - return true; - - first_preproc_line = i; - for (i = first_preproc_line+1; i < f->num_lines; i++) { - if (line_info[i].type == DOC_LINE - || line_info[i].type == COMMENT_LINE) - continue; - if (line_info[i].type == CODE_LINE) { - score_file_error(score, f, i+1, - "Expect second non-comment line to be" - " #define."); - return false; - } else if (line_info[i].type == PREPROC_LINE) - break; - } - - /* No code at all? Weird. */ - if (i == f->num_lines) - return true; - - /* We expect a condition on this line. */ - if (!line_info[i].cond) { - score_file_error(score, f, i+1, "Expected #ifndef"); - return false; - } - - line = f->lines[i]; - - /* We expect the condition to be ! IFDEF . */ - if (line_info[i].cond->type != PP_COND_IFDEF - || !line_info[i].cond->inverse) { - score_file_error(score, f, i+1, "Expected #ifndef"); - return false; - } - - /* And this to be #define */ - if (!get_token(&line, "#")) - abort(); - if (!get_token(&line, "define")) { - char *str = talloc_asprintf(score, - "expected '#define %s'", - line_info[i].cond->symbol); - score_file_error(score, f, i+1, str); - return false; - } - sym = get_symbol_token(f, &line); - if (!sym || !streq(sym, line_info[i].cond->symbol)) { - char *str = talloc_asprintf(score, - "expected '#define %s'", - line_info[i].cond->symbol); - score_file_error(score, f, i+1, str); - return false; - } - - /* Rest of code should all be covered by that conditional. */ - for (i++; i < f->num_lines; i++) { - unsigned int val = 0; - if (line_info[i].type == DOC_LINE - || line_info[i].type == COMMENT_LINE) - continue; - if (get_ccan_line_pp(line_info[i].cond, sym, &val, NULL) - != NOT_COMPILED) { - score_file_error(score, f, i+1, "code outside" - " idempotent region"); - return false; - } - } - - return true; -} - -static void check_idempotent(struct manifest *m, - bool keep, - unsigned int *timeleft, struct score *score) -{ - struct ccan_file *f; - - list_for_each(&m->h_files, f, list) { - if (!check_idem(f, score)) - score->error = "Headers are not idempotent"; - } - if (!score->error) { - score->pass = true; - score->score = score->total; - } -} - -struct ccanlint headers_idempotent = { - .key = "headers_idempotent", - .name = "Module headers are #ifndef/#define wrapped", - .check = check_idempotent, - .handle = handle_idem, - .needs = "" -}; - -REGISTER_TEST(headers_idempotent);