From d1dd3ab0d3f793ed28291ebcc6f7f337e65131b4 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Wed, 30 Jan 2019 15:13:20 +0100 Subject: [PATCH 1/3] tools: Recognize backslashes in Kconfigs with CR+LF line endings --- tools/kconfig/zconf.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/kconfig/zconf.l b/tools/kconfig/zconf.l index 8fd75491c..fa0da6b70 100644 --- a/tools/kconfig/zconf.l +++ b/tools/kconfig/zconf.l @@ -151,7 +151,7 @@ n [A-Za-z0-9_-] return T_WORD; } #.* /* comment */ - \\\n current_file->lineno++; + \\\r?\n current_file->lineno++; [[:blank:]]+ . warn_ignored_character(*yytext); <> { From bcd584a63fb495e0dec79da4fff63dcc0b4136fc Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 31 Jan 2019 13:41:31 +0100 Subject: [PATCH 2/3] tools: check for incorrect case used in Kconfig filenames --- tools/check_kconfigs.py | 84 +++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/tools/check_kconfigs.py b/tools/check_kconfigs.py index e0de7ac79..412aa2c2f 100755 --- a/tools/check_kconfigs.py +++ b/tools/check_kconfigs.py @@ -22,8 +22,8 @@ import re import argparse from io import open -# regular expression search object for matching Kconfig files -RE_KCONFIG = re.compile(r'^Kconfig(?:\.projbuild)?$') +# regular expression for matching Kconfig files +RE_KCONFIG = r'^Kconfig(?:\.projbuild)?$' # ouput file with suggestions will get this suffix OUTPUT_SUFFIX = '.new' @@ -358,47 +358,51 @@ def main(): check_ignore_dirs = default_path is not None and os.path.abspath(args.directory) == os.path.abspath(default_path) for root, dirnames, filenames in os.walk(args.directory): - for filename in [f for f in filenames if RE_KCONFIG.search(f)]: + for filename in filenames: full_path = os.path.join(root, filename) path_in_idf = os.path.relpath(full_path, args.directory) - if check_ignore_dirs and path_in_idf.startswith(IGNORE_DIRS): - print('{}: Ignored'.format(path_in_idf)) - ignore_counter += 1 - continue - suggestions_full_path = full_path + OUTPUT_SUFFIX - with open(full_path, 'r', encoding='utf-8') as f, \ - open(suggestions_full_path, 'w', encoding='utf-8', newline='\n') as f_o, \ - LineRuleChecker(path_in_idf) as line_checker, \ - IndentAndNameChecker(path_in_idf, debug=args.verbose) as indent_and_name_checker: - try: - for line_number, line in enumerate(f, start=1): - try: - for checker in [line_checker, indent_and_name_checker]: - checker.process_line(line, line_number) - # The line is correct therefore we echo it to the output file - f_o.write(line) - except InputError as e: - print(e) - failure = True - f_o.write(e.suggested_line) - except UnicodeDecodeError: - raise ValueError("The encoding of {} is not Unicode.".format(path_in_idf)) + if re.search(RE_KCONFIG, filename): + if check_ignore_dirs and path_in_idf.startswith(IGNORE_DIRS): + print('{}: Ignored'.format(path_in_idf)) + ignore_counter += 1 + continue + suggestions_full_path = full_path + OUTPUT_SUFFIX + with open(full_path, 'r', encoding='utf-8') as f, \ + open(suggestions_full_path, 'w', encoding='utf-8', newline='\n') as f_o, \ + LineRuleChecker(path_in_idf) as line_checker, \ + IndentAndNameChecker(path_in_idf, debug=args.verbose) as indent_and_name_checker: + try: + for line_number, line in enumerate(f, start=1): + try: + for checker in [line_checker, indent_and_name_checker]: + checker.process_line(line, line_number) + # The line is correct therefore we echo it to the output file + f_o.write(line) + except InputError as e: + print(e) + failure = True + f_o.write(e.suggested_line) + except UnicodeDecodeError: + raise ValueError("The encoding of {} is not Unicode.".format(path_in_idf)) - if failure: - print('{} has been saved with suggestions for resolving the issues. Please note that the suggestions ' - 'can be wrong and you might need to re-run the checker several times for solving all issues.' - ''.format(path_in_idf + OUTPUT_SUFFIX)) - print('Please fix the errors and run {} for checking the correctness of ' - 'Kconfigs.'.format(os.path.relpath(os.path.abspath(__file__), args.directory))) - sys.exit(1) - else: - success_couter += 1 - print('{}: OK'.format(path_in_idf)) - try: - os.remove(suggestions_full_path) - except Exception: - # not a serious error is when the file cannot be deleted - print('{} cannot be deleted!'.format(suggestions_full_path)) + if failure: + print('{} has been saved with suggestions for resolving the issues. Please note that the ' + 'suggestions can be wrong and you might need to re-run the checker several times ' + 'for solving all issues'.format(path_in_idf + OUTPUT_SUFFIX)) + print('Please fix the errors and run {} for checking the correctness of ' + 'Kconfigs.'.format(os.path.relpath(os.path.abspath(__file__), args.directory))) + sys.exit(1) + else: + success_couter += 1 + print('{}: OK'.format(path_in_idf)) + try: + os.remove(suggestions_full_path) + except Exception: + # not a serious error is when the file cannot be deleted + print('{} cannot be deleted!'.format(suggestions_full_path)) + elif re.search(RE_KCONFIG, filename, re.IGNORECASE): + # On Windows Kconfig files are working with different cases! + raise ValueError('Incorrect filename of {}. The case should be "Kconfig"!'.format(path_in_idf)) if ignore_counter > 0: print('{} files have been ignored.'.format(ignore_counter)) From 80cb4a1a187bd4ec593459acc3bc020069d97658 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 31 Jan 2019 14:10:14 +0100 Subject: [PATCH 3/3] tools: Don't use backslashes in Kconfigs and ignore long lines to avoid errors Closes https://github.com/espressif/esp-idf/issues/3012 --- components/bt/Kconfig | 6 ++---- components/esp32/Kconfig | 3 +-- tools/check_kconfigs.py | 24 ++++++++++++++++++------ tools/test_check_kconfigs.py | 17 +++-------------- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 2638f1fa8..4551a47f8 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -60,14 +60,12 @@ menu Bluetooth config BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF int - default \ - BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM + default BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM # NOERROR default 0 config BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF int - default \ - BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM + default BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM # NOERROR default 0 choice BTDM_CONTROLLER_PINNED_TO_CORE_CHOICE diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index be7792655..aecd26a65 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -806,8 +806,7 @@ menu "ESP32-specific" int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL default 1024 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC - range 0 27000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL || ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC \ - || ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 + range 0 27000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL || ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC || ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 # NOERROR range 0 32766 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC help When the startup code initializes RTC_SLOW_CLK, it can perform diff --git a/tools/check_kconfigs.py b/tools/check_kconfigs.py index 412aa2c2f..b65f68cda 100755 --- a/tools/check_kconfigs.py +++ b/tools/check_kconfigs.py @@ -44,12 +44,19 @@ CONFIG_NAME_MAX_LENGTH = 60 # TODO increase prefix length (after the names have been refactored) CONFIG_NAME_MIN_PREFIX_LENGTH = 0 +# The checker will not fail if it encounters this string (it can be used for temporarily resolve conflicts) +RE_NOERROR = re.compile(r'\s+#\s+NOERROR\s+$') + # list or rules for lines LINE_ERROR_RULES = [ # (regular expression for finding, error message, correction) (re.compile(r'\t'), 'tabulators should be replaced by spaces', r' ' * SPACES_PER_INDENT), (re.compile(r'\s+\n'), 'trailing whitespaces should be removed', r'\n'), (re.compile(r'.{120}'), 'line should be shorter than 120 characters', None), + # "\" is not recognized due to a bug in tools/kconfig/zconf.l. The bug was fixed but the rebuild of + # mconf-idf is not enforced and an incorrect version is supplied with all previous IDF versions. Backslashes + # cannot be enabled unless everybody updates mconf-idf. + (re.compile(r'\\\n'), 'line cannot be wrapped by backslash', None), ] @@ -81,11 +88,17 @@ class LineRuleChecker(BaseChecker): checks LINE_ERROR_RULES for each line """ def process_line(self, line, line_number): + suppress_errors = RE_NOERROR.search(line) is not None errors = [] for rule in LINE_ERROR_RULES: m = rule[0].search(line) if m: - errors.append(rule[1]) + if suppress_errors: + # just print but no failure + e = InputError(self.path_in_idf, line_number, rule[1], line) + print(e) + else: + errors.append(rule[1]) if rule[2]: line = rule[0].sub(rule[2], line) if len(errors) > 0: @@ -297,11 +310,10 @@ class IndentAndNameChecker(BaseChecker): self.force_next_indent = 0 return - else: - if stripped_line.endswith('\\') and stripped_line.startswith(('config', 'menuconfig', 'choice')): - raise InputError(self.path_in_idf, line_number, - 'Line-wrap with backslash is not supported here', - line) # no suggestion for this + elif stripped_line.endswith('\\') and stripped_line.startswith(('config', 'menuconfig', 'choice')): + raise InputError(self.path_in_idf, line_number, + 'Line-wrap with backslash is not supported here', + line) # no suggestion for this self.check_name_and_update_prefix(stripped_line, line_number) diff --git a/tools/test_check_kconfigs.py b/tools/test_check_kconfigs.py index 866d1d828..737ae4657 100755 --- a/tools/test_check_kconfigs.py +++ b/tools/test_check_kconfigs.py @@ -67,6 +67,9 @@ class TestLineRuleChecker(unittest.TestCase, ApplyLine): self.expt_success('x' * 119) self.expt_success('') + def test_backslashes(self): + self.expect_error('test \\', expect=None) + class TestIndentAndNameChecker(unittest.TestCase, ApplyLine): def setUp(self): @@ -153,15 +156,6 @@ class TestIndent(TestIndentAndNameChecker): self.expt_success('config') self.expt_success(' help') - def test_backslashes(self): - self.expt_success('default \\') - self.expect_error('help', expect=None) - self.expt_success(' CONFIG') - self.expt_success('default \\') - self.expt_success(' LINE1\\') - self.expt_success(' LINE2') - self.expt_success('help') - class TestName(TestIndentAndNameChecker): def setUp(self): @@ -181,11 +175,6 @@ class TestName(TestIndentAndNameChecker): self.expect_error(' choice ' + ('X' * too_long), expect=None) self.expt_success('endmenu') - def test_config_backslash(self): - self.expect_error('config\\', expect=None) - self.expect_error('menuconfig\\', expect=None) - self.expect_error('choice\\', expect=None) - class TestPrefix(TestIndentAndNameChecker): def test_prefix_len(self):