Add check_all.py and check_whitespace.py scripts.
Change-Id: I29ea94aa38ad1cb9e665836db6e4d48d3dbc041b
diff --git a/scripts/src_util/check_all.py b/scripts/src_util/check_all.py
new file mode 100644
index 0000000..f666a78
--- /dev/null
+++ b/scripts/src_util/check_all.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
+import sys
+from argparse import ArgumentParser
+from common import getChangedFiles, getAllProjectFiles
+from check_include_guards import checkIncludeGuards
+from check_whitespace import checkWhitespace
+
+if __name__ == "__main__":
+ parser = ArgumentParser()
+ parser.add_argument("-e", "--only-errors", action="store_true", dest="onlyErrors", default=False, help="Print only on error")
+ parser.add_argument("-i", "--only-changed", action="store_true", dest="useGitIndex", default=False, help="Check only modified files. Uses git.")
+
+ args = parser.parse_args()
+
+ if args.useGitIndex:
+ files = getChangedFiles()
+ else:
+ files = getAllProjectFiles()
+
+ error = not all([
+ checkWhitespace(files),
+ checkIncludeGuards(files),
+ #todo checkRedundantIncludeGuards(files),
+ ])
+
+ if error:
+ print "One or more checks failed"
+ sys.exit(1)
+ if not args.onlyErrors:
+ print "All checks passed"
diff --git a/scripts/src_util/check_include_guards.py b/scripts/src_util/check_include_guards.py
index 085ba0c..fa792e1 100644
--- a/scripts/src_util/check_include_guards.py
+++ b/scripts/src_util/check_include_guards.py
@@ -97,6 +97,15 @@
headers.append(os.path.join(root, file))
return headers
+def checkIncludeGuards (files):
+ error = False
+ for file in files:
+ if isHeader(file):
+ if not hasValidIncludeGuard(file):
+ error = True
+ print "File %s contains invalid include guards" % file
+ return not error
+
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-x", "--fix", action="store_true", dest="fix", default=False, help="attempt to fix include guards (use with caution)")
diff --git a/scripts/src_util/check_whitespace.py b/scripts/src_util/check_whitespace.py
new file mode 100644
index 0000000..7d079bf
--- /dev/null
+++ b/scripts/src_util/check_whitespace.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
+import sys
+from argparse import ArgumentParser
+from common import getChangedFiles, getAllProjectFiles, isTextFile
+
+def checkFileWhitespace (file):
+ f = open(file, 'rb')
+ error = False
+ for lineNum, line in enumerate(f):
+ if line.endswith(" \n") or line.endswith("\t\n"):
+ error = True
+ print "%s:%i trailing whitespace" % (file, lineNum+1)
+ if " \t" in line:
+ error = True
+ print "%s:%i merged <space><tab>" % (file, lineNum+1)
+ f.close()
+
+ return not error
+
+def checkWhitespace (files):
+ error = False
+ for file in files:
+ if isTextFile(file):
+ if not checkFileWhitespace(file):
+ error = True
+
+ return not error
+
+if __name__ == "__main__":
+ parser = ArgumentParser()
+ parser.add_argument("-e", "--only-errors", action="store_true", dest="onlyErrors", default=False, help="Print only on error")
+ parser.add_argument("-i", "--only-changed", action="store_true", dest="useGitIndex", default=False, help="Check only modified files. Uses git.")
+
+ args = parser.parse_args()
+
+ if args.useGitIndex:
+ files = getChangedFiles()
+ else:
+ files = getAllProjectFiles()
+
+ error = not checkWhitespace(files)
+
+ if error:
+ print "One or more checks failed"
+ sys.exit(1)
+ if not args.onlyErrors:
+ print "All checks passed"
diff --git a/scripts/src_util/common.py b/scripts/src_util/common.py
new file mode 100644
index 0000000..536573b
--- /dev/null
+++ b/scripts/src_util/common.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
+import os
+import subprocess
+
+TEXT_FILE_EXTENSION = [
+ ".bat",
+ ".c",
+ ".cfg",
+ ".cmake",
+ ".cpp",
+ ".css",
+ ".h",
+ ".hh",
+ ".hpp",
+ ".html",
+ ".inl",
+ ".java",
+ ".js",
+ ".m",
+ ".mk",
+ ".mm",
+ ".py",
+ ".rule",
+ ".sh",
+ ".test",
+ ".txt",
+ ".xml",
+ ".xsl",
+ ]
+
+BINARY_FILE_EXTENSION = [
+ ".png",
+ ".pkm",
+ ".xcf",
+ ]
+
+def isTextFile (filePath):
+ ext = os.path.splitext(filePath)[1]
+ if ext in TEXT_FILE_EXTENSION:
+ return True
+ if ext in BINARY_FILE_EXTENSION:
+ return False
+
+ # Analyze file contents, zero byte is the marker for a binary file
+ f = open(filePath, "rb")
+
+ TEST_LIMIT = 1024
+ nullFound = False
+ numBytesTested = 0
+
+ byte = f.read(1)
+ while byte and numBytesTested < TEST_LIMIT:
+ if byte == "\0":
+ nullFound = True
+ break
+
+ byte = f.read(1)
+ numBytesTested += 1
+
+ f.close()
+ return not nullFound
+
+def getProjectPath ():
+ # File system hierarchy is fixed
+ scriptDir = os.path.dirname(os.path.abspath(__file__))
+ projectDir = os.path.normpath(os.path.join(scriptDir, "../.."))
+ return projectDir
+
+def git (*args):
+ process = subprocess.Popen(['git'] + list(args), cwd=getProjectPath(), stdout=subprocess.PIPE)
+ output = process.communicate()[0]
+ if process.returncode != 0:
+ raise Exception("Failed to execute '%s', got %d" % (str(args), process.returncode))
+ return output
+
+def getAbsolutePathPathFromProjectRelativePath (projectRelativePath):
+ return os.path.normpath(os.path.join(getProjectPath(), projectRelativePath))
+
+def getChangedFiles ():
+ # Added, Copied, Moved, Renamed
+ output = git('diff', '--cached', '--name-only', '-z', '--diff-filter=ACMR')
+ relativePaths = output.split('\0')[:-1] # remove trailing ''
+ return [getAbsolutePathPathFromProjectRelativePath(path) for path in relativePaths]
+
+def getAllProjectFiles ():
+ output = git('ls-files', '--cached', '-z')
+ relativePaths = output.split('\0')[:-1] # remove trailing ''
+ return [getAbsolutePathPathFromProjectRelativePath(path) for path in relativePaths]