123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- # Copyright (C) 2012 Intel Inc. All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions
- # are met:
- # 1. Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- """Supports checking WebKit style in cmake files.(.cmake, CMakeLists.txt)"""
- import re
- from common import TabChecker
- class CMakeChecker(object):
- """Processes CMake lines for checking style."""
- # NO_SPACE_CMDS list are based on commands section of CMake document.
- # Now it is generated from
- # http://www.cmake.org/cmake/help/v2.8.10/cmake.html#section_Commands.
- # Some commands are from default CMake modules such as pkg_check_modules.
- # Please keep list in alphabet order.
- #
- # For commands in this list, spaces should not be added it and its
- # parentheses. For eg, message("testing"), not message ("testing")
- #
- # The conditional commands like if, else, endif, foreach, endforeach,
- # while, endwhile and break are listed in ONE_SPACE_CMDS
- NO_SPACE_CMDS = [
- 'add_custom_command', 'add_custom_target', 'add_definitions',
- 'add_dependencies', 'add_executable', 'add_library',
- 'add_subdirectory', 'add_test', 'aux_source_directory',
- 'build_command',
- 'cmake_minimum_required', 'cmake_policy', 'configure_file',
- 'create_test_sourcelist',
- 'define_property',
- 'enable_language', 'enable_testing', 'endfunction', 'endmacro',
- 'execute_process', 'export',
- 'file', 'find_file', 'find_library', 'find_package', 'find_path',
- 'find_program', 'fltk_wrap_ui', 'function',
- 'get_cmake_property', 'get_directory_property',
- 'get_filename_component', 'get_property', 'get_source_file_property',
- 'get_target_property', 'get_test_property',
- 'include', 'include_directories', 'include_external_msproject',
- 'include_regular_expression', 'install',
- 'link_directories', 'list', 'load_cache', 'load_command',
- 'macro', 'mark_as_advanced', 'math', 'message',
- 'option',
- #From FindPkgConfig.cmake
- 'pkg_check_modules',
- 'project',
- 'qt_wrap_cpp', 'qt_wrap_ui',
- 'remove_definitions', 'return',
- 'separate_arguments', 'set', 'set_directory_properties', 'set_property',
- 'set_source_files_properties', 'set_target_properties',
- 'set_tests_properties', 'site_name', 'source_group', 'string',
- 'target_link_libraries', 'try_compile', 'try_run',
- 'unset',
- 'variable_watch',
- ]
- # CMake conditional commands, require one space between command and
- # its parentheses, such as "if (", "foreach (", etc.
- ONE_SPACE_CMDS = [
- 'if', 'else', 'elseif', 'endif',
- 'foreach', 'endforeach',
- 'while', 'endwhile',
- 'break',
- ]
- def __init__(self, file_path, handle_style_error):
- self._handle_style_error = handle_style_error
- self._tab_checker = TabChecker(file_path, handle_style_error)
- def check(self, lines):
- self._tab_checker.check(lines)
- self._num_lines = len(lines)
- for l in xrange(self._num_lines):
- self._process_line(l + 1, lines[l])
- def _process_line(self, line_number, line_content):
- if re.match('(^|\ +)#', line_content):
- # ignore comment line
- return
- l = line_content.expandtabs(4)
- # check command like message( "testing")
- if re.search('\(\ +', l):
- self._handle_style_error(line_number, 'whitespace/parentheses', 5,
- 'No space after "("')
- # check command like message("testing" )
- if re.search('\ +\)', l) and not re.search('^\ +\)$', l):
- self._handle_style_error(line_number, 'whitespace/parentheses', 5,
- 'No space before ")"')
- self._check_trailing_whitespace(line_number, l)
- self._check_no_space_cmds(line_number, l)
- self._check_one_space_cmds(line_number, l)
- self._check_indent(line_number, line_content)
- def _check_trailing_whitespace(self, line_number, line_content):
- line_content = line_content.rstrip('\n') # chr(10), newline
- line_content = line_content.rstrip('\r') # chr(13), carriage return
- line_content = line_content.rstrip('\x0c') # chr(12), form feed, ^L
- stripped = line_content.rstrip()
- if line_content != stripped:
- self._handle_style_error(line_number, 'whitespace/trailing', 5,
- 'No trailing spaces')
- def _check_no_space_cmds(self, line_number, line_content):
- # check command like "SET (" or "Set("
- for t in self.NO_SPACE_CMDS:
- self._check_non_lowercase_cmd(line_number, line_content, t)
- if re.search('(^|\ +)' + t.lower() + '\ +\(', line_content):
- msg = 'No space between command "' + t.lower() + '" and its parentheses, should be "' + t + '("'
- self._handle_style_error(line_number, 'whitespace/parentheses', 5, msg)
- def _check_one_space_cmds(self, line_number, line_content):
- # check command like "IF (" or "if(" or "if (" or "If ()"
- for t in self.ONE_SPACE_CMDS:
- self._check_non_lowercase_cmd(line_number, line_content, t)
- if re.search('(^|\ +)' + t.lower() + '(\(|\ \ +\()', line_content):
- msg = 'One space between command "' + t.lower() + '" and its parentheses, should be "' + t + ' ("'
- self._handle_style_error(line_number, 'whitespace/parentheses', 5, msg)
- def _check_non_lowercase_cmd(self, line_number, line_content, cmd):
- if re.search('(^|\ +)' + cmd + '\ *\(', line_content, flags=re.IGNORECASE) and \
- (not re.search('(^|\ +)' + cmd.lower() + '\ *\(', line_content)):
- msg = 'Use lowercase command "' + cmd.lower() + '"'
- self._handle_style_error(line_number, 'command/lowercase', 5, msg)
- def _check_indent(self, line_number, line_content):
- #TODO (halton): add indent checking
- pass
|