X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ffile_analysis.c;h=7ce65479bde929cb3e036ff73514522a9f4cddad;hp=985f259b24c3ac87821a614f01ce0ec63e9d1a89;hb=e8c85e38cc6e0094c8d9e286e1706756035b95e0;hpb=100444225380d3f5ca29424ea54703d308c7c651 diff --git a/tools/ccanlint/file_analysis.c b/tools/ccanlint/file_analysis.c index 985f259b..7ce65479 100644 --- a/tools/ccanlint/file_analysis.c +++ b/tools/ccanlint/file_analysis.c @@ -1,3 +1,4 @@ +#include "config.h" #include "ccanlint.h" #include #include @@ -92,6 +93,7 @@ static void add_files(struct manifest *m, const char *dir) { DIR *d; struct dirent *ent; + char **subs = NULL; if (dir[0]) d = opendir(dir); @@ -116,8 +118,9 @@ static void add_files(struct manifest *m, const char *dir) err(1, "lstat %s", f->name); if (S_ISDIR(st.st_mode)) { - f->name = talloc_append_string(f->name, "/"); - add_files(m, f->name); + size_t len = talloc_array_length(subs); + subs = talloc_realloc(m, subs, char *, len+1); + subs[len] = talloc_append_string(f->name, "/"); continue; } if (!S_ISREG(st.st_mode)) { @@ -133,10 +136,7 @@ static void add_files(struct manifest *m, const char *dir) is_c_src = strends(f->name, ".c"); if (!is_c_src && !strends(f->name, ".h")) { dest = &m->other_files; - continue; - } - - if (!strchr(f->name, '/')) { + } else if (!strchr(f->name, '/')) { if (is_c_src) dest = &m->c_files; else @@ -161,6 +161,20 @@ static void add_files(struct manifest *m, const char *dir) list_add(dest, &f->list); } closedir(d); + + /* Before we recurse, sanity check this is a ccan module. */ + if (!dir[0]) { + size_t i; + + if (!m->info_file + && list_empty(&m->c_files) + && list_empty(&m->h_files)) + errx(1, "No _info, C or H files found here!"); + + for (i = 0; i < talloc_array_length(subs); i++) + add_files(m, subs[i]); + } + talloc_free(subs); } static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b, @@ -240,12 +254,17 @@ struct manifest *get_manifest(const void *ctx, const char *dir) /* We expect the ccan dir to be two levels above module dir. */ if (!ccan_dir) { - char *p; - ccan_dir = talloc_strdup(NULL, m->dir); - p = strrchr(ccan_dir, '/'); + char *p, *dir; + dir = talloc_strdup(NULL, m->dir); + p = strrchr(dir, '/'); + if (!p) + errx(1, "I expect the ccan root directory in ../.."); *p = '\0'; - p = strrchr(ccan_dir, '/'); + p = strrchr(dir, '/'); + if (!p) + errx(1, "I expect the ccan root directory in ../.."); *p = '\0'; + ccan_dir = dir; } add_files(m, ""); @@ -344,7 +363,7 @@ bool get_token(const char **line, const char *token) unsigned int toklen; *line += strspn(*line, " \t"); - if (isalnum(token[0]) || token[0] == '_') + if (cisalnum(token[0]) || token[0] == '_') toklen = strspn(*line, IDENT_CHARS); else { /* FIXME: real tokenizer handles ++ and other multi-chars. */ @@ -386,6 +405,17 @@ static bool parse_hash_if(struct pp_conditions *cond, const char **line) return false; if (!defined) cond->type = PP_COND_IF; + + /* FIXME: We just chain them, ignoring operators. */ + if (get_token(line, "||") || get_token(line, "&&")) { + struct pp_conditions *sub = talloc(cond, struct pp_conditions); + + sub->parent = cond->parent; + sub->type = PP_COND_IFDEF; + if (parse_hash_if(sub, line)) + cond->parent = sub; + } + return true; }