2 #include <ccan/talloc/talloc.h>
3 #include <ccan/str/str.h>
4 #include <ccan/str_talloc/str_talloc.h>
5 #include <ccan/grab_file/grab_file.h>
6 #include <ccan/noerr/noerr.h>
15 char **get_ccan_file_lines(struct ccan_file *f)
18 char *buffer = grab_file(f, f->name, NULL);
20 err(1, "Getting file %s", f->name);
21 f->lines = strsplit(f, buffer, "\n", &f->num_lines);
26 struct list_head *get_ccan_file_docs(struct ccan_file *f)
28 if (!f->doc_sections) {
29 get_ccan_file_lines(f);
30 f->doc_sections = extract_doc_sections(f->lines, f->num_lines);
32 return f->doc_sections;
35 static void add_files(struct manifest *m, const char *dir)
45 err(1, "Opening directory %s", dir[0] ? dir : ".");
47 while ((ent = readdir(d)) != NULL) {
50 struct list_head *dest;
53 if (ent->d_name[0] == '.')
56 f = talloc(m, struct ccan_file);
58 f->doc_sections = NULL;
59 f->name = talloc_asprintf(f, "%s%s", dir, ent->d_name);
60 if (lstat(f->name, &st) != 0)
61 err(1, "lstat %s", f->name);
63 if (S_ISDIR(st.st_mode)) {
64 f->name = talloc_append_string(f->name, "/");
65 add_files(m, f->name);
68 if (!S_ISREG(st.st_mode)) {
73 if (streq(f->name, "_info.c")) {
78 is_c_src = strends(f->name, ".c");
79 if (!is_c_src && !strends(f->name, ".h"))
80 dest = &m->other_files;
81 else if (!strchr(f->name, '/')) {
86 } else if (strstarts(f->name, "test/")) {
88 if (strstarts(f->name, "test/run"))
90 else if (strstarts(f->name, "test/compile_ok"))
91 dest = &m->compile_ok_tests;
92 else if (strstarts(f->name, "test/compile_fail"))
93 dest = &m->compile_fail_tests;
95 dest = &m->other_test_files;
97 dest = &m->other_test_files;
99 dest = &m->other_files;
101 list_add(dest, &f->list);
106 char *report_on_lines(struct list_head *files,
107 char *(*report)(const char *),
112 list_for_each(files, f, list) {
114 char **lines = get_ccan_file_lines(f);
116 for (i = 0; i < f->num_lines; i++) {
117 char *r = report(lines[i]);
121 sofar = talloc_asprintf_append(sofar,
130 struct manifest *get_manifest(void)
132 struct manifest *m = talloc(NULL, struct manifest);
136 list_head_init(&m->c_files);
137 list_head_init(&m->h_files);
138 list_head_init(&m->run_tests);
139 list_head_init(&m->compile_ok_tests);
140 list_head_init(&m->compile_fail_tests);
141 list_head_init(&m->other_test_files);
142 list_head_init(&m->other_files);
144 /* *This* is why people hate C. */
146 m->basename = talloc_array(m, char, len);
147 while (!getcwd(m->basename, len)) {
149 err(1, "Getting current directory");
150 m->basename = talloc_realloc(m, m->basename, char, len *= 2);
153 len = strlen(m->basename);
154 while (len && m->basename[len-1] == '/')
155 m->basename[--len] = '\0';
157 m->basename = strrchr(m->basename, '/');
159 errx(1, "I don't expect to be run from the root directory");