#!/usr/bin/env python 

# Note that this script must be run with Python 2.3.

import sys
import os
import os.path
import shutil
import glob
import getpass
import time
from optparse import OptionParser

j = os.path.join

optparser = OptionParser("usage: %prog [options] <gcc-version> "
                         "<source-directory> <qmtc-directory> "
                         "<qmtest_gcc-directory>")
optparser.add_option("-v", "--version", action="store",
                     dest="pkg_version", default="1.0",
                     metavar="VERSION",
                     help="Package version (default 1.0)")
optparser.add_option("-o", "--output", action="store",
                     dest="targetdir", metavar="DIR",
                     help="Output directory "
                     "(default: qmtest_libstdcpp_GCCVER-PKGVER)")
optparser.add_option("-f", "--force", action="store_true",
                     dest="force", default=False,
                     help="If output directory already exists, delete it")
optparser.add_option("-a", "--add-results", action="append",
                     dest="baselines", default=[],
                     help="Additional result file to distribute (may be "
                     "used multiple times)")
optparser.add_option("-c", "--config-guess", action="store",
                     dest="config_guess", metavar="FILE",
                     help="Path to config.guess "
                     "(default: search in /usr/share/)")


def ensure_dir(dir):
    # Assume we're given foo/bar/baz/quux, and foo/bar already exists.
    fragments = []
    while dir:
        if os.path.exists(dir):
            break
        dir, tail = os.path.split(dir)
        fragments.insert(0, tail)
    # Now dir == "foo/bar" and fragments == ["baz", "quux"]
    # Iterate through the fragments, building up dir and creating
    # directories.
    for frag in fragments:
        dir = j(dir, frag)
        os.mkdir(dir)
        

def add(source_file_or_dir, *target_path):
    dest = os.path.join(*target_path)
    ensure_dir(os.path.dirname(dest))
    if os.path.isfile(source_file_or_dir):
        shutil.copy(source_file_or_dir, dest)
    elif os.path.isdir(source_file_or_dir):
        shutil.copytree(source_file_or_dir, dest)
    else:
        assert 0, "add() must be given a file or directory"


def generate(source_string, substitutions, *target_path):
    dest = os.path.join(*target_path)
    ensure_dir(os.path.dirname(dest))
    f = open(dest, "w")
    f.write(source_string % substitutions)
    f.close()


class InstallRecorder(object):
    def __init__(self, file_to_record_in):
        ensure_dir(os.path.dirname(file_to_record_in))
        self._file = open(file_to_record_in, "w")
    def __call__(self, path):
        self._file.write("%s\n" % path)


def main(fullname, fullargs):

    name = os.path.basename(fullname)
    options, args = optparser.parse_args(fullargs)
    if len(args) != 4:
        optparser.error("Wrong number of arguments")

    gcc_version, srcdir, qmtcdir, qmtest_gccdir = args
    pkg_version = options.pkg_version
    targetdir = options.targetdir
    if targetdir is None:
        targetdir = "./qmtest_libstdcpp_%s-%s" % (gcc_version,
                                                  pkg_version)

    if os.path.exists(targetdir):
        if options.force:
            shutil.rmtree(targetdir)
        else:
            print "Error: Target directory '%s' already exists and " \
                  "deletion not requested" % targetdir
            sys.exit(2)

    if not gcc_version.startswith("3.3") and not gcc_version.startswith("3.4"):
        print "Error: Unsupported gcc version %s" % gcc_version
        sys.exit(2)

    v3src = j(srcdir, "libstdc++-v3")

    # Open a file to record which directories exist (and thus need
    # installing).
    install = InstallRecorder(j(targetdir, "share-contents"))

    # Put 'config.guess' in.
    if options.config_guess is None:
        config_guesses = glob.glob("/usr/share/*/config.guess")
        if not config_guesses:
            optparser.error("Cannot find config.guess, use "
                            "--config-guess") 
        config_guess = config_guesses[0]
    else:
        config_guess = options.config_guess
    add(config_guess, targetdir, "config.guess")

    # Mark that this will be a standalone installation, for later
    # detection by the QMTest harness.  We write the numeral '1' in case
    # we need versioning information later.
    generate("1\n", {}, targetdir, "THIS-IS-STANDALONE-V3")
    install("THIS-IS-STANDALONE-V3")

    # Copy gcc stuff over:
    add(j(v3src, "testsuite"), targetdir, "testsuite")
    install("testsuite")
    add(j(v3src, "po"), targetdir, "po")
    install("po")
    ensure_dir(j(targetdir, "config"))
    add(j(v3src, "config", "abi"), targetdir, "config", "abi")
    install("config")
    
    # gcc 3.4 has a scripts dir that we need.
    if os.path.exists(j(v3src, "scripts")):
        add(j(v3src, "scripts"), targetdir, "scripts")
        install("scripts")

    # Copy in QMTest extension classes.
    add(qmtcdir, targetdir, "qm-classes", "qmtc")
    add(qmtest_gccdir, targetdir, "qm-classes", "qmtest_gcc")
    install("qm-classes")
    # And then clean them up a bit (remove backup files, compiled files,
    # and CVS/ directories).
    for g in "*~", "*.pyc", "*.pyo":
        for file in glob.glob(j(targetdir, "qm-classes", "*", g)):
            os.unlink(file)
    for dir in glob.glob(j(targetdir, "qm-classes", "*", "CVS")):
        shutil.rmtree(dir)

    # Copy over any supplied baselines.
    ensure_dir(j(targetdir, "qm-baselines"))
    install("qm-baselines")
    for b in options.baselines:
        add(b, targetdir, "qm-baselines", os.path.basename(b))

    # Copy this script into the package.
    add(__file__, targetdir, "build_v3_dist")

    # Set up the substitutions dict used by all our templates.
    substitutions = {"prog_name": name,
                     "prog_fullname": fullname,
                     "gcc_version": gcc_version,
                     "pkg_version": pkg_version,
                     "prog_args": " ".join(fullargs),
                     "user": getpass.getuser(),
                     "time": time.strftime("%Y-%m-%d %H:%M:%S"),
                     }

    # Munge testsuite_hooks.h to make testsuite executables
    # relocatable.
    f = open(j(targetdir, "testsuite", "testsuite_hooks.h"), "a")
    f.write(testsuite_hooks_addendum % substitutions)
    f.close()
    
    # Now create the misc. files.
    miscdir = j(targetdir, "qm-misc")
    ensure_dir(miscdir)
    install("qm-misc")

    generate(locale_Makefile, substitutions, miscdir, "locale-Makefile")

    generate(util_Makefile, substitutions, miscdir, "util-Makefile")

    # And the distribution-level files.
    generate(README_file, substitutions, targetdir, "README")
    generate(PKGINFO_file, substitutions, targetdir, "PKGINFO")
    generate(spec_file, substitutions,
             targetdir, "qmtest_libstdcpp_%(gcc_version)s.spec"
                        % substitutions)
    generate(build_binary_testsuite_file, substitutions,
             targetdir, "build_binary_testsuite")
    os.chmod(j(targetdir, "build_binary_testsuite"), 0755)
    

## All the templates for generated files:

locale_Makefile = """\
# Do not edit -- this file automatically generated by %(prog_name)s.
# Makefile to build locale files needed by libstdc++-v3 testsuite.

root := @ROOT@

podir := $(root)/po

POS := $(wildcard $(podir)/*.po)
LANGS := $(basename $(notdir $(POS)))
MOS := $(addsuffix /LC_MESSAGES/libstdc++.mo,$(LANGS))
DIRS := $(addsuffix /LC_MESSAGES,$(LANGS))

# Allow the user to set MSGFMT in their environment
MSGFMT ?= msgfmt

.PHONY: locales

locales: $(POS)
\tmkdir -p $(DIRS)
\tfor lang in $(LANGS); \\
\t    do $(MSGFMT) $(podir)/$$lang.po -o $$lang/LC_MESSAGES/libstdc++.mo; \\
\tdone

"""

util_Makefile = """\
# Do not edit -- this file automatically generated by %(prog_name)s.
# Makefile to build utility files needed by libstdc++-v3 testsuite.

root := @ROOT@
CXX := @CXX@
CXXFLAGS := @CXXFLAGS@

VPATH := $(root)/testsuite

v3test_SOURCES := testsuite_abi.cc testsuite_hooks.cc testsuite_allocator.cc
abi_check_SOURCES := abi_check.cc
abi_check_DEPENDENCIES := libv3test.a

v3test_OBJECTS := $(v3test_SOURCES:.cc=.o)

libv3test.a: $(v3test_OBJECTS)
\t$(AR) r $@ $^

abi_check: $(abi_check_SOURCES) $(abi_check_DEPENDENCIES)
\t$(CXX) $(CXXFLAGS) $^ -o $@
"""

README_file = """\
GNU C++ RUNTIME LIBRARY TESTSUITE
=================================

This package contains the GNU C++ Runtime Library Testsuite for
version %(gcc_version)s of the GNU Compiler Collection.  The tests contained in
this package are the same tests distributed with the GNU Compiler
Collection.  The QMTest extension modules included in this package was
developed by CodeSourcery, LLC under contract from the Free Standards
Group.

For assistance with this software, please contact:

  support@codesourcery.com

For general information about QMTest, the software used to run these
tests, please visit:

  http://www.qmtest.com

You can also send mail to the QMTest mailing list:

  qmtest@codesourcery.com

if you have questions about QMTest.

PREREQUISITES
=============

- Python 2.2 (or later)

  Python binary packages are available for all popular GNU/Linux
  distributions and for many other operating systems.  If you do not
  already have Python, visit http://www.python.org.

- QMTest 2.2 (or later)

  QMTest 2.2 is available from http://www.codesourcery.com/qmtest/download.html
  The source tarball will configure and build easily.

  For binary RPMs for use for LSB testing (seven architectures), see 
  http://www.linuxbase.org/download.  These binary RPMs will also
  require a matching version of Python, for portability purposes the
  LSB Application Battery version of Python (lsb-python) is used.
  This is available from the same download page and is a prerequisite
  for installing the qm package.

- Locales
 
  The tests will access the following locales, which must be installed
  on the runtime system for correct behavior (these would normally
  come from the gcc source tree for a compile test):

    en_US, en_HK, de_DE, de_DE@euro, fr_FR, fr_FR@euro, en_PH, es_MX

- GNU Compiler Collection

  In order to test the GNU C++ Runtime Library, you must install
  the GNU C++ Compiler (G++) and its associated Runtime Library.

INSTALLATION
============

There are two installation methods for the Testsuite, depending on
which package format you select.  Both package formats contain
identical files; which package format you select is purely a matter of
preference.

GNU Zip Tape Archive
--------------------

Download the file:

  qmtest_libstdcpp_%(gcc_version)s-%(pkg_version)s.tar.gz

Then, unpack the file with the following command:

  $ tar xzf qmtest_libstdcpp_%(gcc_version)s-%(pkg_version)s.tar.gz

And then build the testsuite by running:

  $ cd qmtest_libstdcpp_%(gcc_version)s
  $ ./build_binary_testsuite

Before doing this, make sure that you have a canonical version of g++ in
your "PATH", and a canonical version of libstdc++ in your
"LD_LIBRARY_PATH"; the resulting testsuite will specifically test other
libraries for compatibility with this compiler and library.  The command
will generate copious log output; you may wish to use it to verify that
the proper compiler was used.

You must also ensure that a recent version of "qmtest" is in your path.

Red Hat Package Manager
-----------------------

A prebuilt version of the test suite for i386, compiled using the GNU
3.3.3 release of g++ and libstdc++, is packaged in RPM format.  To
install it, first download the file:

  qmtest_libstdcpp_%(gcc_version)s-%(pkg_version)s-1.i386.rpm

Then, install the file with the following command, which must be run
as "root":

  $ rpm -i qmtest_libstdcpp_%(gcc_version)s-%(pkg_version)s-1.i386.rpm

The package will be installed in the directories:

  /usr/share/qmtest_libstdcpp_%(gcc_version)s
  /usr/lib/qmtest_libstdcpp_%(gcc_version)s
  
USAGE
=====

The following examples all assume that you are using the Bourne shell.
If you are using an alternative shell, you may have to make minor
changes to the commands.  Furthermore, these commands assume that the
environment variable "PKGROOT" is the path to the directory in which
you installed the Testsuite.  For example, if you used the RPM
installation, "PKGROOT" should be set to
"/usr/share/qmtest_libstdcpp_%(gcc_version)s".  They also assume that
the environment variable "EXECROOT" is the path in which the
pre-generated test executables are stored.  If you used the RPM
installation, "EXECROOT" should be set to
"/usr/lib/qmtest_libstdcpp_%(gcc_version)s".  If you used the TAR
archive installation, "EXECROOT" should be set to
"$PKGROOT/qm-executables".

These examples assume that "qmtest" is in your path.  You must also
ensure that the "LD_LIBRARY_PATH" environment variable includes the
directory in which the GNU C++ Runtime Library has been installed.  If
your "g++" is in "/path/to/bin/g++", then your "LD_LIBRARY_PATH" should
include "/path/to/lib".

There are four steps required to run the testsuite:

1. Tell QMTest where to find the extension classes required for the
   Testsuite:

     $ QMTEST_CLASS_PATH=$PKGROOT/qm-classes/qmtc:$PKGROOT/qm-classes/qmtest_gcc
     $ export QMTEST_CLASS_PATH

2. Create a test database.

     $ qmtest -D v3db create-tdb -c v3_database.V3Database \\
                                 -a srcdir=$PKGROOT/testsuite

3. Create a context file.
 
   The file should be named "v3db/context" and should contain contents
   similar to:

     CompilerTable.languages=
     V3Test.have_compiler=no
     V3Test.scratch_dir=scratch
     V3Test.compiler_output_dir=$EXECROOT
     DejaGNUTest.target=i686-pc-linux-gnu

  WARNING: You must replace $EXECROOT in the above with the actual path
  to your executables; QMTest will not perform environment variable
  expansion on this file.

  You should also adjust the "DejaGNUTest.target" line to indicate the
  GNU triplet for your operating system.

4. Run the tests:

     $ cd v3db
     $ qmtest run

   QMTest will display the results on the standard error stream.

   All released versions of G++ fail some of these tests.  Therefore,
   you should not be surprised to see some failures.

   If you would like the results in the TET output format, use the
   following command:

     $ qmtest run \\
         --result-stream="tet_stream.TETStream(filename='results.tet')"

   This command will write the results into the file "results.tet"
   using TET output format.

   If you would like to compare the results with the benchmark results
   obtained with the canonical compiler/library used to build the
   testsuite on your architecture, use the following command.

     $ qmtest run -O $PKGROOT/qm-baselines/<arch>.qmr

  For example, if you are running QMTest on Linux running on the Intel
  x86 architecture, use:
  
     $ qmtest run -O $PKGROOT/qm-baselines/i686-pc-linux-gnu.qmr

  QMTest supports a variety of more complex usage scenarios.  For more
  information see the QMTest manual, available at:

    http://www.codesourcery.com/public/qmtest/qm-2.1.2/manual.html

BASELINE FILES
==============

In the interests of insuring binary compatibility, the libstdc++
testsuite compares the symbols exported by the libstdc++ under test to
those exported by some canonical baseline version.  Unfortunately, these
baseline versions are different for each architecture, and so this
package may not contain a baseline file for your architecture.  If this
happens, the test "v3_abi_test" will return an ERROR, and complain that
its baseline file does not exist.

The solution is to create a baseline file.  To do so, download the
source for GCC version %(gcc_version)s, and build it normally.  Say that
the GCC source tree is $SRC, and you have built it in $BUILD.  Now, do
the following:
  $ cd $BUILD/<your architecture>/libstdc++-v3/testsuite
  $ make new-abi-baseline
This will generate a new baseline directory called
  $SRC/libstdc++/config/abi/<your architecture>
Drop this directory in $PKGROOT/config/abi/, and the test suite should
now work.

To build an RPM package with the new baseline included, start with the
.tar.gz distribution, unpack it, follow the above instructions, then
repack it and run
  $ rpm -tb <the new .tar.gz file>
as you would to build any other RPM.

"""

testsuite_hooks_addendum = """

// Following added automatically by %(prog_name)s:
#ifndef DID_LOCALEDIR_OVERRIDE_HACK
#ifdef LOCALEDIR
#error "LOCALEDIR should not be defined for standalone testing; \
set environment variable V3_LOCALEDIR instead"
#endif
#include <cstdlib>
#define LOCALEDIR (std::getenv("V3_LOCALEDIR"))
#define DID_LOCALEDIR_OVERRIDE_HACK
#endif
"""

PKGINFO_file = """\
This package generated automatically by %(prog_name)s.

Invoked by %(user)s at %(time)s.
Call was:
  $ %(prog_fullname)s %(prog_args)s

"""

spec_file = """\
# Do not edit -- this file automatically generated by %(prog_name)s.
Summary:     libstdc++-v3 testsuite packaged to be run under QMTest.
Name:        qmtest_libstdcpp_%(gcc_version)s
Packager:    Nathaniel Smith <njs@codesourcery.com>
Copyright:   Various
Version:     %(pkg_version)s
Release:     1
Group:       Development/Tools
BuildRoot:   %%{_tmppath}/%%{name}-buildroot
Source:      qmtest_libstdcpp_%(gcc_version)s-%(pkg_version)s.tar.gz
Vendor:      CodeSourcery LLC
Prefix:      /usr
# If we let RPM detect dependencies, it will get the idea that this
# package requires a specific version of libstdc++.so, and that is
# unhelpful:
AutoReqProv: no

%%description
This package includes the libstdc++-v3 testsuite from gcc version
%(gcc_version)s, together with QMTest extensions allowing one to run the
testsuite against an installed version of libstdc++.

%%prep
%%setup -q

%%build

%%install
rm -rf $RPM_BUILD_ROOT

# We do the building first, because some of the files generated will be
# installed later.
LIBDIR=$RPM_BUILD_ROOT/usr/lib/qmtest_libstdcpp_%(gcc_version)s
mkdir -p `dirname $LIBDIR`
./build_binary_testsuite $LIBDIR 2>&1 | tee BUILD-DETAILS

SHAREDIR=$RPM_BUILD_ROOT/usr/share/qmtest_libstdcpp_%(gcc_version)s
mkdir -p $SHAREDIR
for thing in `cat share-contents`; do
    if [ -d "$thing" ]; then
        cp -r "$thing" "$SHAREDIR/$thing"
    else
        cp "$thing" "$SHAREDIR/$thing"
    fi
done

find $LIBDIR -name '*.pyc' -o -name '*.pyo' -print0 | xargs -0 rm -f
find $SHAREDIR -name '*.pyc' -o -name '*.pyo' -print0 | xargs -0 rm -f

%%clean
rm -rf $RPM_BUILD_ROOT

%%files
# Install all files as root:
%%defattr(-,root,root)
/usr/share/qmtest_libstdcpp_%(gcc_version)s/
/usr/lib/qmtest_libstdcpp_%(gcc_version)s/
%%doc README
%%doc PKGINFO
%%doc BUILD-DETAILS
%%doc executable-gen.qmr
%%doc build_v3_dist
%%doc build_binary_testsuite

%%changelog
* Mon Apr 19 2004 Nathaniel Smith <njs@codesourcery.com> 
- Fix bug in computation of symbol baseline paths.
- Make package relocatable.
- Document generation of new symbol baseline files.
- Update QMTest-related URLs in README.

* Mon Mar 29 2004 Nathaniel Smith <njs@codesourcery.com> 
- Rework for no-compiler version of testsuite.

* Tue Mar 16 2004 Nathaniel Smith <njs@codesourcery.com> 
- Initial release.

"""


build_binary_testsuite_file = """\
#!/usr/bin/env python

# This script builds the executables needed for testing libstdc++
# without a compiler, and then runs the tests to generate a baseline.
# You should ensure that a canonical version of g++ is in your PATH, and
# a canonical version of libstdc++ in your LD_LIBRARY_PATH, before
# running this script; they will be taken as the gold standard against
# which tested versions will be compared.
#
# It must be run from the directory that contains the standalone V3
# distribution.

usage = \"\"\"\\
Usage:
    %%(progname)s [executable-output-directory] [g++ to use] \\\\
       [directory containing libstdc++ to use]
If the first argument is not given, it defaults to "qm-executables".  If
the last two arguments are not given, defaults will be found in
PATH/LD_LIBRARY_PATH.
\"\"\"

import sys
import os
import os.path
import tempfile
import shutil
import atexit
import glob

def error(*msgs):
    sys.stderr.write("ERROR: " + "".join(msgs) + "\\n")
    sys.stderr.flush()

def log(*msgs):
    prefix = "%%s: " %% progname
    sys.stdout.write(prefix  + "".join(msgs) + "\\n")
    sys.stdout.flush()

def run_and_log(cmdline, failure_ok=False):
    log("Running command: %%s" %% cmdline)
    log("Output:")
    status = os.system(cmdline)
    if status != 0 and not failure_ok:
        error("Command did not complete successfully.")
        error("Exit status: %%i" %% status)
        sys.exit(1)
    log("Execution complete, status = %%i." %% status)
    return status

def resolve_executable(name):
    if os.path.isabs(name):
        return name
    if os.sep in name:
        return os.path.abspath(name)
    log("Searching PATH for %%s." %% name)
    path = os.environ.get("PATH", "").split(os.pathsep)
    for dir in path:
        candidate = os.path.join(dir, name)
        if os.path.exists(candidate):
            return os.path.abspath(candidate)
    error("Cannot find executable %%s." %% name)
    sys.exit(1)

if not os.path.exists("THIS-IS-STANDALONE-V3"):
    error("must run from root of standalone libstdc++ test "
          "distribution.")
    sys.exit(2)

# This global variable is used directly by log().
full_progname = sys.argv[0]
progname = os.path.basename(full_progname)
args = sys.argv[1:]

log("Called as: %%s %%s" %% (full_progname, " ".join(args)))

## Process arguments.
if not 0 <= len(args) <= 3:
    error("bad command line.")
    sys.stderr.write(usage %% {"progname": progname})
    sys.exit(2)

## Find compiler output directory.
if args:
    compiler_output_dir = args.pop(0)
else:
    compiler_output_dir = "qm-executables"

## Find g++.
if args:
    gpp_path = args.pop(0)
else:
    gpp_path = "g++"
gpp_path = resolve_executable(gpp_path)

log("Using g++: %%s" %% gpp_path)
run_and_log("%%s --version" %% gpp_path)
log()

## Find libstdc++.
if args:
    libstdcpp_path = args.pop(0)
    curr = os.environ.get("LD_LIBRARY_PATH", "")
    new = "%%s:%%s" %% (libstdcpp_path, curr)
    os.environ["LD_LIBRARY_PATH"] = new

log('Using LD_LIBRARY_PATH="%%s".'
    %% os.environ.get("LD_LIBRARY_PATH", ""))
log()

## Find qmtest.
qmtest_path = resolve_executable("qmtest")
log("Using qmtest: %%s" %% qmtest_path)
run_and_log("%%s --version" %% qmtest_path)
log()

## Set up the compiler output directory.
if os.path.exists(compiler_output_dir):
    error("output directory %%s already exists." %% compiler_output_dir)
    sys.exit(1)

os.mkdir(compiler_output_dir)

## Create the temporary scratch directory.
if hasattr(tempfile, "mkdtemp"):
    tmpdir = tempfile.mkdtemp()
else:
    tmpdir = tempfile.mktemp()
    os.mkdir(tmpdir)
atexit.register(shutil.rmtree, tmpdir)

## Find the target triplet.
(config_guess_in, config_guess_out) = os.popen4("./config.guess")
config_guess_in.close()
target_triplet = config_guess_out.read()
target_triplet = target_triplet.strip()
assert "-" in target_triplet, "Bad target triplet"
log("Using target triplet: %%s" %% target_triplet)
log()

## Create the basic context to use.
log("Creating V3 context file.")
context_path = os.path.join(tmpdir, "__v3_context__")
f = open(context_path, "w")
f.write(\"\"\"\\
CompilerTable.languages=cplusplus
CompilerTable.cplusplus_kind=GCC
CompilerTable.cplusplus_options=
CompilerTable.cplusplus_path=%%(gpp_path)s
DejaGNUTest.target=%%(target_triplet)s
V3Test.scratch_dir=%%(tmpdir)s
V3Test.compiler_output_dir=%%(compiler_output_dir)s
\"\"\" %% locals())
f.close()

## Set up QMTest environment variables.
class_paths = [os.path.abspath(os.path.join("qm-classes", pkg))
               for pkg in "qmtc", "qmtest_gcc"]
qmtest_class_path = os.pathsep.join(class_paths)
os.environ["QMTEST_CLASS_PATH"] = qmtest_class_path
log('Using QMTEST_CLASS_PATH="%%s"' %% qmtest_class_path)
log()

## Create the test database we use.
log("Creating V3 test database.")
dbpath = os.path.join(tmpdir, "__v3_db__")
srcdir = os.path.abspath("testsuite")
run_and_log("qmtest -D %%(dbpath)s create-tdb "
                     "-c v3_database.V3Database "
                     "-a srcdir=%%(srcdir)s" %% locals())
log()

## Okay, we're ready to run the tests for the first time.
log("Running QMTest to generate executables.")
log("Results stored in executable-gen.qmr")
status = run_and_log("qmtest -D %%(dbpath)s run "
                     "-C %%(context_path)s --format=brief "
                     "-o executable-gen.qmr"
                     %% locals(),
                     failure_ok=True)
if status == 0 or (os.WIFEXITED(status) and os.WEXITSTATUS(status) == 1):
    log("Acceptable output status.")
else:
    error("qmtest exited unsuccessfully.")
    sys.exit(1)

## Clean the irrelevant non-executable output files; they take up a lot of
## space.
log("Cleaning up executable directory.")
for junk in glob.glob(os.path.join(compiler_output_dir, "*.[sio]")):
    os.unlink(junk)
    log("    Deleted: %%s" %% junk)

## We have the executables; all is well.  Now we'll run it again to
## generate the baseline result file.
log("Running QMTest again to generate baseline results.")
baseline_basename = "%%s.qmr" %% target_triplet
baseline = os.path.abspath(os.path.join("qm-baselines",
                                        baseline_basename))

## If there is no qm-baselines directory, create it
if not os.path.exists("qm-baselines"):                                             os.mkdir("qm-baselines")

log("Results stored in %%s" %% baseline)
run_and_log("qmtest -D %%(dbpath)s run "
            "-C %%(context_path)s --format=brief "
            "-c V3Test.have_compiler=no "
            "-o %%(baseline)s"
            %% locals(),
            failure_ok=True)
if status == 0 or (os.WIFEXITED(status) and os.WEXITSTATUS(status) == 1):
    log("Acceptable output status.")
else:
    error("qmtest exited unsuccessfully.")
    sys.exit(1)

## All done.
log("All done.")
"""
        
if __name__ == "__main__":
    main(sys.argv[0], sys.argv[1:])
