xref: /aosp_15_r20/external/deqp/scripts/src_util/check_include_guards.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
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
23import os
24import sys
25from fnmatch import fnmatch
26from optparse import OptionParser
27
28HEADER_PATTERNS = ["*.hpp", "*.h"]
29IGNORE_FILES = set(["tcuEAGLView.h", "tcuIOSAppDelegate.h", "tcuIOSViewController.h"])
30CHECK_END_COMMENT = True
31
32def getIncludeGuardName (headerFile):
33    return '_' + os.path.basename(headerFile).upper().replace('.', '_')
34
35def hasValidIncludeGuard (headerFile):
36    includeGuard = getIncludeGuardName(headerFile)
37    f = open(headerFile, 'rt')
38    isHpp = headerFile[-4:] == ".hpp"
39
40    line0 = f.readline().strip()
41    line1 = f.readline().strip()
42
43    if line0 != ("#ifndef %s" % includeGuard):
44        return False
45    if line1 != ("#define %s" % includeGuard):
46        return False
47
48    if CHECK_END_COMMENT:
49        lastLine = ""
50        expectedComment = ("#endif // %s" if isHpp else "#endif /* %s */") % includeGuard
51        for line in f:
52            lastLine = line.strip()
53
54        if lastLine != expectedComment:
55#            print("'%s' != '%s'" % (lastLine, expectedComment))
56            return False
57
58    f.close()
59    return True
60
61def fixIncludeGuard (headerFile):
62    f = open(headerFile, 'rt')
63    lines = []
64    isHpp = headerFile[-4:] == ".hpp"
65    includeGuard =  getIncludeGuardName(headerFile)
66
67    for line in f:
68        lines.append(line)
69    f.close()
70
71    # Replace include guards
72    lines[0] = "#ifndef %s\n" % includeGuard
73    lines[1] = "#define %s\n" % includeGuard
74
75    if CHECK_END_COMMENT:
76        lines[len(lines)-1] = ("#endif // %s\n" if isHpp else "#endif /* %s */\n") % includeGuard
77
78    f = open(headerFile, 'wt')
79    for line in lines:
80        f.write(line)
81    f.close()
82
83def isHeader (filename):
84    if os.path.basename(filename) in IGNORE_FILES:
85        return False
86
87    for pattern in HEADER_PATTERNS:
88        if fnmatch(filename, pattern):
89            return True
90    return False
91
92def getHeaderFileList (path):
93    headers = []
94    if os.path.isfile(path):
95        if isHeader(path):
96            headers.append(path)
97    else:
98        for root, dirs, files in os.walk(path):
99            for file in files:
100                if isHeader(file):
101                    headers.append(os.path.join(root, file))
102    return headers
103
104def checkIncludeGuards (files):
105    error = False
106    for file in files:
107        if isHeader(file):
108            if not hasValidIncludeGuard(file):
109                error = True
110                print("File %s contains invalid include guards" % file)
111    return not error
112
113if __name__ == "__main__":
114    parser = OptionParser()
115    parser.add_option("-x", "--fix", action="store_true", dest="fix", default=False, help="attempt to fix include guards (use with caution)")
116
117    (options, args) = parser.parse_args()
118    fix = options.fix
119    headers = []
120    invalidHeaders = []
121
122    for dir in args:
123        headers += getHeaderFileList(os.path.normpath(dir))
124
125    print("Checking...")
126    for header in headers:
127        print("  %s" % header)
128        if not hasValidIncludeGuard(header):
129            invalidHeaders.append(header)
130
131    print("")
132    if len(invalidHeaders) > 0:
133        print("Found %d files with invalid include guards:" % len(invalidHeaders))
134
135        for header in invalidHeaders:
136            print("  %s" % header)
137
138        if not fix:
139            sys.exit(-1)
140    else:
141        print("All headers have valid include guards.")
142
143    if fix:
144        print("")
145        for header in invalidHeaders:
146            fixIncludeGuard(header)
147            print("Fixed %s" % header)
148