if (has_dep(m, deps, used, mod))
continue;
- /* FIXME: we can't be sure about
- * conditional includes, so don't
- * complain. */
- if (!li[i].cond) {
+ /* FIXME: we can't be sure about conditional includes,
+ * so don't complain (handle common case of idempotent wrap) */
+ if (!li[i].cond || li[i].cond == f->idempotent_cond) {
score_file_error(score, f, i+1,
"%s not listed in _info", mod);
ok = false;
.key = "depends_accurate",
.name = "Module's CCAN dependencies are the only CCAN files #included",
.check = check_depends_accurate,
- .needs = "depends_exist test_depends_exist"
+ .needs = "depends_exist test_depends_exist headers_idempotent"
};
REGISTER_TEST(depends_accurate);
if (!f->lines[i])
return;
- /* We expect a condition on this line. */
+ /* We expect a condition around this line. */
if (!line_info[i].cond) {
- score_file_error(score, f, i+1, "Expected #ifndef");
+ score_file_error(score, f, first_preproc_line+1,
+ "Expected #ifndef");
return;
}
/* We expect the condition to be ! IFDEF <symbol>. */
if (line_info[i].cond->type != PP_COND_IFDEF
|| !line_info[i].cond->inverse) {
- score_file_error(score, f, i+1, "Expected #ifndef");
+ score_file_error(score, f, first_preproc_line+1,
+ "Expected #ifndef");
return;
}
return;
}
+ /* Record this for use in depends_accurate */
+ f->idempotent_cond = line_info[i].cond;
+
/* Rest of code should all be covered by that conditional. */
for (i++; f->lines[i]; i++) {
unsigned int val = 0;
f->fullname = path_join(f, dir, f->name);
f->contents = NULL;
f->simplified = NULL;
+ f->idempotent_cond = NULL;
+
return f;
}
/* Simplified stream (lowercase letters and single spaces) */
char *simplified;
+
+ /* Condition for idempotent wrapper (filled by headers_idempotent) */
+ struct pp_conditions *idempotent_cond;
};
/* A new ccan_file, with the given dir and name (either can be take()). */