3 # Copyright (c) 2010 Martin Decky
4 # Copyright (c) 2010 Ondrej Sery
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
31 Wrapper for Vcc checker
44 re_attribute
= re
.compile("__attribute__\s*\(\(.*\)\)")
45 re_va_list
= re
.compile("__builtin_va_list")
51 print(prname
+ " <ROOT> [VCC_PATH]")
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"
64 args
.extend(options
.split())
65 args
.extend(['-DCONFIG_VERIFY_VCC=1', srcfname
])
67 # Change working directory
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('#')):
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
)
102 def vcc(vcc_path
, root
, job
):
103 "Run Vcc on a 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?")
114 inf
= open(inname
, "r")
115 records
= inf
.read().splitlines()
118 for record
in records
:
119 arg
= jobfile
.parse_arg(record
)
124 print("Not enough jobfile record arguments")
134 srcfqname
= os
.path
.join(base
, srcfname
)
135 if (not os
.path
.isfile(srcfqname
)):
136 print("Source %s not found" % srcfqname
)
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
151 if (not preprocess(srcfname
, tmpfname
, base
, options
)):
155 print(" -- %s --" % srcfname
)
156 retval
= subprocess
.Popen([vcc_path
, '/pointersize:32', '/newsyntax', cygpath(tmpfqname
)]).wait()
161 # Cleanup, but only if verification was successful
162 # (to be able to examine the preprocessed file)
164 if (os
.path
.isfile(tmpfqname
)):
173 if (len(sys
.argv
) < 2):
177 rootdir
= os
.path
.abspath(sys
.argv
[1])
178 if (len(sys
.argv
) > 2):
179 vcc_path
= sys
.argv
[2]
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.")
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.")
195 specpath
= os
.path
.join(rootdir
, "tools/checkers/vcc.h")
196 if (not os
.path
.isfile(specpath
)):
197 print("%s not found." % config
)
200 specfile
= file(specpath
, "r")
201 specification
= specfile
.read()
205 if (not vcc(vcc_path
, rootdir
, job
)):
207 print("Failed job: %s" % job
)
211 print("All jobs passed")
213 if __name__
== '__main__':