X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ftests%2Fheaders_idempotent.c;h=79e5c367d3a35d0dc4c433605a83512e17dee9c8;hp=340a0698ac6aecbcb8baf85d231ce4e4d8d978fc;hb=HEAD;hpb=051db34fb275491d4d5dfa5bf7970e8e525766d8 diff --git a/tools/ccanlint/tests/headers_idempotent.c b/tools/ccanlint/tests/headers_idempotent.c index 340a0698..79e5c367 100644 --- a/tools/ccanlint/tests/headers_idempotent.c +++ b/tools/ccanlint/tests/headers_idempotent.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -14,20 +13,12 @@ #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])) + if (cisalnum(name[i])) name[i] = toupper(name[i]); else name[i] = '_'; @@ -46,26 +37,26 @@ static void handle_idem(struct manifest *m, struct score *score) /* 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); + name = tal_fmt(score, "CCAN_%s_H", m->modname); else - name = talloc_asprintf(score, "CCAN_%s_%s", - m->basename, e->file->name); + name = tal_fmt(score, "CCAN_%s_%s", + m->modname, e->file->name); fix_name(name); - q = talloc_asprintf(score, + q = tal_fmt(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); + tmpname = temp_file(score, ".h", 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++) + for (i = 0; e->file->lines[i]; i++) if (fprintf(out, "%s\n", e->file->lines[i]) < 0) err(1, "Writing %s", tmpname); @@ -80,18 +71,18 @@ static void handle_idem(struct manifest *m, struct score *score) } } -static bool check_idem(struct ccan_file *f, struct score *score) +static void 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) + if (tal_count(f->lines) < 4) /* FIXME: We assume small headers probably uninteresting. */ - return true; + return; - for (i = 0; i < f->num_lines; i++) { + for (i = 0; f->lines[i]; i++) { if (line_info[i].type == DOC_LINE || line_info[i].type == COMMENT_LINE) continue; @@ -99,17 +90,17 @@ static bool check_idem(struct ccan_file *f, struct score *score) score_file_error(score, f, i+1, "Expect first non-comment line to be" " #ifndef."); - return false; + return; } else if (line_info[i].type == PREPROC_LINE) break; } /* No code at all? Don't complain. */ - if (i == f->num_lines) - return true; + if (!f->lines[i]) + return; first_preproc_line = i; - for (i = first_preproc_line+1; i < f->num_lines; i++) { + for (i = first_preproc_line+1; f->lines[i]; i++) { if (line_info[i].type == DOC_LINE || line_info[i].type == COMMENT_LINE) continue; @@ -117,19 +108,20 @@ static bool check_idem(struct ccan_file *f, struct score *score) score_file_error(score, f, i+1, "Expect second non-comment line to be" " #define."); - return false; + return; } else if (line_info[i].type == PREPROC_LINE) break; } /* No code at all? Weird. */ - if (i == f->num_lines) - return true; + if (!f->lines[i]) + return; - /* We expect a condition on this line. */ + /* We expect a condition around this line. */ if (!line_info[i].cond) { - score_file_error(score, f, i+1, "Expected #ifndef"); - return false; + score_file_error(score, f, first_preproc_line+1, + "Expected #ifndef"); + return; } line = f->lines[i]; @@ -137,31 +129,33 @@ static bool check_idem(struct ccan_file *f, struct score *score) /* 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; + score_file_error(score, f, first_preproc_line+1, + "Expected #ifndef"); + return; } /* 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; + score_file_error(score, f, i+1, + "expected '#define %s'", + line_info[i].cond->symbol); + return; } 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; + score_file_error(score, f, i+1, + "expected '#define %s'", + line_info[i].cond->symbol); + return; } + /* Record this for use in depends_accurate */ + f->idempotent_cond = line_info[i].cond; + /* Rest of code should all be covered by that conditional. */ - for (i++; i < f->num_lines; i++) { + for (i++; f->lines[i]; i++) { unsigned int val = 0; if (line_info[i].type == DOC_LINE || line_info[i].type == COMMENT_LINE) @@ -170,25 +164,24 @@ static bool check_idem(struct ccan_file *f, struct score *score) != NOT_COMPILED) { score_file_error(score, f, i+1, "code outside" " idempotent region"); - return false; + return; } } - - return true; } static void check_idempotent(struct manifest *m, - bool keep, - unsigned int *timeleft, struct score *score) + unsigned int *timeleft UNNEEDED, + struct score *score) { struct ccan_file *f; + /* We don't fail ccanlint for this. */ + score->pass = true; + list_for_each(&m->h_files, f, list) { - if (!check_idem(f, score)) - score->error = "Headers are not idempotent"; + check_idem(f, score); } if (!score->error) { - score->pass = true; score->score = score->total; } } @@ -198,7 +191,7 @@ struct ccanlint headers_idempotent = { .name = "Module headers are #ifndef/#define wrapped", .check = check_idempotent, .handle = handle_idem, - .needs = "" + .needs = "info_exists main_header_exists" }; REGISTER_TEST(headers_idempotent);