source: mainline/tools/checkers/vcc.py@ 28f4adb

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 28f4adb was 28f4adb, checked in by Martin Decky <martin@…>, 15 years ago

update scripts for compatibility with Python 3 (thx Vojtech Horky and Martin Sucha)

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