Add tsk_destructor() to free task's kobject
[helenos.git] / tools / checkers / vcc.py
bloba6f6ee783d1b1f3e8007351fcc8c1eb731d698c7
1 #!/usr/bin/env python
3 # Copyright (c) 2010 Martin Decky
4 # Copyright (c) 2010 Ondrej Sery
5 # All rights reserved.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
11 # - Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # - Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # - The name of the author may not be used to endorse or promote products
17 # derived from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 """
31 Wrapper for Vcc checker
32 """
34 import sys
35 import os
36 import subprocess
37 import jobfile
38 import re
40 jobs = [
41 "kernel/kernel.job"
44 re_attribute = re.compile("__attribute__\s*\(\(.*\)\)")
45 re_va_list = re.compile("__builtin_va_list")
47 specification = ""
49 def usage(prname):
50 "Print usage syntax"
51 print(prname + " <ROOT> [VCC_PATH]")
53 def cygpath(upath):
54 "Convert Unix (Cygwin) path to Windows path"
56 return subprocess.Popen(['cygpath', '--windows', '--absolute', upath], stdout = subprocess.PIPE).communicate()[0].strip()
58 def preprocess(srcfname, tmpfname, base, options):
59 "Preprocess source using GCC preprocessor and compatibility tweaks"
61 global specification
63 args = ['gcc', '-E']
64 args.extend(options.split())
65 args.extend(['-DCONFIG_VERIFY_VCC=1', srcfname])
67 # Change working directory
69 cwd = os.getcwd()
70 os.chdir(base)
72 preproc = subprocess.Popen(args, stdout = subprocess.PIPE).communicate()[0]
74 tmpf = open(tmpfname, "w")
75 tmpf.write(specification)
77 for line in preproc.splitlines():
79 # Ignore preprocessor directives
81 if (line.startswith('#')):
82 continue
84 # Remove __attribute__((.*)) GCC extension
86 line = re.sub(re_attribute, "", line)
88 # Ignore unsupported __builtin_va_list type
89 # (a better solution replacing __builrin_va_list with
90 # an emulated implementation is needed)
92 line = re.sub(re_va_list, "void *", line)
94 tmpf.write("%s\n" % line)
96 tmpf.close()
98 os.chdir(cwd)
100 return True
102 def vcc(vcc_path, root, job):
103 "Run Vcc on a jobfile"
105 # Parse jobfile
107 inname = os.path.join(root, job)
109 if (not os.path.isfile(inname)):
110 print("Unable to open %s" % inname)
111 print("Did you run \"make precheck\" on the source tree?")
112 return False
114 inf = open(inname, "r")
115 records = inf.read().splitlines()
116 inf.close()
118 for record in records:
119 arg = jobfile.parse_arg(record)
120 if (not arg):
121 return False
123 if (len(arg) < 6):
124 print("Not enough jobfile record arguments")
125 return False
127 srcfname = arg[0]
128 tgtfname = arg[1]
129 tool = arg[2]
130 category = arg[3]
131 base = arg[4]
132 options = arg[5]
134 srcfqname = os.path.join(base, srcfname)
135 if (not os.path.isfile(srcfqname)):
136 print("Source %s not found" % srcfqname)
137 return False
139 tmpfname = "%s.preproc" % srcfname
140 tmpfqname = os.path.join(base, tmpfname)
142 vccfname = "%s.i" % srcfname
143 vccfqname = os.path.join(base, vccfname);
145 # Only C files are interesting for us
146 if (tool != "cc"):
147 continue
149 # Preprocess sources
151 if (not preprocess(srcfname, tmpfname, base, options)):
152 return False
154 # Run Vcc
155 print(" -- %s --" % srcfname)
156 retval = subprocess.Popen([vcc_path, '/pointersize:32', '/newsyntax', cygpath(tmpfqname)]).wait()
158 if (retval != 0):
159 return False
161 # Cleanup, but only if verification was successful
162 # (to be able to examine the preprocessed file)
164 if (os.path.isfile(tmpfqname)):
165 os.remove(tmpfqname)
166 os.remove(vccfqname)
168 return True
170 def main():
171 global specification
173 if (len(sys.argv) < 2):
174 usage(sys.argv[0])
175 return
177 rootdir = os.path.abspath(sys.argv[1])
178 if (len(sys.argv) > 2):
179 vcc_path = sys.argv[2]
180 else:
181 vcc_path = "/cygdrive/c/Program Files (x86)/Microsoft Research/Vcc/Binaries/vcc"
183 if (not os.path.isfile(vcc_path)):
184 print("%s is not a binary." % vcc_path)
185 print("Please supply the full Cygwin path to Vcc as the second argument.")
186 return
188 config = os.path.join(rootdir, "HelenOS.config")
190 if (not os.path.isfile(config)):
191 print("%s not found." % config)
192 print("Please specify the path to HelenOS build tree root as the first argument.")
193 return
195 specpath = os.path.join(rootdir, "tools/checkers/vcc.h")
196 if (not os.path.isfile(specpath)):
197 print("%s not found." % config)
198 return
200 specfile = file(specpath, "r")
201 specification = specfile.read()
202 specfile.close()
204 for job in jobs:
205 if (not vcc(vcc_path, rootdir, job)):
206 print()
207 print("Failed job: %s" % job)
208 return
210 print()
211 print("All jobs passed")
213 if __name__ == '__main__':
214 main()