+if sys.platform in ('win32', 'cygwin'):
+
+ def whereis(file):
+ pathext = [''] + os.environ['PATHEXT'].split(os.pathsep)
+ for dir in os.environ['PATH'].split(os.pathsep):
+ f = os.path.join(dir, file)
+ for ext in pathext:
+ fext = f + ext
+ if os.path.isfile(fext):
+ return fext
+ return None
+
+else:
+
+ def whereis(file):
+ for dir in os.environ['PATH'].split(os.pathsep):
+ f = os.path.join(dir, file)
+ if os.path.isfile(f):
+ try:
+ st = os.stat(f)
+ except OSError:
+ continue
+ if stat.S_IMODE(st[stat.ST_MODE]) & 0111:
+ return f
+ return None
+
+# See if --qmtest or --noqmtest specified
+try:
+ qmtest
+except NameError:
+ qmtest = None
+ # Old code for using QMTest by default if it's installed.
+ # We now default to not using QMTest unless explicitly asked for.
+ #for q in ['qmtest', 'qmtest.py']:
+ # path = whereis(q)
+ # if path:
+ # # The name was found on $PATH; just execute the found name so
+ # # we don't have to worry about paths containing white space.
+ # qmtest = q
+ # break
+ #if not qmtest:
+ # msg = ('Warning: found neither qmtest nor qmtest.py on $PATH;\n' +
+ # '\tassuming --noqmtest option.\n')
+ # sys.stderr.write(msg)
+ # sys.stderr.flush()
+
+aegis = whereis('aegis')
+
+if format == '--aegis' and aegis:
+ change = os.popen("aesub '$c' 2>/dev/null", "r").read()
+ if change:
+ if sp is None:
+ paths = os.popen("aesub '$sp' 2>/dev/null", "r").read()[:-1]
+ sp = paths.split(os.pathsep)
+ if spe is None:
+ spe = os.popen("aesub '$spe' 2>/dev/null", "r").read()[:-1]
+ spe = spe.split(os.pathsep)
+ else:
+ aegis = None
+
+if sp is None:
+ sp = []
+if spe is None:
+ spe = []
+
+sp.append(builddir)
+sp.append(cwd)
+
+#
+_ws = re.compile('\s')
+
+def escape(s):
+ if _ws.search(s):
+ s = '"' + s + '"'
+ s = s.replace('\\', '\\\\')
+ return s
+
+# Set up lowest-common-denominator spawning of a process on both Windows
+# and non-Windows systems that works all the way back to Python 1.5.2.
+try:
+ os.spawnv
+except AttributeError:
+ def spawn_it(command_args):
+ pid = os.fork()
+ if pid == 0:
+ os.execv(command_args[0], command_args)
+ else:
+ pid, status = os.waitpid(pid, 0)
+ return status >> 8
+else:
+ def spawn_it(command_args):
+ command = command_args[0]
+ command_args = list(map(escape, command_args))
+ return os.spawnv(os.P_WAIT, command, command_args)
+
+class Base:
+ def __init__(self, path, spe=None):
+ self.path = path
+ self.abspath = os.path.abspath(path)
+ if spe:
+ for dir in spe:
+ f = os.path.join(dir, path)
+ if os.path.isfile(f):
+ self.abspath = f
+ break
+ self.status = None
+
+class SystemExecutor(Base):
+ def execute(self):
+ s = spawn_it(self.command_args)
+ self.status = s
+ if s < 0 or s > 2:
+ sys.stdout.write("Unexpected exit status %d\n" % s)
+
+try:
+ import subprocess
+except ImportError:
+ import popen2
+ try:
+ popen2.Popen3
+ except AttributeError:
+ class PopenExecutor(Base):
+ def execute(self):
+ (tochild, fromchild, childerr) = os.popen3(self.command_str)
+ tochild.close()
+ self.stderr = childerr.read()
+ self.stdout = fromchild.read()
+ fromchild.close()
+ self.status = childerr.close()
+ if not self.status:
+ self.status = 0
+ else:
+ self.status = self.status >> 8
+ else:
+ class PopenExecutor(Base):
+ def execute(self):
+ p = popen2.Popen3(self.command_str, 1)
+ p.tochild.close()
+ self.stdout = p.fromchild.read()
+ self.stderr = p.childerr.read()
+ self.status = p.wait()
+ self.status = self.status >> 8
+else:
+ class PopenExecutor(Base):
+ def execute(self):
+ p = subprocess.Popen(self.command_str,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ shell=True)
+ self.stdout = p.stdout.read()
+ self.stderr = p.stderr.read()
+ self.status = p.wait()
+
+class Aegis(SystemExecutor):
+ def header(self, f):
+ f.write('test_result = [\n')
+ def write(self, f):
+ f.write(' { file_name = "%s";\n' % self.path)
+ f.write(' exit_status = %d; },\n' % self.status)
+ def footer(self, f):
+ f.write('];\n')
+
+class XML(PopenExecutor):
+ def header(self, f):
+ f.write(' <results>\n')
+ def write(self, f):
+ f.write(' <test>\n')
+ f.write(' <file_name>%s</file_name>\n' % self.path)
+ f.write(' <command_line>%s</command_line>\n' % self.command_str)
+ f.write(' <exit_status>%s</exit_status>\n' % self.status)
+ f.write(' <stdout>%s</stdout>\n' % self.stdout)
+ f.write(' <stderr>%s</stderr>\n' % self.stderr)
+ f.write(' <time>%.1f</time>\n' % self.test_time)
+ f.write(' </test>\n')
+ def footer(self, f):
+ f.write(' <time>%.1f</time>\n' % self.total_time)
+ f.write(' </results>\n')
+
+format_class = {
+ None : SystemExecutor,
+ '--aegis' : Aegis,
+ '--xml' : XML,
+}
+
+Test = format_class[format]