]> rtime.felk.cvut.cz Git - coffee/buildroot.git/blob - utils/checkpackagelib/lib_config.py
26ebb393d1dc955664ecd4c2a1586b72c1e19987
[coffee/buildroot.git] / utils / checkpackagelib / lib_config.py
1 # See utils/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
6 import re
7
8 from base import _CheckFunction
9 # Notice: ignore 'imported but unused' from pyflakes for check functions.
10 from lib import ConsecutiveEmptyLines
11 from lib import EmptyLastLine
12 from lib import NewlineAtEof
13 from lib import TrailingSpace
14
15
16 def _empty_or_comment(text):
17     line = text.strip()
18     # ignore empty lines and comment lines indented or not
19     return line == "" or line.startswith("#")
20
21
22 def _part_of_help_text(text):
23     return text.startswith("\t  ")
24
25
26 # used in more than one check
27 entries_that_should_not_be_indented = [
28     "choice", "comment", "config", "endchoice", "endif", "endmenu", "if",
29     "menu", "menuconfig", "source"]
30
31
32 class AttributesOrder(_CheckFunction):
33     attributes_order_convention = {
34         "bool": 1, "prompt": 1, "string": 1, "default": 2, "depends": 3,
35         "select": 4, "help": 5}
36
37     def before(self):
38         self.state = 0
39
40     def check_line(self, lineno, text):
41         if _empty_or_comment(text) or _part_of_help_text(text):
42             return
43
44         attribute = text.split()[0]
45
46         if attribute in entries_that_should_not_be_indented:
47             self.state = 0
48             return
49         if attribute not in self.attributes_order_convention.keys():
50             return
51         new_state = self.attributes_order_convention[attribute]
52         wrong_order = self.state > new_state
53
54         # save to process next line
55         self.state = new_state
56
57         if wrong_order:
58             return ["{}:{}: attributes order: type, default, depends on,"
59                     " select, help ({}#_config_files)"
60                     .format(self.filename, lineno, self.url_to_manual),
61                     text]
62
63
64 class HelpText(_CheckFunction):
65     HELP_TEXT_FORMAT = re.compile("^\t  .{,62}$")
66     URL_ONLY = re.compile("^(http|https|git)://\S*$")
67
68     def before(self):
69         self.help_text = False
70
71     def check_line(self, lineno, text):
72         if _empty_or_comment(text):
73             return
74
75         entry = text.split()[0]
76
77         if entry in entries_that_should_not_be_indented:
78             self.help_text = False
79             return
80         if text.strip() == "help":
81             self.help_text = True
82             return
83
84         if not self.help_text:
85             return
86
87         if self.HELP_TEXT_FORMAT.match(text.rstrip()):
88             return
89         if self.URL_ONLY.match(text.strip()):
90             return
91         return ["{}:{}: help text: <tab><2 spaces><62 chars>"
92                 " ({}#writing-rules-config-in)"
93                 .format(self.filename, lineno, self.url_to_manual),
94                 text,
95                 "\t  " + "123456789 " * 6 + "12"]
96
97
98 class Indent(_CheckFunction):
99     ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
100     entries_that_should_be_indented = [
101         "bool", "default", "depends", "help", "prompt", "select", "string"]
102
103     def before(self):
104         self.backslash = False
105
106     def check_line(self, lineno, text):
107         if _empty_or_comment(text) or _part_of_help_text(text):
108             self.backslash = False
109             return
110
111         entry = text.split()[0]
112
113         last_line_ends_in_backslash = self.backslash
114
115         # calculate for next line
116         if self.ENDS_WITH_BACKSLASH.search(text):
117             self.backslash = True
118         else:
119             self.backslash = False
120
121         if last_line_ends_in_backslash:
122             if text.startswith("\t"):
123                 return
124             return ["{}:{}: continuation line should be indented using tabs"
125                     .format(self.filename, lineno),
126                     text]
127
128         if entry in self.entries_that_should_be_indented:
129             if not text.startswith("\t{}".format(entry)):
130                 return ["{}:{}: should be indented with one tab"
131                         " ({}#_config_files)"
132                         .format(self.filename, lineno, self.url_to_manual),
133                         text]
134         elif entry in entries_that_should_not_be_indented:
135             if not text.startswith(entry):
136                 return ["{}:{}: should not be indented"
137                         .format(self.filename, lineno),
138                         text]