| 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 | """
 | 
|---|
| 30 | Wrapper for Stanse static checker
 | 
|---|
| 31 | """
 | 
|---|
| 32 | 
 | 
|---|
| 33 | import sys
 | 
|---|
| 34 | import os
 | 
|---|
| 35 | import subprocess
 | 
|---|
| 36 | import jobfile
 | 
|---|
| 37 | 
 | 
|---|
| 38 | jobs = [
 | 
|---|
| 39 |         "kernel/kernel.job",
 | 
|---|
| 40 |         "uspace/srv/clip/clip.job"
 | 
|---|
| 41 | ]
 | 
|---|
| 42 | 
 | 
|---|
| 43 | def usage(prname):
 | 
|---|
| 44 |         "Print usage syntax"
 | 
|---|
| 45 |         print(prname + " <ROOT>")
 | 
|---|
| 46 | 
 | 
|---|
| 47 | def stanse(root, job):
 | 
|---|
| 48 |         "Run Stanse on a jobfile"
 | 
|---|
| 49 | 
 | 
|---|
| 50 |         # Convert generic jobfile to Stanse-specific jobfile format
 | 
|---|
| 51 | 
 | 
|---|
| 52 |         inname = os.path.join(root, job)
 | 
|---|
| 53 |         outname = os.path.join(root, "_%s" % os.path.basename(job))
 | 
|---|
| 54 | 
 | 
|---|
| 55 |         if (not os.path.isfile(inname)):
 | 
|---|
| 56 |                 print("Unable to open %s" % inname)
 | 
|---|
| 57 |                 print("Did you run \"make precheck\" on the source tree?")
 | 
|---|
| 58 |                 return False
 | 
|---|
| 59 | 
 | 
|---|
| 60 |         inf = open(inname, "r")
 | 
|---|
| 61 |         records = inf.read().splitlines()
 | 
|---|
| 62 |         inf.close()
 | 
|---|
| 63 | 
 | 
|---|
| 64 |         output = []
 | 
|---|
| 65 |         for record in records:
 | 
|---|
| 66 |                 arg = jobfile.parse_arg(record)
 | 
|---|
| 67 |                 if (not arg):
 | 
|---|
| 68 |                         return False
 | 
|---|
| 69 | 
 | 
|---|
| 70 |                 if (len(arg) < 6):
 | 
|---|
| 71 |                         print("Not enough jobfile record arguments")
 | 
|---|
| 72 |                         return False
 | 
|---|
| 73 | 
 | 
|---|
| 74 |                 srcfname = arg[0]
 | 
|---|
| 75 |                 tgtfname = arg[1]
 | 
|---|
| 76 |                 tool = arg[2]
 | 
|---|
| 77 |                 category = arg[3]
 | 
|---|
| 78 |                 base = arg[4]
 | 
|---|
| 79 |                 options = arg[5]
 | 
|---|
| 80 | 
 | 
|---|
| 81 |                 srcfqname = os.path.join(base, srcfname)
 | 
|---|
| 82 |                 if (not os.path.isfile(srcfqname)):
 | 
|---|
| 83 |                         print("Source %s not found" % srcfqname)
 | 
|---|
| 84 |                         return False
 | 
|---|
| 85 | 
 | 
|---|
| 86 |                 # Only C files are interesting for us
 | 
|---|
| 87 |                 if (tool != "cc"):
 | 
|---|
| 88 |                         continue
 | 
|---|
| 89 | 
 | 
|---|
| 90 |                 output.append([srcfname, tgtfname, base, options])
 | 
|---|
| 91 | 
 | 
|---|
| 92 |         outf = open(outname, "w")
 | 
|---|
| 93 |         for record in output:
 | 
|---|
| 94 |                 outf.write("{%s},{%s},{%s},{%s}\n" % (record[0], record[1], record[2], record[3]))
 | 
|---|
| 95 |         outf.close()
 | 
|---|
| 96 | 
 | 
|---|
| 97 |         # Run Stanse
 | 
|---|
| 98 | 
 | 
|---|
| 99 |         retval = subprocess.Popen(['stanse', '--checker', 'ReachabilityChecker', '--jobfile', outname]).wait()
 | 
|---|
| 100 | 
 | 
|---|
| 101 |         # Cleanup
 | 
|---|
| 102 | 
 | 
|---|
| 103 |         os.remove(outname)
 | 
|---|
| 104 |         for record in output:
 | 
|---|
| 105 |                 tmpfile = os.path.join(record[2], "%s.preproc" % record[1])
 | 
|---|
| 106 |                 if (os.path.isfile(tmpfile)):
 | 
|---|
| 107 |                         os.remove(tmpfile)
 | 
|---|
| 108 | 
 | 
|---|
| 109 |         if (retval == 0):
 | 
|---|
| 110 |                 return True
 | 
|---|
| 111 | 
 | 
|---|
| 112 |         return False
 | 
|---|
| 113 | 
 | 
|---|
| 114 | def main():
 | 
|---|
| 115 |         if (len(sys.argv) < 2):
 | 
|---|
| 116 |                 usage(sys.argv[0])
 | 
|---|
| 117 |                 return
 | 
|---|
| 118 | 
 | 
|---|
| 119 |         rootdir = os.path.abspath(sys.argv[1])
 | 
|---|
| 120 |         config = os.path.join(rootdir, "HelenOS.config")
 | 
|---|
| 121 | 
 | 
|---|
| 122 |         if (not os.path.isfile(config)):
 | 
|---|
| 123 |                 print("%s not found." % config)
 | 
|---|
| 124 |                 print("Please specify the path to HelenOS build tree root as the first argument.")
 | 
|---|
| 125 |                 return
 | 
|---|
| 126 | 
 | 
|---|
| 127 |         for job in jobs:
 | 
|---|
| 128 |                 if (not stanse(rootdir, job)):
 | 
|---|
| 129 |                         print()
 | 
|---|
| 130 |                         print("Failed job: %s" % job)
 | 
|---|
| 131 |                         return
 | 
|---|
| 132 | 
 | 
|---|
| 133 |         print
 | 
|---|
| 134 |         print("All jobs passed")
 | 
|---|
| 135 | 
 | 
|---|
| 136 | if __name__ == '__main__':
 | 
|---|
| 137 |         main()
 | 
|---|