#! /usr/bin/env python

########################################################################
#
# File:   qmtest
# Author: Alex Samuel
# Date:   2001-03-15
#
# Contents:
#   QMTest command line application.
#
# Copyright (c) 2001 - 2006 by CodeSourcery.  All rights reserved. 
#
# For license terms see the file COPYING.
#
########################################################################

########################################################################
# Check Python Version
########################################################################

# Before doing anything else, check that the version of Python in use
# is sufficiently recent.  All code in this section should be portable
# even to old versions of Python.

import sys

def check_python_version():
    """Check to see if the Python interpreter in use is acceptable.

    If the Python interpreter is not sufficiently recent, issue an
    error message and exit."""

    required_python_version = (2, 2)

    # Get the version of Python in use.
    try:
        actual_version = sys.version_info
    except:
        # Older versions of Python do not have "sys.version_info".
        actual_version = (0, 0, 0, 0)

    old = 0
    for i in range(len(required_python_version)):
        if required_python_version[i] > actual_version[i]:
            old = 1

    if old:
        if len(required_python_version) == 2:
            version = "%d.%d" % required_python_version
        else:
            version = "%d.%d.%d" % required_python_version
        sys.stderr.write("qmtest: error: QMTest requires Python %s or later.\n"
                         % version)
        sys.exit(1)

check_python_version()

########################################################################
# Imports
########################################################################

import errno
import gc
import os
import os.path
import string
import traceback
import qm
import qm.cmdline
import qm.diagnostic
import qm.platform
import qm.structured_text
import qm.test.cmdline
if sys.platform != "win32":
    import qm.sigmask

########################################################################
# Functions
########################################################################

def print_error_message(message):
    """Output an error message.

    'message' -- Structured text for the error message to emit.  The
    messing is emitted to the standard error stream with an
    identifying prefix."""
    
    prefix = "qmtest: error: "
    message = qm.structured_text.to_text(str(message),
                                         indent=len(prefix))
    message = prefix + message[len(prefix):]
    sys.stderr.write(message)


def main():
    """Run QMTest.

    returns -- The exit code that should be provided to the operating
    system."""
    
    # Save the initial signal mask, as early as possible.
    if sys.platform != "win32":
        qm.sigmask.save_mask()

    # Parse the command line.
    command = qm.test.cmdline.QMTest(sys.argv[1:], sys.argv[0])

    # Execute the command.
    exit_code = command.Execute()

    return exit_code
    
########################################################################
# script
########################################################################

# Assume that something will go wrong.
exit_code = 2

try:
    # Set the program name.
    qm.common.program_name = "QMTest"

    # Load messages.
    qm.diagnostic.load_messages("test")

    # Load RC options.
    qm.rc.Load("test")

    try:
        exit_code = main()
    except qm.cmdline.CommandError, msg:
        print_error_message(msg)
        sys.stderr.write(
            "Run 'qmtest --help' to get instructions about how to use QMTest.\n")
    except qm.common.QMException, msg:
        print_error_message(msg)
    except NotImplementedError:
        exc_info = sys.exc_info()
        method_name = traceback.extract_tb(exc_info[2])[-1][2]
        print_error_message(qm.message("not implemented",
                                       method_name = method_name))
        sys.stderr.write(qm.common.format_traceback(exc_info))
    except KeyboardInterrupt:
        sys.stderr.write("\nqmtest: Interrupted.\n")
        raise
    except qm.platform.SignalException, se:
        # SIGTERM indicates a request to shut down.  Other signals
        # should be handled earlier.
        if se.GetSignalNumber() != signal.SIGTERM:
            raise
finally:
    # Collect garbage so that any "__del__" methods with externally
    # visible side-effects are executed.
    del qm.test.cmdline._the_qmtest
    gc.collect()

# End the program.
sys.exit(exit_code)

########################################################################
# Local Variables:
# mode: python
# indent-tabs-mode: nil
# End:
