int fd;
struct ccan_file *f;
- name = maybe_temp_file(m, ".c", keep,
- talloc_asprintf(m, "example-%s-%s",
- source->name,
- example->function));
+ name = talloc_asprintf(m, "%s/example-%s-%s.c",
+ talloc_dirname(m,
+ source->fullname),
+ source->name,
+ example->function);
+ /* example->function == 'struct foo' */
+ while (strchr(name, ' '))
+ *strchr(name, ' ') = '_';
+
+ name = maybe_temp_file(m, ".c", keep, name);
f = new_ccan_file(m, talloc_dirname(m, name), talloc_basename(m, name));
talloc_steal(f, name);
- list_add(&m->examples, &f->list);
+ list_add_tail(&m->examples, &f->list);
fd = open(f->fullname, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0)
}
/* FIXME: We should have one example per function in header. */
-struct score {
- bool info_example, header_example;
- char *error;
-};
-
-static void *extract_examples(struct manifest *m,
- bool keep,
- unsigned int *timeleft)
+static void extract_examples(struct manifest *m,
+ bool keep,
+ unsigned int *timeleft,
+ struct score *score)
{
- struct ccan_file *f;
+ struct ccan_file *f, *mainh = NULL; /* gcc complains uninitialized */
struct doc_section *d;
- struct score *score = talloc(m, struct score);
-
- score->info_example = score->header_example = false;
- score->error = NULL;
+ bool have_info_example = false, have_header_example = false;
+ score->total = 2;
list_for_each(get_ccan_file_docs(m->info_file), d, list) {
if (streq(d->type, "example")) {
- score->error = add_example(m, m->info_file, keep, d);;
+ score->error = add_example(m, m->info_file, keep, d);
if (score->error)
- return score;
- score->info_example = true;
+ return;
+ have_info_example = true;
}
}
|| strlen(f->name) != strlen(m->basename) + 2)
continue;
+ mainh = f;
list_for_each(get_ccan_file_docs(f), d, list) {
if (streq(d->type, "example")) {
score->error = add_example(m, f, keep, d);
if (score->error)
- return score;
- score->header_example = true;
+ return;
+ have_header_example = true;
}
}
}
- return score;
-}
-
-static unsigned int score_examples(struct manifest *m, void *check_result)
-{
- struct score *score = check_result;
- int total = 0;
- if (score->error)
- return 0;
- total += score->info_example;
- total += score->header_example;
- return total;
-}
-
-static const char *describe_examples(struct manifest *m,
- void *check_result)
-{
- struct score *score = check_result;
- char *descrip = NULL;
-
- if (score->error)
- return score->error;
-
- if (!score->info_example)
- descrip = talloc_asprintf(score,
- "Your _info file has no module example.\n\n"
- "There should be an Example: section of the _info documentation\n"
- "which provides a concise toy program which uses your module\n");
+ if (have_info_example && have_header_example) {
+ score->score = score->total;
+ score->pass = true;
+ return;
+ }
- if (!score->header_example)
- descrip = talloc_asprintf(score,
- "%sMain header file file has no examples\n\n"
- "There should be an Example: section for each public function\n"
- "demonstrating its use\n", descrip ? descrip : "");
+ score->error = "Expect examples in header and _info";
+ if (!have_info_example)
+ score_file_error(score, m->info_file, 0, "No Example: section");
+ if (!have_header_example)
+ score_file_error(score, mainh, 0, "No Example: section");
- return descrip;
+ score->score = have_info_example + have_header_example;
+ /* We pass if we find any example. */
+ score->pass = score->score != 0;
}
struct ccanlint has_examples = {
.key = "has-examples",
.name = "_info and header files have examples",
- .score = score_examples,
.check = extract_examples,
- .describe = describe_examples,
- .total_score = 2,
};
REGISTER_TEST(has_examples, &has_info, NULL);