02b165dc71
This script currently uses "/usr/bin/env python" as shebang but it does not really support Python3. Instead of limiting the script to Python2, fix it to support both versions. So change all imports to absolute imports because Python3 follows PEP328 and dropped implicit relative imports. In order to avoid errors when decoding files with the default 'utf-8' codec, use errors="surrogateescape" when opening files, the docs for open() states: "This is useful for processing files in an unknown encoding.". This argument is not compatible with Python2 open() so import 'six' to use it only when running in Python3. As a consequence the file handler becomes explicit, so use it to close() the file after it got processed. This "surrogateescape" is a simple alternative to the complete solution of opening files with "rb" and changing all functions in the lib*.py files to use bytes objects instead of strings. The only case we can have non-ascii/non-utf-8 files being checked by the script are for patch files when the upstream file to be patched is not ascii or utf-8. There is currently one case in the tree: package/urg/0002-urg-gcc6-fix-narrowing-conversion.patch. Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Cc: Arnout Vandecappelle <arnout@mind.be> Reviewed-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> Tested-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
144 lines
4.7 KiB
Python
144 lines
4.7 KiB
Python
# See utils/checkpackagelib/readme.txt before editing this file.
|
|
# Kconfig generates errors if someone introduces a typo like "boool" instead of
|
|
# "bool", so below check functions don't need to check for things already
|
|
# checked by running "make menuconfig".
|
|
|
|
import re
|
|
|
|
from checkpackagelib.base import _CheckFunction
|
|
from checkpackagelib.lib import ConsecutiveEmptyLines # noqa: F401
|
|
from checkpackagelib.lib import EmptyLastLine # noqa: F401
|
|
from checkpackagelib.lib import NewlineAtEof # noqa: F401
|
|
from checkpackagelib.lib import TrailingSpace # noqa: F401
|
|
|
|
|
|
def _empty_or_comment(text):
|
|
line = text.strip()
|
|
# ignore empty lines and comment lines indented or not
|
|
return line == "" or line.startswith("#")
|
|
|
|
|
|
def _part_of_help_text(text):
|
|
return text.startswith("\t ")
|
|
|
|
|
|
# used in more than one check
|
|
entries_that_should_not_be_indented = [
|
|
"choice", "comment", "config", "endchoice", "endif", "endmenu", "if",
|
|
"menu", "menuconfig", "source"]
|
|
|
|
|
|
class AttributesOrder(_CheckFunction):
|
|
attributes_order_convention = {
|
|
"bool": 1, "prompt": 1, "string": 1, "default": 2, "depends": 3,
|
|
"select": 4, "help": 5}
|
|
|
|
def before(self):
|
|
self.state = 0
|
|
|
|
def check_line(self, lineno, text):
|
|
if _empty_or_comment(text) or _part_of_help_text(text):
|
|
return
|
|
|
|
attribute = text.split()[0]
|
|
|
|
if attribute in entries_that_should_not_be_indented:
|
|
self.state = 0
|
|
return
|
|
if attribute not in self.attributes_order_convention.keys():
|
|
return
|
|
new_state = self.attributes_order_convention[attribute]
|
|
wrong_order = self.state > new_state
|
|
|
|
# save to process next line
|
|
self.state = new_state
|
|
|
|
if wrong_order:
|
|
return ["{}:{}: attributes order: type, default, depends on,"
|
|
" select, help ({}#_config_files)"
|
|
.format(self.filename, lineno, self.url_to_manual),
|
|
text]
|
|
|
|
|
|
class HelpText(_CheckFunction):
|
|
HELP_TEXT_FORMAT = re.compile("^\t .{,62}$")
|
|
URL_ONLY = re.compile("^(http|https|git)://\S*$")
|
|
|
|
def before(self):
|
|
self.help_text = False
|
|
|
|
def check_line(self, lineno, text):
|
|
if _empty_or_comment(text):
|
|
return
|
|
|
|
entry = text.split()[0]
|
|
|
|
if entry in entries_that_should_not_be_indented:
|
|
self.help_text = False
|
|
return
|
|
if text.strip() == "help":
|
|
self.help_text = True
|
|
return
|
|
|
|
if not self.help_text:
|
|
return
|
|
|
|
if self.HELP_TEXT_FORMAT.match(text.rstrip()):
|
|
return
|
|
if self.URL_ONLY.match(text.strip()):
|
|
return
|
|
return ["{}:{}: help text: <tab><2 spaces><62 chars>"
|
|
" ({}#writing-rules-config-in)"
|
|
.format(self.filename, lineno, self.url_to_manual),
|
|
text,
|
|
"\t " + "123456789 " * 6 + "12"]
|
|
|
|
|
|
class Indent(_CheckFunction):
|
|
ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
|
|
entries_that_should_be_indented = [
|
|
"bool", "default", "depends", "help", "prompt", "select", "string"]
|
|
|
|
def before(self):
|
|
self.backslash = False
|
|
|
|
def check_line(self, lineno, text):
|
|
if _empty_or_comment(text) or _part_of_help_text(text):
|
|
self.backslash = False
|
|
return
|
|
|
|
entry = text.split()[0]
|
|
|
|
last_line_ends_in_backslash = self.backslash
|
|
|
|
# calculate for next line
|
|
if self.ENDS_WITH_BACKSLASH.search(text):
|
|
self.backslash = True
|
|
else:
|
|
self.backslash = False
|
|
|
|
if last_line_ends_in_backslash:
|
|
if text.startswith("\t"):
|
|
return
|
|
return ["{}:{}: continuation line should be indented using tabs"
|
|
.format(self.filename, lineno),
|
|
text]
|
|
|
|
if entry in self.entries_that_should_be_indented:
|
|
if not text.startswith("\t{}".format(entry)):
|
|
return ["{}:{}: should be indented with one tab"
|
|
" ({}#_config_files)"
|
|
.format(self.filename, lineno, self.url_to_manual),
|
|
text]
|
|
elif entry in entries_that_should_not_be_indented:
|
|
if not text.startswith(entry):
|
|
# four Config.in files have a special but legitimate indentation rule
|
|
if self.filename in ["package/Config.in",
|
|
"package/Config.in.host",
|
|
"package/kodi/Config.in",
|
|
"package/x11r7/Config.in"]:
|
|
return
|
|
return ["{}:{}: should not be indented"
|
|
.format(self.filename, lineno),
|
|
text]
|