source: mainline/tools/checkers/stanse/stanse.py@ 8786aa5

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

remove Stanse-specific constructs from makefiles
add generic support for checkers via generating an universal jobfiles (for kernel, boot loader, libraries and tasks)
add Stanse preprocessor which uses this universal jobfiles to run Stanse

  • Property mode set to 100755
File size: 4.1 KB
Line 
1#!/usr/bin/env python
2#
3# Copyright (c) 2010 Martin Decky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29"""
30Wrapper for Stanse static checker
31"""
32
33import sys
34import os
35import subprocess
36
37jobs = [
38 "kernel/kernel.job",
39 "uspace/srv/clip/clip.job"
40]
41
42def usage(prname):
43 "Print usage syntax"
44 print prname + " <ROOT>"
45
46def parse_arg(record):
47 "Parse jobfile line arguments"
48
49 arg = []
50 i = 0
51 current = ""
52 nil = True
53 inside = False
54
55 while (i < len(record)):
56 if (inside):
57 if (record[i] == "}"):
58 inside = False
59 else:
60 current = "%s%s" % (current, record[i])
61 else:
62 if (record[i] == "{"):
63 nil = False
64 inside = True
65 elif (record[i] == ","):
66 arg.append(current)
67 current = ""
68 nil = True
69 else:
70 print "Unexpected '%s'" % record[i]
71 return False
72
73 i += 1
74
75 if (not nil):
76 arg.append(current)
77
78 return arg
79
80def stanse(root, job):
81 "Run Stanse on a jobfile"
82
83 # Convert generic jobfile to Stanse-specific jobfile format
84
85 inname = os.path.join(root, job)
86 outname = os.path.join(root, "_%s" % os.path.basename(job))
87
88 if (not os.path.isfile(inname)):
89 print "Unable to open %s" % inname
90 print "Did you run \"make precheck\" on the source tree?"
91 return False
92
93 inf = file(inname, "r")
94 records = inf.read().splitlines()
95 inf.close()
96
97 output = []
98 for record in records:
99 arg = parse_arg(record)
100 if (not arg):
101 return False
102
103 if (len(arg) < 6):
104 print "Not enought jobfile record arguments"
105 return False
106
107 srcfname = arg[0]
108 tgtfname = arg[1]
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 # Only C files are interesting for us
118 if (arg[2] != "cc"):
119 continue
120
121 output.append([srcfname, tgtfname, base, options])
122
123 outf = file(outname, "w")
124 for record in output:
125 outf.write("{%s},{%s},{%s},{%s}\n" % (record[0], record[1], record[2], record[3]))
126 outf.close()
127
128 # Run Stanse
129
130 retval = subprocess.Popen(['stanse', '--checker', 'ReachabilityChecker', '--jobfile', outname]).wait()
131
132 # Cleanup
133
134 os.remove(outname)
135 for record in output:
136 tmpfile = os.path.join(record[2], "%s.preproc" % record[1])
137 if (os.path.isfile(tmpfile)):
138 os.remove(tmpfile)
139
140 if (retval == 0):
141 return True
142
143 return False
144
145def main():
146 if (len(sys.argv) < 2):
147 usage(sys.argv[0])
148 return
149
150 rootdir = os.path.abspath(sys.argv[1])
151 config = os.path.join(rootdir, "HelenOS.config")
152
153 if (not os.path.isfile(config)):
154 print "%s not found." % config
155 print "Please specify the path to HelenOS build tree root as the first argument."
156 return
157
158 for job in jobs:
159 if (not stanse(rootdir, job)):
160 print
161 print "Failed job: %s" % job
162 return
163
164 print
165 print "All jobs passed"
166
167if __name__ == '__main__':
168 main()
Note: See TracBrowser for help on using the repository browser.