Subversion Repositories tendra.SVN

Rev

Rev 5 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific, prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 */
/*
                 Crown Copyright (c) 1997

    This TenDRA(r) Computer Program is subject to Copyright
    owned by the United Kingdom Secretary of State for Defence
    acting through the Defence Evaluation and Research Agency
    (DERA).  It is made available to Recipients with a
    royalty-free licence for its use, reproduction, transfer
    to other parties and amendment for any purpose not excluding
    product development provided that any such use et cetera
    shall be deemed to be acceptance of the following conditions:-

        (1) Its Recipients shall ensure that this Notice is
        reproduced upon any copies or amended versions of it;

        (2) Any amended version of it shall be clearly marked to
        show both the nature of and the organisation responsible
        for the relevant amendment or amendments;

        (3) Its onward transfer from a recipient to another
        party shall be deemed to be that party's acceptance of
        these conditions;

        (4) DERA gives no warranty or assurance as to its
        quality or suitability for any purpose and DERA accepts
        no liability whatsoever in relation to any use to which
        it may be put.
*/


#include "config.h"
#include "filename.h"
#include "list.h"
#include "archive.h"
#include "copyright.h"
#include "environ.h"
#include "flags.h"
#include "startup.h"
#include "suffix.h"
#include "utility.h"


/*
 * STRING VARIABLES
 *
 * These variables given various compilation values, including the location of
 * the main temporary directory.
 */

char *api_info = "unknown";
char *api_output = API_ANAL_NAME;
char *dump_opts = null;
char *environ_dir = ".";
char *final_name = null;
char *machine_name = "unknown";
char *name_E_file = ENDUP_NAME;
char *name_h_file = STARTUP_NAME;
char *name_j_file = TDF_COMPLEX_NAME;
char *name_k_file = C_SPEC_COMPLEX_NAME;
char *name_K_file = CPP_SPEC_COMPLEX_NAME;
char *name_p_file = TOKDEF_NAME;
char *temporary_dir = "/usr/tmp";
char *tokdef_output = null;
char *version_flag = "";
char *dev_null = null;
char **env_paths = NULL;


/*
 * INTERNAL OPTIONS
 *
 * These variables control the overall behaviour of tcc. For example, should
 * we be running in verbose mode?
 */

boolean api_checks = 0;
boolean checker = 0;
boolean copyright = 0;
boolean dry_run = 0;
boolean env_dump = 0;
boolean link_specs = 1;
boolean make_up_names = 0;
boolean show_api = 0;
boolean show_errors = 0;
boolean suffix_overrides = 0;
boolean taciturn = 0;
boolean tidy_up = 0;
boolean time_commands = 0;
boolean tool_chain = 0;
boolean tool_chain_environ = 0;
boolean verbose = 0;
boolean warnings = 1;
/* Should the cmd line args be rank sorted, or taken as is? */
boolean no_shuffle = 0;


/*
 * COMPILATION CONTROL OPTIONS
 *
 * These variables control the main compilation path taken. For example, should
 * we form a TDF archive?
 */


boolean make_archive = 0;
boolean make_complex = 0;
boolean make_preproc = 0;
boolean make_pretty = 0;
boolean make_tspec = 0;
boolean use_assembler = 1;
boolean use_mips_assembler = 0;
boolean use_alpha_assembler = 0;
boolean use_hp_linker = 0;
boolean use_dynlink = 0;
boolean use_sparc_cc = 0;
boolean use_system_cc = 0;
boolean allow_cpp = 0;
boolean allow_notation = 0;
boolean allow_pl_tdf = 0;
boolean allow_specs = 0;


/*
 * FILE PRESERVATION AND CONSTRUCTION OPTIONS
 *
 * These arrays control the creation and storage of the various file types. In
 * the keeps array, a nonzero value indicates that any file of this type which
 * is created should be preserved. In the stops array, it indicates that the
 * compilation halts at this stage. In either case, 0 means "false but
 * changeable", 1 means "true but changeable", and 2 means "true and
 * unchangeable". The special variable, keep_ofiles, indicates whether all
 * binary object files should be kept when more than one input file is given
 * (this is for cc compatibility). The keeps_aux array keeps track of the
 * explicit file preservation options. These tables need to be kept in step
 * with Table 1.
 */

boolean keeps[TYPE_ARRAY_SIZE] = {
        0,      /* C_SOURCE */
        0,      /* PREPROC_C */
        0,      /* CPP_SOURCE */
        0,      /* PREPROC_CPP */
        0,      /* INDEP_TDF */
        0,      /* DEP_TDF */
        0,      /* AS_SOURCE */
        0,      /* BINARY_OBJ */
        2,      /* EXECUTABLE */
        1,      /* PRETTY_TDF */
        0,      /* PL_TDF */
        2,      /* TDF_ARCHIVE */
        0,      /* MIPS_G_FILE */
        0,      /* MIPS_T_FILE */
        0,      /* C_SPEC */
        0,      /* CPP_SPEC */
        0,      /* STARTUP_FILE */
        0,      /* UNKNOWN_TYPE */
        0,      /* INDEP_TDF_COMPLEX (dummy type) */
        0,      /* C_SPEC_1 (dummy type) */
        1,      /* C_SPEC_2 (dummy type) */
        0,      /* CPP_SPEC_1 (dummy type) */
        1,      /* CPP_SPEC_2 (dummy type) */
        0,      /* INDEP_TDF_AUX (dummy type) */
        0        /* BINARY_OBJ_AUX (dummy type) */
};

boolean keeps_aux[TYPE_ARRAY_SIZE] = {
        0,      /* C_SOURCE */
        0,      /* PREPROC_C */
        0,      /* CPP_SOURCE */
        0,      /* PREPROC_CPP */
        0,      /* INDEP_TDF */
        0,      /* DEP_TDF */
        0,      /* AS_SOURCE */
        0,      /* BINARY_OBJ */
        0,      /* EXECUTABLE */
        0,      /* PRETTY_TDF */
        0,      /* PL_TDF */
        0,      /* TDF_ARCHIVE */
        0,      /* MIPS_G_FILE */
        0,      /* MIPS_T_FILE */
        0,      /* C_SPEC */
        0,      /* CPP_SPEC */
        0,      /* STARTUP_FILE */
        0,      /* UNKNOWN_TYPE */
        0,      /* INDEP_TDF_COMPLEX (dummy type) */
        0,      /* C_SPEC_1 (dummy type) */
        0,      /* C_SPEC_2 (dummy type) */
        0,      /* CPP_SPEC_1 (dummy type) */
        0,      /* CPP_SPEC_2 (dummy type) */
        0,      /* INDEP_TDF_AUX (dummy type) */
        0        /* BINARY_OBJ_AUX (dummy type) */
};

boolean stops[TYPE_ARRAY_SIZE] = {
        0,      /* C_SOURCE */
        0,      /* PREPROC_C */
        0,      /* CPP_SOURCE */
        0,      /* PREPROC_CPP */
        0,      /* INDEP_TDF */
        0,      /* DEP_TDF */
        0,      /* AS_SOURCE */
        0,      /* BINARY_OBJ */
        2,      /* EXECUTABLE */
        2,      /* PRETTY_TDF */
        0,      /* PL_TDF */
        2,      /* TDF_ARCHIVE */
        0,      /* MIPS_G_FILE */
        0,      /* MIPS_T_FILE */
        0,      /* C_SPEC */
        0,      /* CPP_SPEC */
        0,      /* STARTUP_FILE */
        0,      /* UNKNOWN_TYPE */
        0,      /* INDEP_TDF_COMPLEX (dummy type) */
        0,      /* C_SPEC_1 (dummy type) */
        0,      /* C_SPEC_2 (dummy type) */
        0,      /* CPP_SPEC_1 (dummy type) */
        0,      /* CPP_SPEC_2 (dummy type) */
        0,      /* INDEP_TDF_AUX (dummy type) */
        0        /* BINARY_OBJ_AUX (dummy type) */
};

static boolean keep_all = 0;
static boolean keep_ofiles = 1;


/*
 * INDIVIDUAL OPTIONS
 *
 * These flags control those individual executable options which are not easily
 * integrated into the main scheme of things.
 */

boolean flag_diag = 0;
boolean flag_keep_err = 0;
boolean flag_incl = 0;
boolean flag_merge_all = 0;
boolean flag_nepc = 0;
boolean flag_no_files = 0;
boolean flag_optim = 0;
boolean flag_prof = 0;
boolean flag_startup = 1;
boolean flag_strip = 0;


/*
 * EXECUTABLES
 *
 * These variables give the values of the various executables comprising the
 * system. For example, exec_produce gives the location of the C to TDF
 * producer.
 */

list *exec_produce = null;
list *exec_preproc = null;
list *exec_cpp_produce = null;
list *exec_cpp_preproc = null;
list *exec_tdf_link = null;
list *exec_translate = null;
list *exec_assemble = null;
list *exec_assemble_mips = null;
list *exec_link = null;
list *exec_notation = null;
list *exec_pl_tdf = null;
list *exec_pretty = null;
list *exec_spec_link = null;
list *exec_cpp_spec_link = null;
list *exec_split_arch = null;
list *exec_build_arch = null;
list *exec_cat = null;
list *exec_cc = null;
list *exec_mkdir = null;
list *exec_move = null;
list *exec_remove = null;
list *exec_touch = null;
list *exec_dynlink = null;
list *exec_dump_anal = null;
list *exec_dump_link = null;


/*
 * BUILT-IN OPTIONS
 *
 * These lists of options are built into the system, although they may be
 * altered by environments and command-line options.
 */

list *std_prod_incldirs = null;
list *std_prod_portfile = null;
list *std_prod_startdirs = null;
list *std_prod_startup = null;
list *std_cpp_prod_incldirs = null;
list *std_cpp_prod_startdirs = null;
list *std_cpp_prod_startup = null;
list *std_tdf_link_libdirs = null;
list *std_tdf_link_libs = null;
list *std_link_crt0 = null;
list *std_link_crt1 = null;
list *std_link_crtp_n = null;
list *std_link_crtn = null;
list *std_link_libdirs = null;
list *std_link_libs = null;
list *std_link_c_libs = null;
list *std_link_entry = null;



/*
 * COMMAND-LINE OPTIONS
 *
 * These lists of options are those specified on the command-line.
 */

list *usr_prod_incldirs = null;
list *usr_prod_foptions = null;
list *usr_prod_eoptions = null;
list *usr_prod_startup = null;
list *usr_cpp_prod_startup = null;
list *usr_pl_tdf_incldirs = null;
list *usr_tdf_link_libdirs = null;
list *usr_tdf_link_libs = null;
list *usr_link_libdirs = null;
list *usr_link_libs = null;


/*
 * EXECUTABLE OPTIONS
 *
 * These lists record the command-line options which are passed directly to the
 * various executables.
 */

list *opt_produce = null;
list *opt_preproc = null;
list *opt_cpp_produce = null;
list *opt_cpp_preproc = null;
list *opt_tdf_link = null;
list *opt_translate = null;
list *opt_assemble = null;
list *opt_assemble_mips = null;
list *opt_dynlink = null;
list *opt_link = null;
list *opt_notation = null;
list *opt_pl_tdf = null;
list *opt_pretty = null;
list *opt_spec_link = null;
list *opt_cpp_spec_link = null;
list *opt_dump_anal = null;
list *opt_dump_link = null;
list *opt_archive = null;
list *opt_joiner = null;
list *opt_cc = null;
list *opt_startup = null;
list *opt_endup = null;
list *opt_unknown = null;


/*
 * SET A KEEP OR STOP OPTION
 *
 * This routine sets a value in the keeps or stops arrays. The variable t gives
 * the file type (including ALL_TYPES) and k gives the storage command (see
 * flags.h).
 */

void
set_stage(int t, int k)
{
        if (t == ALL_TYPES) {
                boolean ks = keeps[STARTUP_FILE];
                if (k == STOP_STAGE || k == STOP_ONLY_STAGE) {
                        error(WARNING, "Illegal stop option");
                } else if (k == KEEP_STAGE) {
                        int i;
                        for (i = 0; i < array_size(keeps); i++) {
                                if (keeps[i] == 0) {
                                        keeps[i] = 1;
                                }
                        }
                        keep_all = 1;
                } else if (k == DONT_KEEP_STAGE) {
                        int i;
                        for (i = 0; i < array_size(keeps); i++) {
                                if (keeps[i] == 1) {
                                        keeps[i] = 0;
                                }
                        }
                        keep_all = 0;
                        keep_ofiles = 0;
                }
                keeps[STARTUP_FILE] = ks;
        } else {
                if (k == STOP_STAGE || k == STOP_ONLY_STAGE) {
                        static int last_stop = UNKNOWN_TYPE;
                        if (stops[t] == 0) {
                                stops[t] = 1;
                        }
                        if (k == STOP_STAGE && keeps[t] == 0) {
                                keeps[t] = 1;
                        }
                        switch (last_stop) {
                        case UNKNOWN_TYPE:
                                break;
                        case INDEP_TDF:
                        case C_SPEC:
                        case CPP_SPEC:
                                if (t == C_SPEC || t == CPP_SPEC) {
                                        break;
                                }
                                if (t == INDEP_TDF) {
                                        break;
                                }
                                goto default_lab;
                        case PREPROC_C:
                        case PREPROC_CPP:
                                if (t == PREPROC_CPP) {
                                        break;
                                }
                                goto default_lab;
                        default:
default_lab:
                                if (t != last_stop) {
                                        error(WARNING, "More than one stop option given");
                                }
                                break;
                        }
                        last_stop = t;
                } else if (k == KEEP_STAGE) {
                        if (keeps[t] == 0) {
                                keeps[t] = 1;
                        }
                        keeps_aux[t] = 1;
                        if (t == BINARY_OBJ) {
                                keep_ofiles = 1;
                        }
                } else if (k == DONT_KEEP_STAGE) {
                        if (keeps[t] == 1) {
                                keeps[t] = 0;
                        }
                        keeps_aux[t] = 2;
                        if (t == BINARY_OBJ) {
                                keep_ofiles = 0;
                        }
                }
        }
        return;
}


/*
 * SET THE MACHINE NAME
 *
 * This routine sets any special flags required by the machine indicated by
 * machine_name.
 */

void
set_machine(void)
{
#if 0
        char *mach = machine_name;
        use_assembler = 1;
        use_mips_assembler = 0;
        use_alpha_assembler = 0;
        use_hp_linker = 0;
        if (streq(mach, "hp") || streq(mach, "hppa")) {
                use_hp_linker = 1;
        } else if (streq(mach, "mips")) {
                use_mips_assembler = 1;
        } else if (streq(mach, "alpha")) {
                use_alpha_assembler = 1;
        } else if (streq(mach, "sparc") || streq(mach, "svr4_sparc")) {
                use_sparc_cc = 1;
        } else if (streq(mach, "svr4_i386")) {
                use_sparc_cc = 2;
        } else if (streq(mach, "transputer")) {
                use_assembler = 0;
        }
#endif
        return;
}


/*
 * INITIALISE ALL OPTIONS
 *
 * This routine initialises any necessary values before the command-line
 * options are read.
 */

void
initialise_options(void)
{
        /* Initialise executables */
        list *p;
        int sz;
        int i;
        exec_produce = make_list("builtin/undef C_producer");
        exec_preproc = make_list("builtin/undef C_preprocessor");
        exec_cpp_produce = make_list("builtin/undef C++_producer");
        exec_cpp_preproc = make_list("builtin/undef C++_preprocessor");
        exec_tdf_link = make_list("builtin/undef TDF_linker");
        exec_translate = make_list("builtin/undef TDF_translator");
        exec_assemble = make_list("builtin/undef system_assembler");
        exec_assemble_mips = make_list("builtin/undef mips_assembler");
        exec_link = make_list("builtin/undef system_linker");
        exec_notation = make_list("builtin/undef TDF_notation_compiler");
        exec_pl_tdf = make_list("builtin/undef PL_TDF_compiler");
        exec_pretty = make_list("builtin/undef TDF_pretty_printer");
        exec_spec_link = make_list("builtin/undef C_spec_linker");
        exec_cpp_spec_link = make_list("builtin/undef C++_spec_linker");
        exec_split_arch = make_list("builtin/split_archive");
        exec_build_arch = make_list("builtin/build_archive");
        exec_cat = make_list("builtin/cat");
        exec_cc = make_list("builtin/undef system_compiler");
        exec_mkdir = make_list("builtin/mkdir");
        exec_move = make_list("builtin/move");
        exec_remove = make_list("builtin/remove");
        exec_touch = make_list("builtin/touch");
        exec_dynlink = make_list("builtin/undef dynamic_initialiser");

        /* Initialise other options */
        find_envpath();
        for (p = opt_startup; p != null; p = p->next) {
                add_to_startup(p->item);
        }
        for (p = opt_endup; p != null; p = p->next) {
                add_to_endup(p->item);
        }
        if (checker) {
                allow_specs = 1;
        }

        /* allocate space for cmd line env args */
        sz = (sizeof(PATH_SUBS));
        env_paths = (char**) xalloc (sz * sizeof(char *));

        /* Here, we should set these to sane defaults.  For now, just NULL */
        for (i=0; i < sz; i++) {
                env_paths[i] = NULL;
        }
        return;
}


/*
 * UPDATE ALL OPTIONS
 *
 * This routine updates the values of the variables above after all the
 * command-line options have been read. The stops options need to be kept in
 * step with the general compilation scheme given in compile.c. Deciding which
 * versions of certain file types to preserve (INDEP_TDF and C_SPEC in
 * particular) gets pretty messy.
 */

void
update_options(void)
{
        char *mode = null;
        static boolean done_diag = 0;
        static boolean done_preproc = 0;
        static boolean done_prof = 0;
        static boolean done_time = 0;

        /* Process archive options */
        process_archive_opt();

        /* Deal with cc mode */
        if (checker) {
                mode = "checker";
        }
        if (use_system_cc) {
                if (!checker) {
                        error(WARNING, "Using the system C compiler");
                }
                mode = "system compiler";
        }
        if (mode) {
                if (make_archive) {
                        error(WARNING, "Can't build TDF archive in %s mode",
                              mode);
                        stops[INDEP_TDF] = 1;
                        make_archive = 0;
                }
                if (make_complex) {
                        error(WARNING, "Can't build TDF complex in %s mode",
                              mode);
                        make_complex = 0;
                }
                if (make_pretty) {
                        error(WARNING, "Can't pretty print TDF in %s mode",
                              mode);
                        stops[INDEP_TDF] = 1;
                        make_pretty = 0;
                }
                allow_notation = 0;
                allow_pl_tdf = 0;
        }

        /* Register extra stops */
        if (make_archive) {
                set_stage(TDF_ARCHIVE, STOP_STAGE);
        }
        if (make_preproc) {
                set_stage(PREPROC_C, STOP_ONLY_STAGE);
                set_stage(PREPROC_CPP, STOP_ONLY_STAGE);
        }
        if (make_pretty) {
                set_stage(PRETTY_TDF, STOP_STAGE);
        }

        /* Read special environments etc. */
        if (make_preproc && keeps[PREPROC_C] && !done_preproc) {
                read_env(PREPROC_ENV);
                done_preproc = 1;
        }
        if (flag_diag && !done_diag) {
                read_env(DIAG_ENV);
                done_diag = 1;
        }
        if (flag_prof && !done_prof) {
                read_env(PROF_ENV);
                done_prof = 1;
        }
        if (time_commands && !done_time) {
                read_env(TIME_ENV);
                done_time = 1;
        }

        /* Print API information */
        if (show_api) {
                error(INFO, "API is %s", api_info);
                show_api = 0;
        }

#if 0
        /* The option -Fk means stop after producer */
        if (stops[C_SPEC] || stops[CPP_SPEC] ||
            stops[PREPROC_C] || stops[PREPROC_CPP]) {
                stops[INDEP_TDF] = 1;
        }
#endif

        /* Propagate stop options down */
        if (stops[INDEP_TDF]) {
                stops[INDEP_TDF_COMPLEX] = 1;
                stops[DEP_TDF] = 1;
                stops[AS_SOURCE] = 1;
                stops[BINARY_OBJ] = 1;
        } else if (stops[DEP_TDF]) {
                stops[AS_SOURCE] = 1;
                stops[BINARY_OBJ] = 1;
        } else if (stops[AS_SOURCE]) {
                stops[BINARY_OBJ] = 1;
        } else if (stops[MIPS_G_FILE]) {
                stops[BINARY_OBJ] = 1;
        } else if (stops[MIPS_T_FILE]) {
                stops[BINARY_OBJ] = 1;
        }

        /* Check keep options */
        if (make_complex) {
                if (keeps[INDEP_TDF]) {
                        keeps[INDEP_TDF] = keep_all;
                        keeps[INDEP_TDF_COMPLEX] = 1;
                }
                if (stops[INDEP_TDF]) {
                        keeps[C_SPEC_1] = 1;
                        keeps[CPP_SPEC_1] = 1;
                }
        }
        if (keeps[C_SPEC]) {
                if (make_complex) {
                        keeps[C_SPEC] = keep_all;
                        keeps[C_SPEC_1] = 1;
                }
        } else {
                if (keeps_aux[C_SPEC] == 2) {
                        keeps[C_SPEC_1] = 0;
                        keeps[C_SPEC_2] = 0;
                }
        }
        if (keeps[CPP_SPEC]) {
                if (make_complex) {
                        keeps[CPP_SPEC] = keep_all;
                        keeps[CPP_SPEC_1] = 1;
                }
        } else if (keeps_aux[CPP_SPEC] == 2) {
                keeps[CPP_SPEC_1] = 0;
                keeps[CPP_SPEC_2] = 0;
        }
        if (keep_ofiles && no_input_files > 1 && !make_complex) {
                keeps[BINARY_OBJ] = 1;
        }
        if (keeps_aux[BINARY_OBJ] == 1) {
                keeps[BINARY_OBJ_AUX] = 1;
        }
        if (link_specs) {
                boolean b;
                if (checker && !use_system_cc) {
                        if (keeps_aux[BINARY_OBJ]) {
                                b = 1;
                        } else if (stops[BINARY_OBJ] && !stops[AS_SOURCE]) {
                                b = keeps[BINARY_OBJ];
                        } else {
                                b = 0;
                        }
                } else {
                        b = keeps[BINARY_OBJ];
                }
                if (b) {
                        if (make_complex) {
                                keeps[C_SPEC_1] = 1;
                                keeps[CPP_SPEC_1] = 1;
                        } else {
                                keeps[C_SPEC] = 1;
                                keeps[CPP_SPEC] = 1;
                        }
                        keeps[BINARY_OBJ_AUX] = 1;
                }
        }

        /* Set checker options */
        if (checker) {
                if (allow_specs == 0) {
                        allow_specs = 1;
                }
                if (!use_system_cc) {
                        stops[C_SPEC_2] = 1;
                        stops[CPP_SPEC_2] = 1;
                }
        }

        /* Print the copyright message if required */
        if (copyright) {
                print_copyright();
                copyright = 0;
        }

        /* A couple of housekeeping routines */
        close_startup();
        find_envpath();
        return;
}