X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Fidempotent.c;h=38d48d8319676e9044ca631a423559d7657e3d11;hp=81984ec713198abed4f94baa88a421d7f9efa042;hb=f3505f82c0fdc9daac85d2cb2c6338a0292033e7;hpb=7beaa3448fa8e6015798c1609f33d96e8986063d diff --git a/tools/ccanlint/idempotent.c b/tools/ccanlint/idempotent.c index 81984ec7..38d48d83 100644 --- a/tools/ccanlint/idempotent.c +++ b/tools/ccanlint/idempotent.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include "../tools.h" static const char explain[] = "Headers usually start with the C preprocessor lines to prevent multiple\n" @@ -20,26 +22,81 @@ static const char explain[] "...\n" "#endif /* MY_HEADER_H */\n"; +static char *get_ifndef_sym(char *line) +{ + line += strspn(line, SPACE_CHARS); + if (line[0] == '#') + { + line++; + line += strspn(line, SPACE_CHARS); + if (strstarts(line, "ifndef") && isspace(line[6])) + return line+6+strspn(line+6, SPACE_CHARS); + else if (strstarts(line, "if")) + { + line += 2; + line += strspn(line, SPACE_CHARS); + if (line[0] == '!') + { + line++; + line += strspn(line, SPACE_CHARS); + if (strstarts(line, "defined")) + { + line += 7; + line += strspn(line, SPACE_CHARS); + if (line[0] == '(') + { + line++; + line += strspn(line, + SPACE_CHARS); + } + return line; + } + } + } + } + return NULL; +} + +static int is_define(char *line, char *id, size_t id_len) +{ + line += strspn(line, SPACE_CHARS); + if (line[0] == '#') + { + line++; + line += strspn(line, SPACE_CHARS); + if (strstarts(line, "define") && isspace(line[6])) + { + line += 6; + line += strspn(line, SPACE_CHARS); + if (strspn(line, IDENT_CHARS) == id_len && + memcmp(id, line, id_len) == 0) + return 1; + } + } + return 0; +} + static char *report_idem(struct ccan_file *f, char *sofar) { char **lines; - char *secondline; + char *id; + size_t id_len; lines = get_ccan_file_lines(f); if (f->num_lines < 3) /* FIXME: We assume small headers probably uninteresting. */ return NULL; - if (!strstarts(lines[0], "#ifndef ")) + id = get_ifndef_sym(lines[0]); + if (!id) return talloc_asprintf_append(sofar, "%s:1:expect first line to be #ifndef.\n", f->name); + id_len = strspn(id, IDENT_CHARS); - secondline = talloc_asprintf(f, "#define %s", - lines[0] + strlen("#ifndef ")); - if (!streq(lines[1], secondline)) + if (!is_define(lines[1], id, id_len)) return talloc_asprintf_append(sofar, - "%s:2:expect second line to be '%s'.\n", - f->name, secondline); + "%s:2:expect second line to be '#define %.*s'.\n", + f->name, (int)id_len, id); return sofar; }