idempotent.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "ccanlint.h"
  2. #include <talloc/talloc.h>
  3. #include <string/string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <limits.h>
  9. #include <errno.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <err.h>
  13. #include <string.h>
  14. static const char explain[]
  15. = "Headers usually start with the C preprocessor lines to prevent multiple\n"
  16. "inclusions. These look like the following:\n"
  17. "#ifndef MY_HEADER_H\n"
  18. "#define MY_HEADER_H\n"
  19. "...\n"
  20. "#endif /* MY_HEADER_H */\n";
  21. static char *report_idem(struct ccan_file *f, char *sofar)
  22. {
  23. char **lines;
  24. char *secondline;
  25. lines = get_ccan_file_lines(f);
  26. if (f->num_lines < 3)
  27. /* FIXME: We assume small headers probably uninteresting. */
  28. return NULL;
  29. if (!strstarts(lines[0], "#ifndef "))
  30. return talloc_asprintf_append(sofar,
  31. "%s:1:expect first line to be #ifndef.\n", f->name);
  32. secondline = talloc_asprintf(f, "#define %s",
  33. lines[0] + strlen("#ifndef "));
  34. if (!streq(lines[1], secondline))
  35. return talloc_asprintf_append(sofar,
  36. "%s:2:expect second line to be '%s'.\n",
  37. f->name, secondline);
  38. return sofar;
  39. }
  40. static void *check_idempotent(struct manifest *m)
  41. {
  42. struct ccan_file *f;
  43. char *report = NULL;
  44. list_for_each(&m->h_files, f, list)
  45. report = report_idem(f, report);
  46. return report;
  47. }
  48. static const char *describe_idempotent(struct manifest *m, void *check_result)
  49. {
  50. return talloc_asprintf(check_result,
  51. "Some headers not idempotent:\n"
  52. "%s\n%s", (char *)check_result,
  53. explain);
  54. }
  55. struct ccanlint idempotent = {
  56. .name = "Headers are #ifndef/#define idempotent wrapped",
  57. .total_score = 1,
  58. .check = check_idempotent,
  59. .describe = describe_idempotent,
  60. };