Merge "Fix off-by-one in info log query."
[platform/upstream/VK-GL-CTS.git] / scripts / check_redundant_include_guards.py
1 # -*- coding: utf-8 -*-
2
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
6 #
7 # Copyright 2015 The Android Open Source Project
8 #
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #      http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 #-------------------------------------------------------------------------
22
23 import os
24 import sys
25 from fnmatch import fnmatch
26 from optparse import OptionParser
27
28 HEADER_PATTERNS                         = ["*.hpp", "*.h"]
29 INDENTED_INCLUDE_PREFIX         = "#\tinclude "
30 IFNDEF_PREFIX                           = "#ifndef "
31
32 def getIncludeGuardName (headerFile):
33         return '_' + os.path.basename(headerFile).upper().replace('.', '_')
34
35 def getRedundantIncludeGuardErrors (fileName):
36         f               = open(fileName, 'rb')
37         errors  = []
38
39         lineNumber = 1
40         prevLine = None
41         for line in f:
42                 if line.startswith(INDENTED_INCLUDE_PREFIX):
43                         if prevLine is not None and prevLine.startswith(IFNDEF_PREFIX):
44                                 ifndefName              = prevLine[len(IFNDEF_PREFIX):-1]                       # \note -1 to take out the newline.
45                                 includeName             = line[len(INDENTED_INCLUDE_PREFIX)+1:-2]       # \note +1 to take out the beginning quote, -2 to take out the newline and the ending quote.
46                                 if getIncludeGuardName(includeName) != ifndefName:
47                                         errors.append("Invalid redundant include guard around line %d:" % lineNumber)
48                                         errors.append("guard is %s but included file is %s" % (ifndefName, includeName))
49
50                 prevLine = line
51                 lineNumber += 1
52
53         f.close()
54         return errors
55
56 def isHeader (filename):
57         for pattern in HEADER_PATTERNS:
58                 if fnmatch(filename, pattern):
59                         return True
60         return False
61
62 def getFileList (path):
63         allFiles = []
64         if os.path.isfile(path):
65                 if isHeader(path):
66                         allFiles.append(path)
67         else:
68                 for root, dirs, files in os.walk(path):
69                         for file in files:
70                                 if isHeader(file):
71                                         allFiles.append(os.path.join(root, file))
72         return allFiles
73
74 if __name__ == "__main__":
75         parser = OptionParser()
76         parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False, help="only print files with errors")
77
78         (options, args) = parser.parse_args()
79         quiet                   = options.quiet
80         files                   = []
81         invalidFiles    = []
82
83         for dir in args:
84                 files += getFileList(os.path.normpath(dir))
85
86         print "Checking..."
87         for file in files:
88                 if not quiet:
89                         print "  %s" % file
90
91                 errors = getRedundantIncludeGuardErrors(file)
92                 if errors:
93                         if quiet:
94                                 print "  %s" % file
95                         for err in errors:
96                                 print "    %s" % err
97                         invalidFiles.append(file)
98
99         print ""
100         if len(invalidFiles) > 0:
101                 print "Found %d files with invalid redundant include guards:" % len(invalidFiles)
102
103                 for file in invalidFiles:
104                         print "  %s" % file
105
106                 sys.exit(-1)
107         else:
108                 print "All files have valid redundant include guards."