hash_if.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <tools/ccanlint/ccanlint.h>
  2. #include <tools/tools.h>
  3. #include <ccan/talloc/talloc.h>
  4. #include <ccan/str/str.h>
  5. #include <ccan/str_talloc/str_talloc.h>
  6. #include <ccan/foreach/foreach.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <limits.h>
  12. #include <errno.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <err.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. static void check_hash_if(struct manifest *m,
  19. bool keep,
  20. unsigned int *timeleft, struct score *score)
  21. {
  22. struct list_head *list;
  23. const char *explanation =
  24. "\n\t(#if works like #ifdef, but with gcc's -Wundef, we can detect\n"
  25. "\tmistyped or unknown configuration options)";
  26. /* We don't fail ccanlint for this. */
  27. score->pass = true;
  28. foreach_ptr(list, &m->c_files, &m->h_files,
  29. &m->run_tests, &m->api_tests,
  30. &m->compile_ok_tests, &m->compile_fail_tests,
  31. &m->other_test_c_files) {
  32. struct ccan_file *f;
  33. list_for_each(list, f, list) {
  34. unsigned int i;
  35. char **lines = get_ccan_file_lines(f);
  36. for (i = 0; lines[i]; i++) {
  37. const char *line = lines[i];
  38. char *sym;
  39. if (!get_token(&line, "#"))
  40. continue;
  41. if (!(get_token(&line, "if")
  42. && get_token(&line, "defined")
  43. && get_token(&line, "("))
  44. && !get_token(&line, "ifdef"))
  45. continue;
  46. sym = get_symbol_token(lines, &line);
  47. if (!sym || !strstarts(sym, "HAVE_"))
  48. continue;
  49. score_file_error(score, f, i+1,
  50. "%s should be tested with #if"
  51. "%s",
  52. sym, explanation);
  53. explanation = "";
  54. }
  55. }
  56. }
  57. if (!score->error) {
  58. score->score = score->total;
  59. }
  60. }
  61. struct ccanlint hash_if = {
  62. .key = "hash_if",
  63. .name = "Features are checked with #if not #ifdef",
  64. .check = check_hash_if,
  65. .needs = "info_exists"
  66. };
  67. REGISTER_TEST(hash_if);