2
1

lib_config.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. # See support/scripts/checkpackagelib/readme.txt before editing this file.
  2. # Kconfig generates errors if someone introduces a typo like "boool" instead of
  3. # "bool", so below check functions don't need to check for things already
  4. # checked by running "make menuconfig".
  5. import re
  6. from base import _CheckFunction
  7. # Notice: ignore 'imported but unused' from pyflakes for check functions.
  8. from lib import ConsecutiveEmptyLines
  9. from lib import EmptyLastLine
  10. from lib import NewlineAtEof
  11. from lib import TrailingSpace
  12. def _empty_or_comment(text):
  13. line = text.strip()
  14. # ignore empty lines and comment lines indented or not
  15. return line == "" or line.startswith("#")
  16. def _part_of_help_text(text):
  17. return text.startswith("\t ")
  18. # used in more than one check
  19. entries_that_should_not_be_indented = [
  20. "choice", "comment", "config", "endchoice", "endif", "endmenu", "if",
  21. "menu", "menuconfig", "source"]
  22. class AttributesOrder(_CheckFunction):
  23. attributes_order_convention = {
  24. "bool": 1, "prompt": 1, "string": 1, "default": 2, "depends": 3,
  25. "select": 4, "help": 5}
  26. def before(self):
  27. self.state = 0
  28. def check_line(self, lineno, text):
  29. if _empty_or_comment(text) or _part_of_help_text(text):
  30. return
  31. attribute = text.split()[0]
  32. if attribute in entries_that_should_not_be_indented:
  33. self.state = 0
  34. return
  35. if attribute not in self.attributes_order_convention.keys():
  36. return
  37. new_state = self.attributes_order_convention[attribute]
  38. wrong_order = self.state > new_state
  39. # save to process next line
  40. self.state = new_state
  41. if wrong_order:
  42. return ["{}:{}: attributes order: type, default, depends on,"
  43. " select, help ({}#_config_files)"
  44. .format(self.filename, lineno, self.url_to_manual),
  45. text]
  46. class HelpText(_CheckFunction):
  47. HELP_TEXT_FORMAT = re.compile("^\t .{,62}$")
  48. URL_ONLY = re.compile("^(http|https|git)://\S*$")
  49. def before(self):
  50. self.help_text = False
  51. def check_line(self, lineno, text):
  52. if _empty_or_comment(text):
  53. return
  54. entry = text.split()[0]
  55. if entry in entries_that_should_not_be_indented:
  56. self.help_text = False
  57. return
  58. if text.strip() == "help":
  59. self.help_text = True
  60. return
  61. if not self.help_text:
  62. return
  63. if self.HELP_TEXT_FORMAT.match(text.rstrip()):
  64. return
  65. if self.URL_ONLY.match(text.strip()):
  66. return
  67. return ["{}:{}: help text: <tab><2 spaces><62 chars>"
  68. " ({}#writing-rules-config-in)"
  69. .format(self.filename, lineno, self.url_to_manual),
  70. text,
  71. "\t " + "123456789 " * 6 + "12"]
  72. class Indent(_CheckFunction):
  73. ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
  74. entries_that_should_be_indented = [
  75. "bool", "default", "depends", "help", "prompt", "select", "string"]
  76. def before(self):
  77. self.backslash = False
  78. def check_line(self, lineno, text):
  79. if _empty_or_comment(text) or _part_of_help_text(text):
  80. self.backslash = False
  81. return
  82. entry = text.split()[0]
  83. last_line_ends_in_backslash = self.backslash
  84. # calculate for next line
  85. if self.ENDS_WITH_BACKSLASH.search(text):
  86. self.backslash = True
  87. else:
  88. self.backslash = False
  89. if last_line_ends_in_backslash:
  90. if text.startswith("\t"):
  91. return
  92. return ["{}:{}: continuation line should be indented using tabs"
  93. .format(self.filename, lineno),
  94. text]
  95. if entry in self.entries_that_should_be_indented:
  96. if not text.startswith("\t{}".format(entry)):
  97. return ["{}:{}: should be indented with one tab"
  98. " ({}#_config_files)"
  99. .format(self.filename, lineno, self.url_to_manual),
  100. text]
  101. elif entry in entries_that_should_not_be_indented:
  102. if not text.startswith(entry):
  103. return ["{}:{}: should not be indented"
  104. .format(self.filename, lineno),
  105. text]