Просмотр исходного кода

Merge branch 'bugfix/win_kconfig_backslash' into 'master'

tools: Fix Windows related Kconfig issues

See merge request idf/esp-idf!4206
Angus Gratton 7 лет назад
Родитель
Сommit
a2b47fd314
5 измененных файлов с 70 добавлено и 68 удалено
  1. 2 4
      components/bt/Kconfig
  2. 1 2
      components/esp32/Kconfig
  3. 63 47
      tools/check_kconfigs.py
  4. 1 1
      tools/kconfig/zconf.l
  5. 3 14
      tools/test_check_kconfigs.py

+ 2 - 4
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

+ 1 - 2
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

+ 63 - 47
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'
@@ -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),
+    # "\<CR><LF>" 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)
 
@@ -358,47 +370,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 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 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))
+            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))

+ 1 - 1
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);
 	<<EOF>> {

+ 3 - 14
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):