2006-08-02 13:59:57 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
#
|
|
|
|
# Scyther interface
|
|
|
|
#
|
|
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
""" Import externals """
|
|
|
|
import os
|
2006-08-07 11:42:34 +01:00
|
|
|
import os.path
|
2006-08-02 13:59:57 +01:00
|
|
|
import sys
|
|
|
|
import StringIO
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
""" Import scyther components """
|
|
|
|
import XMLReader
|
|
|
|
from Misc import *
|
|
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class Scyther(object):
|
|
|
|
def __init__ ( self):
|
2006-08-04 23:00:22 +01:00
|
|
|
|
|
|
|
# Where is my executable?
|
|
|
|
if sys.platform.startswith('win'):
|
|
|
|
""" Windows """
|
|
|
|
# TODO hardcoded for now, bad
|
2006-08-07 11:42:34 +01:00
|
|
|
self.program = os.path.join("bin","Scyther.exe")
|
2006-08-05 00:28:59 +01:00
|
|
|
if not os.path.isfile(self.program):
|
|
|
|
print "I can't find the Scyther executable at %s" % (self.program)
|
2006-08-04 23:00:22 +01:00
|
|
|
else:
|
|
|
|
""" Non-windows """
|
2006-08-07 11:42:34 +01:00
|
|
|
self.program = os.path.join("bin","scyther")
|
2006-08-04 23:00:22 +01:00
|
|
|
|
2006-08-07 11:42:34 +01:00
|
|
|
# defaults
|
2006-08-02 13:59:57 +01:00
|
|
|
self.options = ""
|
|
|
|
self.spdl = None
|
2006-08-02 14:44:45 +01:00
|
|
|
self.inputfile = None
|
2006-08-02 13:59:57 +01:00
|
|
|
self.claims = None
|
2006-08-06 20:52:07 +01:00
|
|
|
self.errors = None
|
2006-08-06 22:16:14 +01:00
|
|
|
self.errorcount = 0
|
2006-08-07 11:52:48 +01:00
|
|
|
self.run = False
|
2006-08-02 13:59:57 +01:00
|
|
|
|
|
|
|
def setInput(self,spdl):
|
|
|
|
self.spdl = spdl
|
2006-08-02 14:44:45 +01:00
|
|
|
self.inputfile = None
|
2006-08-02 13:59:57 +01:00
|
|
|
|
|
|
|
def setFile(self,filename):
|
2006-08-02 14:44:45 +01:00
|
|
|
self.inputfile = filename
|
2006-08-02 13:59:57 +01:00
|
|
|
self.spdl = ""
|
|
|
|
fp = open(filename,"r")
|
|
|
|
for l in fp.readlines():
|
|
|
|
self.spdl += l
|
|
|
|
fp.close()
|
|
|
|
|
2006-08-07 19:23:30 +01:00
|
|
|
def addFile(self,filename):
|
|
|
|
self.inputfile = None
|
|
|
|
if not self.spdl:
|
|
|
|
self.spdl = ""
|
|
|
|
fp = open(filename,"r")
|
|
|
|
for l in fp.readlines():
|
|
|
|
self.spdl += l
|
|
|
|
fp.close()
|
|
|
|
|
2006-08-02 13:59:57 +01:00
|
|
|
def verify(self):
|
|
|
|
|
2006-08-02 14:10:38 +01:00
|
|
|
# Run Scyther on temp file
|
|
|
|
self.cmd = "%s --dot-output --xml-output --plain %s" % (self.program,self.options)
|
|
|
|
|
2006-08-06 20:52:07 +01:00
|
|
|
(stdin,stdout,stderr) = os.popen3(self.cmd)
|
2006-08-02 14:10:38 +01:00
|
|
|
if self.spdl:
|
2006-08-06 20:52:07 +01:00
|
|
|
stdin.write(self.spdl)
|
|
|
|
stdin.close()
|
|
|
|
|
|
|
|
# In the order below, or stuff breaks (hangs), as described at
|
|
|
|
# http://mail.python.org/pipermail/python-dev/2000-September/009460.html
|
|
|
|
#
|
|
|
|
# TODO this is annoying: we would like to determine progress
|
|
|
|
# from the error output (maybe this can also be done by flushing
|
|
|
|
# the XML at certain points...)
|
|
|
|
xmlinput = stdout.read()
|
2006-08-07 12:02:14 +01:00
|
|
|
errlines = stderr.readlines()
|
2006-08-06 22:16:14 +01:00
|
|
|
|
|
|
|
# filter out any non-errors (say maybe only claim etc) and count
|
|
|
|
# them.
|
2006-08-07 12:02:14 +01:00
|
|
|
self.errors = []
|
|
|
|
for l in errlines:
|
|
|
|
if not l.startswith("claim\t"):
|
|
|
|
self.errors.append(l.strip())
|
|
|
|
|
2006-08-06 22:16:14 +01:00
|
|
|
self.errorcount = len(self.errors)
|
2006-08-06 20:52:07 +01:00
|
|
|
|
|
|
|
# close
|
|
|
|
stdout.close()
|
|
|
|
stderr.close()
|
|
|
|
|
2006-08-06 20:57:01 +01:00
|
|
|
if len(xmlinput) > 0:
|
|
|
|
xmlfile = StringIO.StringIO(xmlinput)
|
|
|
|
reader = XMLReader.XMLReader()
|
|
|
|
self.claims = reader.readXML(xmlfile)
|
|
|
|
else:
|
|
|
|
# no output...
|
|
|
|
self.claims = []
|
2006-08-02 13:59:57 +01:00
|
|
|
|
2006-08-07 11:52:48 +01:00
|
|
|
self.run = True
|
2006-08-02 14:10:38 +01:00
|
|
|
return self.claims
|
2006-08-02 13:59:57 +01:00
|
|
|
|
2006-08-07 19:23:30 +01:00
|
|
|
def getClaim(self,claimid):
|
|
|
|
if self.claims:
|
|
|
|
for cl in self.claims:
|
|
|
|
if cl.id == claimid:
|
|
|
|
return cl
|
|
|
|
return None
|
|
|
|
|
2006-08-02 13:59:57 +01:00
|
|
|
def __str__(self):
|
2006-08-07 11:52:48 +01:00
|
|
|
if self.run:
|
|
|
|
if self.errorcount > 0:
|
2006-08-07 17:40:46 +01:00
|
|
|
return "%i errors:\n%s" % (self.errorcount, "\n".join(self.errors))
|
2006-08-07 11:52:48 +01:00
|
|
|
else:
|
|
|
|
s = "Claim results:\n"
|
|
|
|
for cl in self.claims:
|
|
|
|
s += str(cl) + "\n"
|
|
|
|
return s
|
2006-08-02 13:59:57 +01:00
|
|
|
else:
|
|
|
|
return "Scyther has not been run yet."
|
|
|
|
|
|
|
|
|
2006-08-02 14:44:45 +01:00
|
|
|
def basicTest():
|
2006-08-02 13:59:57 +01:00
|
|
|
# Some basic testing
|
2006-08-02 14:44:45 +01:00
|
|
|
#if sys.platform.startswith('win'):
|
|
|
|
# print "Dir test"
|
|
|
|
# p = os.popen("dir")
|
|
|
|
# print p.read()
|
|
|
|
# print p.close()
|
|
|
|
# confirm("See the dir?")
|
2006-08-07 11:52:48 +01:00
|
|
|
#
|
|
|
|
print "I don't know what to test now."
|
2006-08-02 13:59:57 +01:00
|
|
|
|
2006-08-02 14:44:45 +01:00
|
|
|
|
|
|
|
def simpleRun(args):
|
|
|
|
x = Scyther()
|
|
|
|
x.options = args
|
|
|
|
x.verify()
|
|
|
|
return x
|
2006-08-02 13:59:57 +01:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2006-08-02 14:10:38 +01:00
|
|
|
pars = sys.argv[1:]
|
|
|
|
if len(pars) == 0:
|
2006-08-02 14:44:45 +01:00
|
|
|
basicTest()
|
2006-08-02 14:10:38 +01:00
|
|
|
else:
|
2006-08-02 14:44:45 +01:00
|
|
|
print simpleRun(" ".join(pars))
|
2006-08-02 13:59:57 +01:00
|
|
|
|
|
|
|
|