source: mainline/tools/checkers/vcc.py@ 77578e8

Last change on this file since 77578e8 was 4dd3912, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update python scripts

  • Property mode set to 100755
File size: 4.0 KB
Line 
1#!/usr/bin/env python
2#
3# SPDX-FileCopyrightText: 2010 Martin Decky
4# SPDX-FileCopyrightText: 2010 Ondrej Sery
5#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8"""
9Wrapper for Vcc checker
10"""
11
12import sys
13import os
14import subprocess
15import jobfile
16import re
17
18jobs = [
19 "kernel/kernel.job"
20]
21
22re_attribute = re.compile("__attribute__\s*\(\(.*\)\)")
23re_va_list = re.compile("__builtin_va_list")
24
25specification = ""
26
27def usage(prname):
28 "Print usage syntax"
29 print(prname + " <ROOT> [VCC_PATH]")
30
31def cygpath(upath):
32 "Convert Unix (Cygwin) path to Windows path"
33
34 return subprocess.Popen(['cygpath', '--windows', '--absolute', upath], stdout = subprocess.PIPE).communicate()[0].strip()
35
36def preprocess(srcfname, tmpfname, base, options):
37 "Preprocess source using GCC preprocessor and compatibility tweaks"
38
39 global specification
40
41 args = ['gcc', '-E']
42 args.extend(options.split())
43 args.extend(['-DCONFIG_VERIFY_VCC=1', srcfname])
44
45 # Change working directory
46
47 cwd = os.getcwd()
48 os.chdir(base)
49
50 preproc = subprocess.Popen(args, stdout = subprocess.PIPE).communicate()[0]
51
52 tmpf = open(tmpfname, "w")
53 tmpf.write(specification)
54
55 for line in preproc.splitlines():
56
57 # Ignore preprocessor directives
58
59 if (line.startswith('#')):
60 continue
61
62 # Remove __attribute__((.*)) GCC extension
63
64 line = re.sub(re_attribute, "", line)
65
66 # Ignore unsupported __builtin_va_list type
67 # (a better solution replacing __builrin_va_list with
68 # an emulated implementation is needed)
69
70 line = re.sub(re_va_list, "void *", line)
71
72 tmpf.write("%s\n" % line)
73
74 tmpf.close()
75
76 os.chdir(cwd)
77
78 return True
79
80def vcc(vcc_path, root, job):
81 "Run Vcc on a jobfile"
82
83 # Parse jobfile
84
85 inname = os.path.join(root, job)
86
87 if (not os.path.isfile(inname)):
88 print("Unable to open %s" % inname)
89 print("Did you run \"make precheck\" on the source tree?")
90 return False
91
92 inf = open(inname, "r")
93 records = inf.read().splitlines()
94 inf.close()
95
96 for record in records:
97 arg = jobfile.parse_arg(record)
98 if (not arg):
99 return False
100
101 if (len(arg) < 6):
102 print("Not enough jobfile record arguments")
103 return False
104
105 srcfname = arg[0]
106 tgtfname = arg[1]
107 tool = arg[2]
108 category = arg[3]
109 base = arg[4]
110 options = arg[5]
111
112 srcfqname = os.path.join(base, srcfname)
113 if (not os.path.isfile(srcfqname)):
114 print("Source %s not found" % srcfqname)
115 return False
116
117 tmpfname = "%s.preproc" % srcfname
118 tmpfqname = os.path.join(base, tmpfname)
119
120 vccfname = "%s.i" % srcfname
121 vccfqname = os.path.join(base, vccfname);
122
123 # Only C files are interesting for us
124 if (tool != "cc"):
125 continue
126
127 # Preprocess sources
128
129 if (not preprocess(srcfname, tmpfname, base, options)):
130 return False
131
132 # Run Vcc
133 print(" -- %s --" % srcfname)
134 retval = subprocess.Popen([vcc_path, '/pointersize:32', '/newsyntax', cygpath(tmpfqname)]).wait()
135
136 if (retval != 0):
137 return False
138
139 # Cleanup, but only if verification was successful
140 # (to be able to examine the preprocessed file)
141
142 if (os.path.isfile(tmpfqname)):
143 os.remove(tmpfqname)
144 os.remove(vccfqname)
145
146 return True
147
148def main():
149 global specification
150
151 if (len(sys.argv) < 2):
152 usage(sys.argv[0])
153 return
154
155 rootdir = os.path.abspath(sys.argv[1])
156 if (len(sys.argv) > 2):
157 vcc_path = sys.argv[2]
158 else:
159 vcc_path = "/cygdrive/c/Program Files (x86)/Microsoft Research/Vcc/Binaries/vcc"
160
161 if (not os.path.isfile(vcc_path)):
162 print("%s is not a binary." % vcc_path)
163 print("Please supply the full Cygwin path to Vcc as the second argument.")
164 return
165
166 config = os.path.join(rootdir, "HelenOS.config")
167
168 if (not os.path.isfile(config)):
169 print("%s not found." % config)
170 print("Please specify the path to HelenOS build tree root as the first argument.")
171 return
172
173 specpath = os.path.join(rootdir, "tools/checkers/vcc.h")
174 if (not os.path.isfile(specpath)):
175 print("%s not found." % config)
176 return
177
178 specfile = file(specpath, "r")
179 specification = specfile.read()
180 specfile.close()
181
182 for job in jobs:
183 if (not vcc(vcc_path, rootdir, job)):
184 print()
185 print("Failed job: %s" % job)
186 return
187
188 print()
189 print("All jobs passed")
190
191if __name__ == '__main__':
192 main()
Note: See TracBrowser for help on using the repository browser.