Added: trunk/Tools/Scripts/webkitpy/style/checkers/cmake.py (0 => 137057)
--- trunk/Tools/Scripts/webkitpy/style/checkers/cmake.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cmake.py 2012-12-09 07:46:55 UTC (rev 137057)
@@ -0,0 +1,150 @@
+# 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
Added: trunk/Tools/Scripts/webkitpy/style/checkers/cmake_unittest.py (0 => 137057)
--- trunk/Tools/Scripts/webkitpy/style/checkers/cmake_unittest.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cmake_unittest.py 2012-12-09 07:46:55 UTC (rev 137057)
@@ -0,0 +1,90 @@
+# 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+
+"""Unit test for cmake.py."""
+
+import unittest
+
+from cmake import CMakeChecker
+
+
+class CMakeCheckerTest(unittest.TestCase):
+
+ """Tests CMakeChecker class."""
+
+ def test_init(self):
+ """Test __init__() method."""
+ def _mock_handle_style_error(self):
+ pass
+
+ checker = CMakeChecker("foo.cmake", _mock_handle_style_error)
+ self.assertEqual(checker._handle_style_error, _mock_handle_style_error)
+
+ def test_check(self):
+ """Test check() method."""
+ errors = []
+
+ def _mock_handle_style_error(line_number, category, confidence,
+ message):
+ error = (line_number, category, confidence, message)
+ errors.append(error)
+
+ checker = CMakeChecker("foo.cmake", _mock_handle_style_error)
+
+ lines = [
+ '# This file is sample input for cmake_unittest.py and includes below problems:\n',
+ 'IF ()',
+ '\tmessage("Error line with Tab")\n',
+ ' message("Error line with endding spaces") \n',
+ ' message( "Error line with space after (")\n',
+ ' message("Error line with space before (" )\n',
+ ' MESSAGE("Error line with upper case non-condtional command")\n',
+ ' MESSage("Error line with upper case non-condtional command")\n',
+ ' message("correct message line")\n',
+ 'ENDif ()\n',
+ '\n',
+ 'if()\n',
+ 'endif ()\n',
+ '\n',
+ 'macro ()\n',
+ 'ENDMacro()\n',
+ '\n',
+ 'function ()\n',
+ 'endfunction()\n',
+ ]
+ checker.check(lines)
+
+ self.maxDiff = None
+ self.assertEqual(errors, [
+ (3, 'whitespace/tab', 5, 'Line contains tab character.'),
+ (2, 'command/lowercase', 5, 'Use lowercase command "if"'),
+ (4, 'whitespace/trailing', 5, 'No trailing spaces'),
+ (5, 'whitespace/parentheses', 5, 'No space after "("'),
+ (6, 'whitespace/parentheses', 5, 'No space before ")"'),
+ (7, 'command/lowercase', 5, 'Use lowercase command "message"'),
+ (8, 'command/lowercase', 5, 'Use lowercase command "message"'),
+ (10, 'command/lowercase', 5, 'Use lowercase command "endif"'),
+ (12, 'whitespace/parentheses', 5, 'One space between command "if" and its parentheses, should be "if ("'),
+ (15, 'whitespace/parentheses', 5, 'No space between command "macro" and its parentheses, should be "macro("'),
+ (16, 'command/lowercase', 5, 'Use lowercase command "endmacro"'),
+ (18, 'whitespace/parentheses', 5, 'No space between command "function" and its parentheses, should be "function("'),
+ ])