Misc cleanups and fixes.
http://reviews.llvm.org/D7073
Files:
test/libcxx/compiler.py
test/libcxx/double_include.sh.cpp
test/libcxx/test/config.py
test/libcxx/test/format.py
test/libcxx/util.py
test/lit.cfg
utils/not/not.py
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: test/libcxx/compiler.py
===================================================================
--- test/libcxx/compiler.py
+++ test/libcxx/compiler.py
@@ -1,9 +1,10 @@
import lit.util
-
+import libcxx.util
class CXXCompiler(object):
- def __init__(self, path, flags=[], compile_flags=[], link_flags=[], use_ccache=False):
+ def __init__(self, path, flags=[], compile_flags=[], link_flags=[],
+ use_ccache=False):
self.path = path
self.flags = list(flags)
self.compile_flags = list(compile_flags)
@@ -91,6 +92,29 @@
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
return cmd, out, err, rc
+ def _compileLinkTwoSteps(self, infile, object_file, out=None, flags=[],
+ env=None, cwd=None):
+ cmd, output, err, rc = self.compile(infile, object_file,
+ flags=flags, env=env, cwd=cwd)
+ if rc != 0:
+ return cmd, output, err, rc
+ return self.link(object_file, out=out, flags=flags, env=env,
+ cwd=cwd)
+
+ def compileLinkTwoSteps(self, infile, out=None, object_file=None, flags=[],
+ env=None, cwd=None):
+ if not isinstance(infile, str):
+ raise TypeError('This function only accepts a single input file')
+ # Create, use and delete a temporary object file if none is given.
+ if object_file is None:
+ with libcxx.util.guardedTemporaryFile(suffix='.o') as object_file:
+ return self._compileLinkTwoSteps(infile, object_file, out,
+ flags, env, cwd)
+ # Othewise compile using the given object file.
+ else:
+ return self._compileLinkTwoSteps(infile, object_file, out, flags,
+ env, cwd)
+
def dumpMacros(self, infiles=None, flags=[], env=None, cwd=None):
if infiles is None:
infiles = '/dev/null'
Index: test/libcxx/double_include.sh.cpp
===================================================================
--- /dev/null
+++ test/libcxx/double_include.sh.cpp
@@ -0,0 +1,108 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that we can include each header in two TU's and link them together.
+
+// RUN: %cxx -c %s -o %t.first.o %flags %compile_flags
+// RUN: %cxx -c %s -o %t.second.o -DWITH_MAIN %flags %compile_flags
+// RUN: %cxx -o %t.exe %t.first.o %t.second.o %flags %link_flags
+// RUN: %run
+
+#include <algorithm>
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <cassert>
+#include <ccomplex>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <chrono>
+#include <cinttypes>
+#include <ciso646>
+#include <climits>
+#include <clocale>
+#include <cmath>
+#include <codecvt>
+#include <complex>
+#include <complex.h>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstdbool>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctgmath>
+#include <ctime>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <exception>
+#include <experimental/dynarray>
+#include <experimental/optional>
+#include <experimental/string_view>
+#include <experimental/type_traits>
+#include <experimental/utility>
+#include <ext/hash_map>
+#include <ext/hash_set>
+#include <forward_list>
+#include <fstream>
+#include <functional>
+#include <future>
+#include <initializer_list>
+#include <iomanip>
+#include <ios>
+#include <iosfwd>
+#include <iostream>
+#include <istream>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <locale>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <new>
+#include <numeric>
+#include <ostream>
+#include <queue>
+#include <random>
+#include <ratio>
+#include <regex>
+#include <scoped_allocator>
+#include <set>
+#include <shared_mutex>
+#include <sstream>
+#include <stack>
+#include <stdexcept>
+#include <streambuf>
+#include <string>
+#include <strstream>
+#include <system_error>
+#include <tgmath.h>
+#include <thread>
+#include <tuple>
+#include <typeindex>
+#include <typeinfo>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <vector>
+
+#if defined(WITH_MAIN)
+int main() {}
+#endif
Index: test/libcxx/test/config.py
===================================================================
--- test/libcxx/test/config.py
+++ test/libcxx/test/config.py
@@ -12,6 +12,34 @@
from libcxx.compiler import CXXCompiler
+def loadSiteConfig(lit_config, config, param_name, env_name):
+ # We haven't loaded the site specific configuration (the user is
+ # probably trying to run on a test file directly, and either the site
+ # configuration hasn't been created by the build system, or we are in an
+ # out-of-tree build situation).
+ site_cfg = lit_config.params.get(param_name,
+ os.environ.get(env_name))
+ if not site_cfg:
+ lit_config.warning('No site specific configuration file found!'
+ ' Running the tests in the default configuration.')
+ # TODO: Set test_exec_root to a temporary directory where output files
+ # can be placed. This is needed for ShTest.
+ elif not os.path.isfile(site_cfg):
+ lit_config.fatal(
+ "Specified site configuration file does not exist: '%s'" %
+ site_cfg)
+ else:
+ lit_config.note('using site specific configuration at %s' % site_cfg)
+ ld_fn = lit_config.load_config
+ # Null out the load_config function so that lit.site.cfg doesn't
+ # recursively load a config even if it tries.
+ # TODO: This is one hell of a hack. Fix it.
+ def prevent_reload_fn(*args, **kwargs):
+ pass
+ lit_config.load_config = prevent_reload_fn
+ ld_fn(config, site_cfg)
+ lit_config.load_config = ld_fn
+
class Configuration(object):
# pylint: disable=redefined-outer-name
def __init__(self, lit_config, config):
@@ -61,6 +89,7 @@
self.configure_compile_flags()
self.configure_link_flags()
self.configure_sanitizer()
+ self.configure_substitutions()
self.configure_features()
def print_config_info(self):
@@ -441,6 +470,45 @@
self.lit_config.fatal('unsupported value for '
'use_sanitizer: {0}'.format(san))
+ def configure_substitutions(self):
+ sub = self.config.substitutions
+ # Configure compiler substitions
+ sub.append( ('%cxx', self.cxx.path) )
+ # Configure flags substitutions
+ flags_str = ' '.join(self.cxx.flags)
+ compile_flags_str = ' '.join(self.cxx.compile_flags)
+ link_flags_str = ' '.join(self.cxx.link_flags)
+ all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
+ sub.append( ('%flags' , flags_str ) )
+ sub.append( ('%compile_flags', compile_flags_str) )
+ sub.append( ('%link_flags' , link_flags_str ) )
+ sub.append( ('%all_flags' , all_flags ) )
+ # Add compile and link shortcuts
+ compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
+ + compile_flags_str)
+ link_str = (self.cxx.path + ' -o %t.exe %t.o ' + flags_str
+ + link_flags_str)
+ assert type(link_str) is str
+ build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
+ sub.append( ('%compile', compile_str) )
+ sub.append( ('%link' , link_str ) )
+ sub.append( ('%build' , build_str ) )
+ # Configure exec prefix substitutions.
+ exec_env_str = 'env ' if len(self.env) != 0 else ''
+ for k,v in self.env.items():
+ exec_env_str += ' %s=%s' % (k, v)
+ # Configure run env substitution.
+ exec_str = ''
+ if self.lit_config.useValgrind:
+ exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
+ sub.append( ('%exec', exec_str) )
+ # Configure run shortcut
+ sub.append( ('%run', exec_str + ' %t.exe') )
+ # Configure not program substitions
+ python_exe = sys.executable
+ not_py = os.path.join(self.libcxx_src_root, 'utils', 'not', 'not.py')
+ sub.append( ('not', python_exe + ' ' + not_py) )
+
def configure_triple(self):
# Get or infer the target triple.
self.config.target_triple = self.get_lit_conf('target_triple')
Index: test/libcxx/test/format.py
===================================================================
--- test/libcxx/test/format.py
+++ test/libcxx/test/format.py
@@ -1,12 +1,14 @@
import errno
import os
-import tempfile
import time
-import lit.formats # pylint: disable=import-error
+import lit.Test # pylint: disable=import-error
+import lit.TestRunner # pylint: disable=import-error
+import lit.util # pylint: disable=import-error
+import libcxx.util
-class LibcxxTestFormat(lit.formats.FileBasedTest):
+class LibcxxTestFormat(object):
"""
Custom test format handler for use with the test format use by libc++.
@@ -21,6 +23,21 @@
self.use_verify_for_fail = use_verify_for_fail
self.exec_env = dict(exec_env)
+ def getTestsInDirectory(self, testSuite, path_in_suite,
+ litConfig, localConfig):
+ source_path = testSuite.getSourcePath(path_in_suite)
+ for filename in os.listdir(source_path):
+ # Ignore dot files and excluded tests.
+ if (filename.startswith('.') or
+ filename in localConfig.excludes):
+ continue
+
+ filepath = os.path.join(source_path, filename)
+ if not os.path.isdir(filepath):
+ if any([filename.endswith(ext) for ext in localConfig.suffixes]):
+ yield lit.Test.Test(testSuite, path_in_suite + (filename,),
+ localConfig)
+
def execute(self, test, lit_config):
while True:
try:
@@ -31,95 +48,33 @@
time.sleep(0.1)
def _execute(self, test, lit_config):
- # Extract test metadata from the test file.
- requires = []
- unsupported = []
- use_verify = False
- with open(test.getSourcePath()) as f:
- for ln in f:
- if 'XFAIL:' in ln:
- items = ln[ln.index('XFAIL:') + 6:].split(',')
- test.xfails.extend([s.strip() for s in items])
- elif 'REQUIRES:' in ln:
- items = ln[ln.index('REQUIRES:') + 9:].split(',')
- requires.extend([s.strip() for s in items])
- elif 'UNSUPPORTED:' in ln:
- items = ln[ln.index('UNSUPPORTED:') + 12:].split(',')
- unsupported.extend([s.strip() for s in items])
- elif 'USE_VERIFY' in ln and self.use_verify_for_fail:
- use_verify = True
- elif not ln.strip().startswith("//") and ln.strip():
- # Stop at the first non-empty line that is not a C++
- # comment.
- break
-
- # Check that we have the required features.
- #
- # FIXME: For now, this is cribbed from lit.TestRunner, to avoid
- # introducing a dependency there. What we more ideally would like to do
- # is lift the "requires" handling to be a core lit framework feature.
- missing_required_features = [
- f for f in requires
- if f not in test.config.available_features
- ]
- if missing_required_features:
- return (lit.Test.UNSUPPORTED,
- "Test requires the following features: %s" % (
- ', '.join(missing_required_features),))
-
- unsupported_features = [f for f in unsupported
- if f in test.config.available_features]
- if unsupported_features:
- return (lit.Test.UNSUPPORTED,
- "Test is unsupported with the following features: %s" % (
- ', '.join(unsupported_features),))
-
- # Evaluate the test.
- return self._evaluate_test(test, use_verify, lit_config)
-
- def _make_report(self, cmd, out, err, rc): # pylint: disable=no-self-use
- report = "Command: %s\n" % cmd
- report += "Exit Code: %d\n" % rc
- if out:
- report += "Standard Output:\n--\n%s--\n" % out
- if err:
- report += "Standard Error:\n--\n%s--\n" % err
- report += '\n'
- return cmd, report, rc
-
- def _compile(self, output_path, source_path, use_verify=False):
- extra_flags = []
- if use_verify:
- extra_flags += ['-Xclang', '-verify']
- return self.cxx.compile(source_path, out=output_path, flags=extra_flags)
-
- def _link(self, exec_path, object_path):
- return self.cxx.link(object_path, out=exec_path)
-
- def _compile_and_link(self, exec_path, source_path):
- object_file = tempfile.NamedTemporaryFile(suffix=".o", delete=False)
- object_path = object_file.name
- object_file.close()
- try:
- cmd, out, err, rc = self.cxx.compile(source_path, out=object_path)
- if rc != 0:
- return cmd, out, err, rc
- return self.cxx.link(object_path, out=exec_path)
- finally:
- try:
- os.remove(object_path)
- except OSError:
- pass
-
- def _build(self, exec_path, source_path, compile_only=False,
- use_verify=False):
- if compile_only:
- cmd, out, err, rc = self._compile(exec_path, source_path,
- use_verify)
+ name = test.path_in_suite[-1]
+ is_sh_test = name.endswith('.sh.cpp')
+ is_pass_test = name.endswith('.pass.cpp')
+ is_fail_test = name.endswith('.fail.cpp')
+
+ res = lit.TestRunner.parseIntegratedTestScript(test,
+ require_script=is_sh_test)
+ if isinstance(res, lit.Test.Result):
+ return res
+ if lit_config.noExecute:
+ return lit.Test.Result(lit.Test.PASS)
+
+ script, tmpBase, execDir = res
+ # Check that we don't have run lines on tests that don't support them.
+ if not is_sh_test and len(script) != 0:
+ lit_config.fatal('Unsupported RUN line found in test %s' % name)
+ # Dispatch the test based on its suffix.
+ if is_sh_test:
+ return lit.TestRunner._runShTest(test, lit_config, False, script,
+ tmpBase, execDir)
+ elif is_fail_test:
+ return self._evaluate_fail_test(test, tmpBase, execDir, lit_config)
+ elif is_pass_test:
+ return self._evaluate_pass_test(test, tmpBase, execDir, lit_config)
else:
- assert not use_verify
- cmd, out, err, rc = self._compile_and_link(exec_path, source_path)
- return self._make_report(cmd, out, err, rc)
+ # No other test type is supported
+ assert False
def _clean(self, exec_path): # pylint: disable=no-self-use
try:
@@ -127,58 +82,58 @@
except OSError:
pass
- def _run(self, exec_path, lit_config, in_dir=None):
- cmd = []
- if self.exec_env:
- cmd.append('env')
- cmd.extend('%s=%s' % (name, value)
- for name, value in self.exec_env.items())
- cmd.append(exec_path)
- if lit_config.useValgrind:
- cmd = lit_config.valgrindArgs + cmd
- out, err, rc = lit.util.executeCommand(cmd, cwd=in_dir)
- return self._make_report(cmd, out, err, rc)
-
- def _evaluate_test(self, test, use_verify, lit_config):
- name = test.path_in_suite[-1]
+ def _evaluate_pass_test(self, test, tmpBase, execDir, lit_config):
source_path = test.getSourcePath()
- source_dir = os.path.dirname(source_path)
+ exec_path = tmpBase + '.exe'
+ object_path = tmpBase + '.o'
+ # Create the output directory if it does not already exist.
+ lit.util.mkdir_p(os.path.dirname(tmpBase))
+ try:
+ # Compile the test
+ cmd, out, err, rc = self.cxx.compileLinkTwoSteps(
+ source_path, out=exec_path, object_file=object_path)
+ compile_cmd = cmd
+ if rc != 0:
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ report += "Compilation failed unexpectedly!"
+ return lit.Test.FAIL, report
+ # Run the test
+ cmd = []
+ if self.exec_env:
+ cmd.append('env')
+ cmd.append('%s=%s' % (k,v) for k,v in self.exec_env.items())
+ if lit_config.useValgrind:
+ cmd = lit_config.valgrindArgs + cmd
+ cmd.append(exec_path)
+ out, err, rc = lit.util.executeCommand(cmd,
+ cwd=os.path.dirname(source_path))
+ if rc != 0:
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ report = "Compiled With: %s\n%s" % (compile_cmd, report)
+ report += "Compiled test failed unexpectedly!"
+ return lit.Test.FAIL, report
+ return lit.Test.PASS, ''
+ finally:
+ # Note that cleanup of exec_file happens in `_clean()`. If you
+ # override this, cleanup is your reponsibility.
+ self._clean(object_path)
+ self._clean(exec_path)
- # Check what kind of test this is.
- assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
- expected_compile_fail = name.endswith('.fail.cpp')
- # If this is a compile (failure) test, build it and check for failure.
- if expected_compile_fail:
- cmd, report, rc = self._build('/dev/null', source_path,
- compile_only=True,
- use_verify=use_verify)
- expected_rc = 0 if use_verify else 1
- if rc == expected_rc:
- return lit.Test.PASS, ""
- else:
- return (lit.Test.FAIL,
- report + 'Expected compilation to fail!\n')
+ def _evaluate_fail_test(self, test, tmpBase, execDir, lit_config):
+ source_path = test.getSourcePath()
+ with open(source_path, 'r') as f:
+ contents = f.read()
+ use_verify = 'USE_VERIFY' in contents and self.use_verify_for_fail
+ extra_flags = []
+ if use_verify:
+ extra_flags += ['-Xclang', '-verify']
+ cmd, out, err, rc = self.cxx.compile(source_path, out='/dev/null',
+ flags=extra_flags)
+ expected_rc = 0 if use_verify else 1
+ if rc == expected_rc:
+ return lit.Test.PASS, ""
else:
- exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
- exec_path = exec_file.name
- exec_file.close()
-
- try:
- cmd, report, rc = self._build(exec_path, source_path)
- compile_cmd = cmd
- if rc != 0:
- report += "Compilation failed unexpectedly!"
- return lit.Test.FAIL, report
-
- cmd, report, rc = self._run(exec_path, lit_config,
- source_dir)
- if rc != 0:
- report = "Compiled With: %s\n%s" % (compile_cmd, report)
- report += "Compiled test failed unexpectedly!"
- return lit.Test.FAIL, report
- finally:
- # Note that cleanup of exec_file happens in `_clean()`. If you
- # override this, cleanup is your reponsibility.
- self._clean(exec_path)
- return lit.Test.PASS, ""
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ return (lit.Test.FAIL,
+ report + 'Expected compilation to fail!\n')
Index: test/libcxx/util.py
===================================================================
--- /dev/null
+++ test/libcxx/util.py
@@ -0,0 +1,25 @@
+from contextlib import contextmanager
+import os
+import tempfile
+
+import lit.util # pylint: disable=import-error
+
+@contextmanager
+def guardedTemporaryFile(suffix='', prefix='', dir=None):
+ handle, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
+ os.close(handle)
+ yield name
+ try:
+ os.remove(name)
+ except OSError:
+ pass
+
+def makeReport(cmd, out, err, rc):
+ report = "Command: %s\n" % cmd
+ report += "Exit Code: %d\n" % rc
+ if out:
+ report += "Standard Output:\n--\n%s--\n" % out
+ if err:
+ report += "Standard Error:\n--\n%s--\n" % err
+ report += '\n'
+ return report
Index: test/lit.cfg
===================================================================
--- test/lit.cfg
+++ test/lit.cfg
@@ -15,37 +15,27 @@
config.name = 'libc++'
# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.cpp']
+config.suffixes = ['.pass.cpp', '.fail.cpp', '.sh.cpp']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
# Infer the test_exec_root from the libcxx_object root.
-libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
-if libcxx_obj_root is not None:
- config.test_exec_root = os.path.join(libcxx_obj_root, 'test')
+obj_root = getattr(config, 'libcxx_obj_root', None)
# Check that the test exec root is known.
-if config.test_exec_root is None:
- # Otherwise, we haven't loaded the site specific configuration (the user is
- # probably trying to run on a test file directly, and either the site
- # configuration hasn't been created by the build system, or we are in an
- # out-of-tree build situation).
- site_cfg = lit_config.params.get('libcxx_site_config',
- os.environ.get('LIBCXX_SITE_CONFIG'))
- if not site_cfg:
- lit_config.warning('No site specific configuration file found!'
- ' Running the tests in the default configuration.')
- # TODO: Set test_exec_root to a temporary directory where output files
- # can be placed. This is needed for ShTest.
- elif not os.path.isfile(site_cfg):
- lit_config.fatal(
- "Specified site configuration file does not exist: '%s'" %
- site_cfg)
- else:
- lit_config.note('using site specific configuration at %s' % site_cfg)
- lit_config.load_config(config, site_cfg)
- raise SystemExit()
+if obj_root is None:
+ import libcxx.test.config
+ libcxx.test.config.loadSiteConfig(lit_config, config, 'libcxx_site_config',
+ 'LIBCXX_SITE_CONFIG')
+ obj_root = getattr(config, 'libcxx_obj_root', None)
+ if obj_root is None:
+ import tempfile
+ obj_root = tempfile.mkdtemp(prefix='libcxx-testsuite-')
+ lit_config.warning('Creating temporary directory for object root: %s' %
+ obj_root)
+
+config.test_exec_root = os.path.join(obj_root, 'test')
cfg_variant = getattr(config, 'configuration_variant', 'libcxx')
if cfg_variant:
Index: utils/not/not.py
===================================================================
--- /dev/null
+++ utils/not/not.py
@@ -0,0 +1,86 @@
+import os
+import platform
+import signal
+import subprocess
+import sys
+
+# not.py is a utility for inverting the return code of commands. It acts similar
+# to llvm/utils/not.
+# ex: python /path/to/not.py echo hello
+# echo $? // (prints 1)
+
+
+# NOTE: this is stolen from llvm/utils/lit/lit/util.py because python probably
+# won't be able to find the lit import.
+def which(command, paths = None):
+ """which(command, [paths]) - Look up the given command in the paths string
+ (or the PATH environment variable, if unspecified)."""
+
+ if paths is None:
+ paths = os.environ.get('PATH','')
+
+ # Check for absolute match first.
+ if os.path.isfile(command):
+ return command
+
+ # Would be nice if Python had a lib function for this.
+ if not paths:
+ paths = os.defpath
+
+ # Get suffixes to search.
+ # On Cygwin, 'PATHEXT' may exist but it should not be used.
+ if os.pathsep == ';':
+ pathext = os.environ.get('PATHEXT', '').split(';')
+ else:
+ pathext = ['']
+
+ # Search the paths...
+ for path in paths.split(os.pathsep):
+ for ext in pathext:
+ p = os.path.join(path, command + ext)
+ if os.path.exists(p):
+ return p
+
+ return None
+
+# Close extra file handles on UNIX (on Windows this cannot be done while
+# also redirecting input).
+kUseCloseFDs = not (platform.system() == 'Windows')
+def executeCommand(command, cwd=None, env=None):
+ p = subprocess.Popen(command, cwd=cwd,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=env, close_fds=kUseCloseFDs)
+ out,err = p.communicate()
+ exitCode = p.wait()
+
+ # Detect Ctrl-C in subprocess.
+ if exitCode == -signal.SIGINT:
+ raise KeyboardInterrupt
+
+ return out, err, exitCode
+
+def main():
+ argv = sys.argv
+ del argv[0]
+ if len(argv) > 0 and argv[0] == '--crash':
+ del argv[0]
+ expectCrash = True
+ else:
+ expectCrash = False
+ if len(argv) == 0:
+ return 1
+ prog = which(argv[0])
+ if prog is None:
+ sys.stderr.write('Failed to find program %s' % argv[0])
+ return 1
+ out, err, rc = executeCommand(argv)
+ if rc == 0 and not expectCrash:
+ return 1
+ else:
+ return 0
+
+if __name__ == '__main__':
+ ret = main()
+ exit(ret)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits