X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fmanifest.c;h=82668acfed05fd43eab6b59c7d61dba4f258652f;hp=f7f86f74955548bd2c1f5568f851023b5e0e04c3;hb=HEAD;hpb=dc8042b42500f79f613b1197df6cdf739615a89f diff --git a/tools/manifest.c b/tools/manifest.c index f7f86f74..82668acf 100644 --- a/tools/manifest.c +++ b/tools/manifest.c @@ -3,6 +3,8 @@ #include "tools.h" #include #include +#include +#include #include #include #include @@ -42,10 +44,10 @@ static struct htable_manifest *manifests; const char *get_ccan_file_contents(struct ccan_file *f) { if (!f->contents) { - f->contents = tal_grab_file(f, f->fullname, - &f->contents_size); + f->contents = grab_file(f, f->fullname); if (!f->contents) err(1, "Reading file %s", f->fullname); + f->contents_size = tal_count(f->contents) - 1; } return f->contents; } @@ -56,12 +58,11 @@ char **get_ccan_file_lines(struct ccan_file *f) f->lines = tal_strsplit(f, get_ccan_file_contents(f), "\n", STR_EMPTY_OK); - /* FIXME: is f->num_lines necessary? */ - f->num_lines = tal_count(f->lines) - 1; return f->lines; } -struct ccan_file *new_ccan_file(const void *ctx, const char *dir, char *name) +struct ccan_file *new_ccan_file(const void *ctx, const char *dir, + const char *name) { struct ccan_file *f; unsigned int i; @@ -74,25 +75,30 @@ struct ccan_file *new_ccan_file(const void *ctx, const char *dir, char *name) f->doc_sections = NULL; for (i = 0; i < ARRAY_SIZE(f->compiled); i++) f->compiled[i] = NULL; - f->name = tal_steal(f, name); - f->fullname = tal_fmt(f, "%s/%s", dir, f->name); + f->name = tal_strdup(f, name); + f->fullname = path_join(f, dir, f->name); f->contents = NULL; f->simplified = NULL; + f->idempotent_cond = NULL; + return f; } -static void add_files(struct manifest *m, const char *dir) +static void add_files(struct manifest *m, const char *base, const char *subdir) { DIR *d; struct dirent *ent; char **subs = tal_arr(m, char *, 0); + const char *thisdir; - if (dir[0]) - d = opendir(dir); + if (!subdir) + thisdir = base; else - d = opendir("."); + thisdir = path_join(subs, base, subdir); + + d = opendir(thisdir); if (!d) - err(1, "Opening directory %s", dir[0] ? dir : "."); + err(1, "Opening directory %s", thisdir); while ((ent = readdir(d)) != NULL) { struct stat st; @@ -104,9 +110,10 @@ static void add_files(struct manifest *m, const char *dir) continue; f = new_ccan_file(m, m->dir, - tal_fmt(m, "%s%s", dir, ent->d_name)); - if (lstat(f->name, &st) != 0) - err(1, "lstat %s", f->name); + subdir ? path_join(m, subdir, ent->d_name) + : ent->d_name); + if (stat(f->fullname, &st) != 0) + err(1, "stat %s", f->fullname); if (S_ISDIR(st.st_mode)) { size_t len = tal_count(subs); @@ -154,22 +161,29 @@ static void add_files(struct manifest *m, const char *dir) closedir(d); /* Before we recurse, sanity check this is a ccan module. */ - if (!dir[0]) { + if (!subdir) { 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 < tal_count(subs); i++) - add_files(m, subs[i]); + errx(1, "No _info, C or H files found in %s", thisdir); + + /* Don't enter subdirs with _info: they're separate modules. */ + for (i = 0; i < tal_count(subs); i++) { + struct stat st; + char *subinfo = path_join(subs, base, + path_join(subs, subs[i], + "_info")); + if (lstat(subinfo, &st) != 0) + add_files(m, base, subs[i]); + } } tal_free(subs); } static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b, - void *unused) + void *unused UNNEEDED) { return strcmp((*a)->name, (*b)->name); } @@ -193,7 +207,7 @@ static void sort_files(struct list_head *list) struct manifest *get_manifest(const void *ctx, const char *dir) { struct manifest *m; - char *olddir, *canon_dir; + char *canon_dir; unsigned int len; struct list_head *list; @@ -202,20 +216,14 @@ struct manifest *get_manifest(const void *ctx, const char *dir) htable_manifest_init(manifests); } - olddir = tal_getcwd(NULL); - if (!olddir) - err(1, "Getting current directory"); - - if (chdir(dir) != 0) - err(1, "Failed to chdir to %s", dir); - - canon_dir = tal_getcwd(olddir); + canon_dir = path_canon(ctx, dir); if (!canon_dir) - err(1, "Getting current directory"); + err(1, "Getting canonical version of directory %s", dir); m = htable_manifest_get(manifests, canon_dir); if (m) - goto done; + return m; + m = tal_linkable(tal(NULL, struct manifest)); m->info_file = NULL; m->compiled[COMPILE_NORMAL] = m->compiled[COMPILE_NOFEAT] = NULL; @@ -247,7 +255,7 @@ struct manifest *get_manifest(const void *ctx, const char *dir) assert(strstarts(m->dir, find_ccan_dir(m->dir))); m->modname = m->dir + strlen(find_ccan_dir(m->dir)) + strlen("ccan/"); - add_files(m, ""); + add_files(m, canon_dir, NULL); /* Nicer to run tests in a predictable order. */ foreach_ptr(list, &m->api_tests, &m->run_tests, &m->compile_ok_tests, @@ -256,10 +264,5 @@ struct manifest *get_manifest(const void *ctx, const char *dir) htable_manifest_add(manifests, tal_link(manifests, m)); -done: - if (chdir(olddir) != 0) - err(1, "Returning to original directory '%s'", olddir); - tal_free(olddir); - return m; }