| Index: tools/checkdeps/checkdeps.py
|
| diff --git a/tools/checkdeps/checkdeps.py b/tools/checkdeps/checkdeps.py
|
| index dae44c336da50728f03e8f3a6c5973cf773fc5b6..9624812086a0d732db98a5a0e5825d4bad09b739 100755
|
| --- a/tools/checkdeps/checkdeps.py
|
| +++ b/tools/checkdeps/checkdeps.py
|
| @@ -55,10 +55,13 @@ only lowercase.
|
| import os
|
| import optparse
|
| import pipes
|
| -import re
|
| import sys
|
| import copy
|
|
|
| +import cpp_checker
|
| +import java_checker
|
| +
|
| +
|
| # Variable name used in the DEPS file to add or subtract include files from
|
| # the module-level deps.
|
| INCLUDE_RULES_VAR_NAME = "include_rules"
|
| @@ -67,20 +70,9 @@ INCLUDE_RULES_VAR_NAME = "include_rules"
|
| # be checked. This allows us to skip third party code, for example.
|
| SKIP_SUBDIRS_VAR_NAME = "skip_child_includes"
|
|
|
| -# The maximum number of non-include lines we can see before giving up.
|
| -MAX_UNINTERESTING_LINES = 50
|
| -
|
| -# The maximum line length, this is to be efficient in the case of very long
|
| -# lines (which can't be #includes).
|
| -MAX_LINE_LENGTH = 128
|
| -
|
| # Set to true for more output. This is set by the command line options.
|
| VERBOSE = False
|
|
|
| -# This regular expression will be used to extract filenames from include
|
| -# statements.
|
| -EXTRACT_INCLUDE_PATH = re.compile('[ \t]*#[ \t]*(?:include|import)[ \t]+"(.*)"')
|
| -
|
| # In lowercase, using forward slashes as directory separators, ending in a
|
| # forward slash. Set by the command line options.
|
| BASE_DIRECTORY = ""
|
| @@ -91,13 +83,13 @@ GIT_SOURCE_DIRECTORY = set()
|
|
|
| # Specifies a single rule for an include, which can be either allow or disallow.
|
| class Rule(object):
|
| - def __init__(self, allow, dir, source):
|
| - self._allow = allow
|
| - self._dir = dir
|
| + def __init__(self, allow, directory, source):
|
| + self.allow = allow
|
| + self._dir = directory
|
| self._source = source
|
|
|
| def __str__(self):
|
| - if (self._allow):
|
| + if (self.allow):
|
| return '"+%s" from %s.' % (self._dir, self._source)
|
| return '"-%s" from %s.' % (self._dir, self._source)
|
|
|
| @@ -160,7 +152,7 @@ class Rules:
|
| for rule in self._rules:
|
| if rule.ChildOrMatch(allowed_dir):
|
| # This rule applies.
|
| - if rule._allow:
|
| + if rule.allow:
|
| return (True, "")
|
| return (False, rule.__str__())
|
| # No rules apply, fail.
|
| @@ -196,7 +188,7 @@ def ApplyRules(existing_rules, includes, cur_dir):
|
| (cur_dir, BASE_DIRECTORY))
|
|
|
| # Last, apply the additional explicit rules.
|
| - for (index, rule_str) in enumerate(includes):
|
| + for (_, rule_str) in enumerate(includes):
|
| if not len(relative_dir):
|
| rule_description = "the top level include_rules"
|
| else:
|
| @@ -233,10 +225,10 @@ def ApplyDirectoryRules(existing_rules, dir_name):
|
| # Check the DEPS file in this directory.
|
| if VERBOSE:
|
| print "Applying rules from", dir_name
|
| - def FromImpl(unused, unused2):
|
| + def FromImpl(_unused, _unused2):
|
| pass # NOP function so "From" doesn't fail.
|
|
|
| - def FileImpl(unused):
|
| + def FileImpl(_unused):
|
| pass # NOP function so "File" doesn't fail.
|
|
|
| class _VarImpl:
|
| @@ -247,7 +239,7 @@ def ApplyDirectoryRules(existing_rules, dir_name):
|
| """Implements the Var syntax."""
|
| if var_name in self._local_scope.get("vars", {}):
|
| return self._local_scope["vars"][var_name]
|
| - raise Error("Var is not defined: %s" % var_name)
|
| + raise Exception("Var is not defined: %s" % var_name)
|
|
|
| local_scope = {}
|
| global_scope = {
|
| @@ -270,111 +262,7 @@ def ApplyDirectoryRules(existing_rules, dir_name):
|
| return (ApplyRules(existing_rules, include_rules, dir_name), skip_subdirs)
|
|
|
|
|
| -def ShouldCheckFile(file_name):
|
| - """Returns True if the given file is a type we want to check."""
|
| - checked_extensions = [
|
| - '.h',
|
| - '.cc',
|
| - '.m',
|
| - '.mm',
|
| - ]
|
| - basename, extension = os.path.splitext(file_name)
|
| - return extension in checked_extensions
|
| -
|
| -
|
| -def CheckLine(rules, line):
|
| - """Checks the given file with the given rule set.
|
| - Returns a tuple (is_include, illegal_description).
|
| - If the line is an #include directive the first value will be True.
|
| - If it is also an illegal include, the second value will be a string describing
|
| - the error. Otherwise, it will be None."""
|
| - found_item = EXTRACT_INCLUDE_PATH.match(line)
|
| - if not found_item:
|
| - return False, None # Not a match
|
| -
|
| - include_path = found_item.group(1)
|
| -
|
| - # Fix up backslashes in case somebody accidentally used them.
|
| - include_path.replace("\\", "/")
|
| -
|
| - if include_path.find("/") < 0:
|
| - # Don't fail when no directory is specified. We may want to be more
|
| - # strict about this in the future.
|
| - if VERBOSE:
|
| - print " WARNING: directory specified with no path: " + include_path
|
| - return True, None
|
| -
|
| - (allowed, why_failed) = rules.DirAllowed(include_path)
|
| - if not allowed:
|
| - if VERBOSE:
|
| - retval = "\nFor " + rules.__str__()
|
| - else:
|
| - retval = ""
|
| - return True, retval + ('Illegal include: "%s"\n Because of %s' %
|
| - (include_path, why_failed))
|
| -
|
| - return True, None
|
| -
|
| -
|
| -def CheckFile(rules, file_name):
|
| - """Checks the given file with the given rule set.
|
| -
|
| - Args:
|
| - rules: The set of rules that apply to files in this directory.
|
| - file_name: The source file to check.
|
| -
|
| - Returns: Either a string describing the error if there was one, or None if
|
| - the file checked out OK.
|
| - """
|
| - if VERBOSE:
|
| - print "Checking: " + file_name
|
| -
|
| - ret_val = "" # We'll collect the error messages in here
|
| - last_include = 0
|
| - try:
|
| - cur_file = open(file_name, "r")
|
| - in_if0 = 0
|
| - for line_num in xrange(sys.maxint):
|
| - if line_num - last_include > MAX_UNINTERESTING_LINES:
|
| - break
|
| -
|
| - cur_line = cur_file.readline(MAX_LINE_LENGTH)
|
| - if cur_line == "":
|
| - break
|
| - cur_line = cur_line.strip()
|
| -
|
| - # Check to see if we're at / inside a #if 0 block
|
| - if cur_line == '#if 0':
|
| - in_if0 += 1
|
| - continue
|
| - if in_if0 > 0:
|
| - if cur_line.startswith('#if'):
|
| - in_if0 += 1
|
| - elif cur_line == '#endif':
|
| - in_if0 -= 1
|
| - continue
|
| -
|
| - is_include, line_status = CheckLine(rules, cur_line)
|
| - if is_include:
|
| - last_include = line_num
|
| - if line_status is not None:
|
| - if len(line_status) > 0: # Add newline to separate messages.
|
| - line_status += "\n"
|
| - ret_val += line_status
|
| - cur_file.close()
|
| -
|
| - except IOError:
|
| - if VERBOSE:
|
| - print "Unable to open file: " + file_name
|
| - cur_file.close()
|
| -
|
| - # Map empty string to None for easier checking.
|
| - if len(ret_val) == 0:
|
| - return None
|
| - return ret_val
|
| -
|
| -
|
| -def CheckDirectory(parent_rules, dir_name):
|
| +def CheckDirectory(parent_rules, checkers, dir_name):
|
| (rules, skip_subdirs) = ApplyDirectoryRules(parent_rules, dir_name)
|
| if rules == None:
|
| return True
|
| @@ -390,19 +278,20 @@ def CheckDirectory(parent_rules, dir_name):
|
| full_name = os.path.join(dir_name, cur)
|
| if os.path.isdir(full_name):
|
| dirs_to_check.append(full_name)
|
| - elif ShouldCheckFile(full_name):
|
| + elif os.path.splitext(full_name)[1] in checkers:
|
| files_to_check.append(full_name)
|
|
|
| # First check all files in this directory.
|
| for cur in files_to_check:
|
| - file_status = CheckFile(rules, cur)
|
| - if file_status != None:
|
| + checker = checkers[os.path.splitext(cur)[1]]
|
| + file_status = checker.CheckFile(rules, cur)
|
| + if file_status:
|
| print "ERROR in " + cur + "\n" + file_status
|
| success = False
|
|
|
| # Next recurse into the subdirectories.
|
| for cur in dirs_to_check:
|
| - if not CheckDirectory(rules, cur):
|
| + if not CheckDirectory(rules, checkers, cur):
|
| success = False
|
|
|
| return success
|
| @@ -488,7 +377,12 @@ def checkdeps(options, args):
|
| global GIT_SOURCE_DIRECTORY
|
| GIT_SOURCE_DIRECTORY = GetGitSourceDirectory(BASE_DIRECTORY)
|
|
|
| - success = CheckDirectory(base_rules, start_dir)
|
| + java = java_checker.JavaChecker(BASE_DIRECTORY, VERBOSE)
|
| + cpp = cpp_checker.CppChecker(VERBOSE)
|
| + checkers = dict(
|
| + (extension, checker)
|
| + for checker in [java, cpp] for extension in checker.EXTENSIONS)
|
| + success = CheckDirectory(base_rules, checkers, start_dir)
|
| if not success:
|
| print "\nFAILED\n"
|
| return 1
|
|
|