printf("%s%s", score->error,
strends(score->error, "\n") ? "" : "\n");
}
- if (!quiet && !score->pass && i->handle)
- i->handle(m, score);
}
+ if (!quiet && score->score < score->total && i->handle)
+ i->handle(m, score);
*running_score += score->score;
*running_total += score->total;
int main(int argc, char *argv[])
{
- bool summary = false;
+ bool summary = false, pass = true;
unsigned int score = 0, total_score = 0;
struct manifest *m;
struct ccanlint *i;
add_info_options(m->info_file, !target);
while ((i = get_next_test(&normal_tests)) != NULL)
- run_test(i, summary, &score, &total_score, m);
+ pass &= run_test(i, summary, &score, &total_score, m);
printf("%sTotal score: %u/%u\n", prefix, score, total_score);
- return 0;
+ return pass ? 0 : 1;
}
struct list_head deps;
};
+/* Get the manifest for a given directory. */
struct manifest *get_manifest(const void *ctx, const char *dir);
+/* Error in a particular file: stored off score->per_file_errors. */
struct file_error {
struct list_node list;
struct ccan_file *file;
unsigned int line;
};
+/* The score for an individual test. */
struct score {
+ /* Starts as false: if not set to true, ccanlint exits non-zero.
+ * Thus it is usually set for compilation or other serious failures. */
bool pass;
+ /* Starts at 0 and 1 respectively. */
unsigned int score, total;
+ /* The error message to print. */
char *error;
+ /* Per file errors, set by score_file_error() */
struct list_head per_file_errors;
};
/* If not set, we'll give an error if they try to set options. */
bool takes_options;
- /* comma-separated list of dependency keys. */
+ /* Space-separated list of dependency keys. */
const char *needs;
/* Internal use fields: */
{
struct list_head *list;
+ /* FIXME: This isn't reliable enough with #ifdefs, so we don't fail. */
+ score->pass = true;
+
foreach_ptr(list, &m->c_files, &m->h_files,
&m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests,
}
if (!score->error) {
- score->pass = true;
score->score = score->total;
}
}
}
}
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
if (have_info_example && have_header_example) {
score->score = score->total;
- score->pass = true;
return;
}
score_file_error(score, mainh, 0, "No Example: section");
score->score = have_info_example + have_header_example;
- /* We pass if we find any example. */
- score->pass = score->score != 0;
}
struct ccanlint examples_exist = {
"\n\t(#if works like #ifdef, but with gcc's -Wundef, we can detect\n"
"\tmistyped or unknown configuration options)";
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
+
foreach_ptr(list, &m->c_files, &m->h_files,
&m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests,
}
if (!score->error) {
- score->pass = true;
score->score = score->total;
}
}
{
struct ccan_file *f;
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
+
list_for_each(&m->h_files, f, list) {
check_idem(f, score);
}
if (!score->error) {
- score->pass = true;
score->score = score->total;
}
}
struct doc_section *d;
bool summary = false, description = false;
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
+
list_for_each(infodocs, d, list) {
if (!streq(d->function, m->basename))
continue;
if (summary && description) {
score->score = score->total;
- score->pass = true;
} else if (!summary) {
score->error = talloc_strdup(score,
"_info file has no module documentation.\n\n"
#include <ccan/talloc/talloc.h>
#include <ccan/str/str.h>
-REGISTER_TEST(license_exists);
-
static struct doc_section *find_license(const struct manifest *m)
{
struct doc_section *d;
}
}
+extern struct ccanlint license_exists;
+
static void check_has_license(struct manifest *m,
bool keep,
unsigned int *timeleft, struct score *score)
score->error = talloc_strdup(score, "No License: tag in _info");
return;
}
+ /* If they have a license tag at all, we pass. */
+ score->pass = true;
+
expected = expected_link(m, d);
len = readlink(license, buf, sizeof(buf));
.check = check_has_license,
.needs = "info_exists"
};
+REGISTER_TEST(license_exists);
struct ccan_file *f;
unsigned int i;
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
+
foreach_ptr(list, &m->c_files, &m->h_files) {
list_for_each(list, f, list) {
char **lines = get_ccan_file_lines(f);
}
}
if (!score->error) {
- score->pass = true;
score->score = score->total;
}
}
}
}
+ /* We don't fail ccanlint for this. */
+ score->pass = true;
+
score->total = 1;
if (!errors) {
- score->pass = true;
score->score = !warnings;
}
}
if (errno != ENOENT)
err(1, "statting %s", test_dir);
tests_exist.handle = handle_no_tests;
+ /* We "pass" this. */
+ score->pass = true;
return;
}
}
}
+ /* FIXME: We don't fail for this, since many tests leak. */
+ score->pass = true;
if (!leaks) {
score->score = 1;
- score->pass = true;
}
}