summaryrefslogtreecommitdiff
path: root/utils/checkstyle.py
diff options
context:
space:
mode:
Diffstat (limited to 'utils/checkstyle.py')
-rwxr-xr-xutils/checkstyle.py87
1 files changed, 67 insertions, 20 deletions
diff --git a/utils/checkstyle.py b/utils/checkstyle.py
index 88078a61..4185c39a 100755
--- a/utils/checkstyle.py
+++ b/utils/checkstyle.py
@@ -4,7 +4,7 @@
#
# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
#
-# checkstyle.py - A patch style checker script based on clang-format
+# A patch style checker script based on clang-format
#
# TODO:
#
@@ -556,20 +556,49 @@ class StyleChecker(metaclass=ClassRegistry):
class StyleIssue(object):
- def __init__(self, line_number, line, msg):
+ def __init__(self, line_number, position, line, msg):
self.line_number = line_number
+ self.position = position
self.line = line
self.msg = msg
+class HexValueChecker(StyleChecker):
+ patterns = ('*.c', '*.cpp', '*.h')
+
+ regex = re.compile(r'\b0[xX][0-9a-fA-F]+\b')
+
+ def __init__(self, content):
+ super().__init__()
+ self.__content = content
+
+ def check(self, line_numbers):
+ issues = []
+
+ for line_number in line_numbers:
+ line = self.__content[line_number - 1]
+ match = HexValueChecker.regex.search(line)
+ if not match:
+ continue
+
+ value = match.group(0)
+ if value == value.lower():
+ continue
+
+ issues.append(StyleIssue(line_number, match.span(0), line,
+ f'Use lowercase hex constant {value.lower()}'))
+
+ return issues
+
+
class IncludeChecker(StyleChecker):
patterns = ('*.cpp', '*.h')
- headers = ('assert', 'ctype', 'errno', 'fenv', 'float', 'inttypes',
- 'limits', 'locale', 'setjmp', 'signal', 'stdarg', 'stddef',
- 'stdint', 'stdio', 'stdlib', 'string', 'time', 'uchar', 'wchar',
- 'wctype')
- include_regex = re.compile(r'^#include <c([a-z]*)>')
+ headers = ('cassert', 'cctype', 'cerrno', 'cfenv', 'cfloat', 'cinttypes',
+ 'climits', 'clocale', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
+ 'cstdint', 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cuchar',
+ 'cwchar', 'cwctype', 'math.h')
+ include_regex = re.compile(r'^#include <([a-z.]*)>')
def __init__(self, content):
super().__init__()
@@ -588,8 +617,15 @@ class IncludeChecker(StyleChecker):
if header not in IncludeChecker.headers:
continue
- issues.append(StyleIssue(line_number, line,
- 'C compatibility header <%s.h> is preferred' % header))
+ if header.endswith('.h'):
+ header_type = 'C++'
+ header = 'c' + header[:-2]
+ else:
+ header_type = 'C compatibility'
+ header = header[1:] + '.h'
+
+ issues.append(StyleIssue(line_number, match.span(1), line,
+ f'{header_type} header <{header}> is preferred'))
return issues
@@ -606,10 +642,12 @@ class LogCategoryChecker(StyleChecker):
issues = []
for line_number in line_numbers:
line = self.__content[line_number-1]
- if not LogCategoryChecker.log_regex.search(line):
+ match = LogCategoryChecker.log_regex.search(line)
+ if not match:
continue
- issues.append(StyleIssue(line_number, line, 'LOG() should use categories'))
+ issues.append(StyleIssue(line_number, match.span(1), line,
+ 'LOG() should use categories'))
return issues
@@ -625,8 +663,10 @@ class MesonChecker(StyleChecker):
issues = []
for line_number in line_numbers:
line = self.__content[line_number-1]
- if line.find('\t') != -1:
- issues.append(StyleIssue(line_number, line, 'meson.build should use spaces for indentation'))
+ pos = line.find('\t')
+ if pos != -1:
+ issues.append(StyleIssue(line_number, [pos, pos], line,
+ 'meson.build should use spaces for indentation'))
return issues
@@ -646,7 +686,7 @@ class Pep8Checker(StyleChecker):
ret = subprocess.run(['pycodestyle', '--ignore=E501', '-'],
input=data, stdout=subprocess.PIPE)
except FileNotFoundError:
- issues.append(StyleIssue(0, None, 'Please install pycodestyle to validate python additions'))
+ issues.append(StyleIssue(0, None, None, 'Please install pycodestyle to validate python additions'))
return issues
results = ret.stdout.decode('utf-8').splitlines()
@@ -658,7 +698,7 @@ class Pep8Checker(StyleChecker):
if line_number in line_numbers:
line = self.__content[line_number - 1]
- issues.append(StyleIssue(line_number, line, msg))
+ issues.append(StyleIssue(line_number, None, line, msg))
return issues
@@ -679,7 +719,7 @@ class ShellChecker(StyleChecker):
ret = subprocess.run(['shellcheck', '-Cnever', '-'],
input=data, stdout=subprocess.PIPE)
except FileNotFoundError:
- issues.append(StyleIssue(0, None, 'Please install shellcheck to validate shell script additions'))
+ issues.append(StyleIssue(0, None, None, 'Please install shellcheck to validate shell script additions'))
return issues
results = ret.stdout.decode('utf-8').splitlines()
@@ -692,11 +732,8 @@ class ShellChecker(StyleChecker):
line = results[nr + 1]
msg = results[nr + 2]
- # Determined, but not yet used
- position = msg.find('^') + 1
-
if line_number in line_numbers:
- issues.append(StyleIssue(line_number, line, msg))
+ issues.append(StyleIssue(line_number, None, line, msg))
return issues
@@ -938,6 +975,16 @@ def check_file(top_level, commit, filename, checkers):
print('%s+%s%s' % (Colours.fg(Colours.Yellow), issue.line.rstrip(),
Colours.reset()))
+ if issue.position is not None:
+ # Align the position marker by using the original line with
+ # all characters except for tabs replaced with spaces. This
+ # ensures proper alignment regardless of how the code is
+ # indented.
+ start = issue.position[0]
+ prefix = ''.join([c if c == '\t' else ' ' for c in issue.line[:start]])
+ length = issue.position[1] - start - 1
+ print(' ' + prefix + '^' + '~' * length)
+
return len(formatted_diff) + len(issues)