X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fmanifest.c;h=fe3e4680b2d49117338def1e27bfc3b2ff58607e;hp=9de9030b2a0e71d6e18f95c36536fe98a4c5ad35;hb=c9d946d07ae9a270042bcfef2bccfa09de6bddd9;hpb=08eb7e5a370941feec1d556339a00608925f9cb2 diff --git a/tools/manifest.c b/tools/manifest.c index 9de9030b..fe3e4680 100644 --- a/tools/manifest.c +++ b/tools/manifest.c @@ -1,30 +1,26 @@ #include "config.h" #include "manifest.h" #include "tools.h" -#include #include -#include -#include +#include +#include #include #include -#include #include #include #include #include +#include #include #include #include #include -#include #include #include #include #include #include -const char *ccan_dir; - static size_t dir_hash(const char *name) { return hash(name, strlen(name), 0); @@ -47,7 +43,8 @@ static struct htable_manifest *manifests; const char *get_ccan_file_contents(struct ccan_file *f) { if (!f->contents) { - f->contents = grab_file(f, f->fullname, &f->contents_size); + f->contents = tal_grab_file(f, f->fullname, + &f->contents_size); if (!f->contents) err(1, "Reading file %s", f->fullname); } @@ -57,45 +54,50 @@ const char *get_ccan_file_contents(struct ccan_file *f) char **get_ccan_file_lines(struct ccan_file *f) { if (!f->lines) - f->lines = strsplit(f, get_ccan_file_contents(f), "\n"); + f->lines = tal_strsplit(f, get_ccan_file_contents(f), "\n", + STR_EMPTY_OK); - /* FIXME: is f->num_lines necessary? */ - f->num_lines = talloc_array_length(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; assert(dir[0] == '/'); - f = talloc(ctx, struct ccan_file); + f = tal(ctx, struct ccan_file); f->lines = NULL; f->line_info = NULL; f->doc_sections = NULL; for (i = 0; i < ARRAY_SIZE(f->compiled); i++) f->compiled[i] = NULL; - f->name = talloc_steal(f, name); - f->fullname = talloc_asprintf(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 = NULL; + 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; @@ -107,19 +109,19 @@ static void add_files(struct manifest *m, const char *dir) continue; f = new_ccan_file(m, m->dir, - talloc_asprintf(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 (lstat(f->fullname, &st) != 0) + err(1, "lstat %s", f->fullname); if (S_ISDIR(st.st_mode)) { - size_t len = talloc_array_length(subs); - subs = talloc_realloc(m, subs, char *, len+1); - subs[len] = talloc_append_string(f->name, "/"); + size_t len = tal_count(subs); + tal_resize(&subs, len+1); + subs[len] = tal_strcat(subs, f->name, "/"); continue; } if (!S_ISREG(st.st_mode)) { - talloc_free(f); + tal_free(f); continue; } @@ -158,7 +160,7 @@ 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 @@ -166,10 +168,10 @@ static void add_files(struct manifest *m, const char *dir) && 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]); + for (i = 0; i < tal_count(subs); i++) + add_files(m, base, subs[i]); } - talloc_free(subs); + tal_free(subs); } static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b, @@ -180,69 +182,44 @@ static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b, static void sort_files(struct list_head *list) { - struct ccan_file **files = NULL, *f; - unsigned int i, num; + struct ccan_file **files = tal_arr(NULL, struct ccan_file *, 0), *f; + unsigned int i; - num = 0; while ((f = list_top(list, struct ccan_file, list)) != NULL) { - files = talloc_realloc(NULL, files, struct ccan_file *, num+1); - files[num++] = f; + tal_expand(&files, &f, 1); list_del(&f->list); } - asort(files, num, cmp_names, NULL); + asort(files, tal_count(files), cmp_names, NULL); - for (i = 0; i < num; i++) + for (i = 0; i < tal_count(files); i++) list_add_tail(list, &files[i]->list); - talloc_free(files); -} - -/* Walk up tp find /ccan/ => ccan directory. */ -static unsigned int ccan_dir_prefix(const char *fulldir) -{ - unsigned int i; - - assert(fulldir[0] == '/'); - for (i = strlen(fulldir) - 1; i > 0; i--) { - if (strncmp(fulldir+i, "/ccan", 5) != 0) - continue; - if (fulldir[i+5] != '\0' && fulldir[i+5] != '/') - continue; - return i + 1; - } - errx(1, "Could not find /ccan/ dir in %s", fulldir); + tal_free(files); } 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; if (!manifests) { - manifests = talloc(NULL, struct htable_manifest); + manifests = tal(NULL, struct htable_manifest); htable_manifest_init(manifests); } - olddir = talloc_getcwd(NULL); - if (!olddir) - err(1, "Getting current directory"); - - if (chdir(dir) != 0) - err(1, "Failed to chdir to %s", dir); - - canon_dir = talloc_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 = talloc_linked(ctx, talloc(NULL, struct manifest)); + m = tal_linkable(tal(NULL, struct manifest)); m->info_file = NULL; m->compiled[COMPILE_NORMAL] = m->compiled[COMPILE_NOFEAT] = NULL; - m->dir = talloc_steal(m, canon_dir); + m->dir = tal_steal(m, canon_dir); list_head_init(&m->c_files); list_head_init(&m->h_files); list_head_init(&m->api_tests); @@ -255,7 +232,9 @@ struct manifest *get_manifest(const void *ctx, const char *dir) list_head_init(&m->examples); list_head_init(&m->mangled_examples); list_head_init(&m->deps); + list_head_init(&m->test_deps); + /* Trim trailing /. */ len = strlen(m->dir); while (len && m->dir[len-1] == '/') m->dir[--len] = '\0'; @@ -265,25 +244,17 @@ struct manifest *get_manifest(const void *ctx, const char *dir) errx(1, "I don't expect to be run from the root directory"); m->basename++; - if (!ccan_dir) { - unsigned int prefix = ccan_dir_prefix(m->dir); - - ccan_dir = talloc_strndup(NULL, m->dir, prefix); - } + 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, &m->compile_fail_tests) sort_files(list); - htable_manifest_add(manifests, m); - -done: - if (chdir(olddir) != 0) - err(1, "Returning to original directory '%s'", olddir); - talloc_free(olddir); + htable_manifest_add(manifests, tal_link(manifests, m)); return m; }