diff options
author | dos-reis <gdr@axiomatics.org> | 2011-06-02 23:04:55 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2011-06-02 23:04:55 +0000 |
commit | 640477f91eae7560dd7b46499caf0818e51dfb9e (patch) | |
tree | 4bc692e5d3c1a709b4ca690073a79d40ea86baf4 /src/driver | |
parent | 761e0f5d002dc199db16b996aafa60d6df6afcd7 (diff) | |
download | open-axiom-640477f91eae7560dd7b46499caf0818e51dfb9e.tar.gz |
more utility code consolidation
Diffstat (limited to 'src/driver')
-rw-r--r-- | src/driver/Makefile.in | 8 | ||||
-rw-r--r-- | src/driver/utils.cc | 548 |
2 files changed, 5 insertions, 551 deletions
diff --git a/src/driver/Makefile.in b/src/driver/Makefile.in index 5ad25526..1769b44c 100644 --- a/src/driver/Makefile.in +++ b/src/driver/Makefile.in @@ -32,11 +32,14 @@ bin_PROGRAMS = open-axiom$(EXEEXT) -open_axiom_SOURCES = main.cc utils.cc +open_axiom_SOURCES = main.cc open_axiom_objects = $(open_axiom_SOURCES:.cc=.lo) -open_axiom_LDADD = -L$(builddir)/../lib $(oa_c_libs) +open_axiom_LDADD = \ + -L$(axiom_target_libdir)/ \ + -L$(builddir)/../lib \ + -lOpenAxiom $(oa_c_libs) VPATH += $(top_srcdir)/src/include @@ -59,7 +62,6 @@ stamp: $(bin_PROGRAMS) -DOPENAXIOM_ROOT_DIRECTORY="\"$(open_axiom_installdir)\"" \ $(axiom_includes) $< -utils.lo: open-axiom.h main.lo: open-axiom.h open-axiom$(EXEEXT): $(open_axiom_objects) diff --git a/src/driver/utils.cc b/src/driver/utils.cc deleted file mode 100644 index 498e2f4e..00000000 --- a/src/driver/utils.cc +++ /dev/null @@ -1,548 +0,0 @@ -/* - Copyright (C) 2008-2011, Gabriel Dos Reis. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - 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. - - - Neither the name of The Numerical Algorithms Group Ltd. 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 OWNER - 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. -*/ - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include "open-axiom.h" - -namespace OpenAxiom { - -/* The basename of the file holding the OpenAxiom core executable. */ -#define OPENAXIOM_CORE_EXECUTABLE \ - "AXIOMsys" OPENAXIOM_EXEEXT - -/* The basename of the file holding the session manager executable. */ -#define OPENAXIOM_SMAN_EXECUTABLE \ - "sman" OPENAXIOM_EXEEXT - -/* Path to the OpenAxiom executable core, relative to - OPENAXIOM_ROOT_DIRECTORY, or to the system root directory as specified - on command line. */ -#define OPENAXIOM_CORE_PATH \ - "/bin/" OPENAXIOM_CORE_EXECUTABLE - -#define OPENAXIOM_GUI_SUBPATH \ - "/bin/" OPENAXIOM_GUI_EXECUTABLE - -#define OPENAXIOM_GUI_EXECUTABLE \ - "gui" OPENAXIOM_EXEEXT - -/* Path to the session manager, relative to OPENAXIOM_ROOT_DIRECTORY, - or to the system root directory as specified on command line. */ -#define OPENAXIOM_SMAN_PATH \ - "/bin/" OPENAXIOM_SMAN_EXECUTABLE - -/* Name of the entry point for Lisp-based OpenAxiom. */ -#define OPENAXIOM_LISP_CORE_ENTRY_POINT \ - "|AxiomCore|::|topLevel|" - - // -- Arguments -- - Arguments::Arguments(int n) : std::vector<char*>(n > 0 ? n + 1 : 0) - { } - - int Arguments::size() const { - return empty() ? 0 : std::vector<char*>::size() - 1; - } - - void Arguments::allocate(int n) { - resize(n + 1); - } - - char* const* Arguments::data() const { - return &*begin(); - }; - - // -- Command -- - Command::Command() - : core(), - rt_args(), - root_dir(), - exec_path() - { } - - static const char* - get_suffix(const char* first, const char* last, const char* seq) { - for (; first < last; ++first, ++seq) - if (*first != *seq) - return 0; - return seq; - } - - // -- Return non-null if `lhs' is a prefix of `rhs'. When non-null - // -- the pointer points to the '=' character that starts of the - // -- value supplied to the argument. - template<int N> - const char* is_prefix(const char (&lhs)[N], const char* rhs) { - for (int i = 0; i < N - 1; ++i) - if (lhs[i] != rhs[i]) - return 0; - return rhs + N - 1; - } - - const char* - option_value(const Command* command, const char* opt) { - const int n = strlen(opt); - for (int i = 1; i < command->core.argc; ++i) { - const char* arg = command->core.argv[i]; - if (strlen(arg) < n) - continue; - if(const char* val = get_suffix(opt, opt + n, arg)) { - if (*val++ == '=') - return val; - break; - } - } - return 0; - } - -/* Return a path to the running system, either as specified on command - line through --system=, or as specified at configuration time. */ -const char* -get_systemdir(int argc, char* argv[]) -{ - int i; - - /* Root directory specified on command line takes precedence - over location specified at configuration time. */ - for (i = 1; i < argc; ++i) - if (strcmp("--", argv[i]) == 0) - break; - else if (strncmp("--system=", argv[i], sizeof("--system=") - 1) == 0) { - return argv[i] + sizeof ("--system=") - 1; - } - - /* Command line did not change the system location to use. - Return what was computed at configuration time. */ - return OPENAXIOM_ROOT_DIRECTORY; -} - -/* Return the path to `driver'. */ -static const char* -get_driver_subpath(Driver driver) -{ - switch (driver) { - case sman_driver: - return OPENAXIOM_SMAN_PATH; - - case gui_driver: - return OPENAXIOM_GUI_SUBPATH; - - case script_driver: - case compiler_driver: - case core_driver: - case translator_driver: - case linker_driver: - return OPENAXIOM_CORE_PATH; - - default: - abort(); - } -} - - -/* Return a path for PROG specified as a relative path to PREFIX. */ -const char* -make_path_for(const char* prefix, Driver driver) -{ - const int prefix_length = strlen(prefix); - const char* prog = get_driver_subpath(driver); - char* execpath = (char*) malloc(prefix_length + strlen(prog) + 1); - strcpy(execpath, prefix); - strcpy(execpath + prefix_length, prog); - return execpath; -} - -/* Build arguments, if any, to be supplied to the runtime system - of `driver'. */ -void -build_rts_options(Command* command, Driver driver) -{ - switch (driver) { - case config_driver: - case sman_driver: - case gui_driver: - case execute_driver: - case unknown_driver: - break; - - case core_driver: - break; - - case compiler_driver: - case script_driver: - case translator_driver: - case linker_driver: - switch (OPENAXIOM_BASE_RTS) { - case gcl_runtime: - command->rt_args.allocate(3); - command->rt_args[0] = (char*) "-batch"; - command->rt_args[1] = (char*) "-eval"; - command->rt_args[2] = - (char*) ("(" OPENAXIOM_LISP_CORE_ENTRY_POINT ")"); - break; - - case sbcl_runtime: - command->rt_args.allocate(4); - command->rt_args[0] = (char*) "--noinform"; - command->rt_args[1] = (char*) "--end-runtime-options"; - command->rt_args[2] = (char*) "--noprint"; - command->rt_args[3] = (char*) "--end-toplevel-options"; - break; - - case clozure_runtime: - command->rt_args.allocate(2); - command->rt_args[0] = (char*) "--quiet"; - command->rt_args[1] = (char*) "--batch"; - break; - - case clisp_runtime: - command->rt_args.allocate(2); - command->rt_args[0] = (char*) "--quiet"; - command->rt_args[1] = (char*) "-norc"; - break; - - case ecl_runtime: - command->rt_args.allocate(2); - command->rt_args[0] = (char*) "-q"; - command->rt_args[1] = (char*) "-norc"; - break; - - default: - abort(); - } - break; - - default: - abort(); - } -} - -#if OPENAXIOM_USE_SMAN -# define OPENAXIOM_DEFAULT_DRIVER sman_driver -#elif OPENAXIOM_USE_GUI -# define OPENAXIOM_DEFAULT_DRIVER gui_driver -#else -# define OPENAXIOM_DEFAULT_DRIVER core_driver -#endif - - -static void print_line(const char* line) { - fputs(line, stdout); - fputc('\n', stdout); -} - -/* Print OpenAxiom version information. */ -static void print_version(void) { - print_line(PACKAGE_STRING); -} - -/* Print OpenAxiom invokation syntax (e.g. options) on standard - output stream. */ - -static void print_usage(void) { - print_line("Usage: open-axiom [options] [file]"); - print_line("General options:"); - print_line(" --help Print this information and exit."); - print_line(" --version Print OpenAxiom version and exit."); - print_line(" --script Execute the file argument as a Spad script."); - print_line(" If specified, this option should be last before file argument."); - print_line(" --compile Invoke the compiler on the file argument."); - print_line(" If specified, this option should be last before file argument."); - print_line(" --server Start the Superman as master process."); - print_line(" --no-server Do not start Superman as master process."); - print_line(""); - print_line("Superman options:"); - print_line(" --no-gui Do not start the Graphics or HyperDoc components."); - print_line(" --graph Start the Graphics component. This option is meaningful"); - print_line(" only if OpenAxiom was built with graphics support."); - print_line(" --no-graph Do not start the Graphics component."); - print_line(" --hyperdoc Start the HyperDoc component. This option is meaningful"); - print_line(" only if OpenAxiom was built with graphics support."); - print_line(" --no-hyperdoc Do not start the HyperDoc component."); - print_line(" --execute cmd args execute `cmd' with arguments `args'"); - - print_line(""); - print_line("Compiler options:"); - print_line(" --optimize=<n> Set compiler optimization level to <n>, a natural number."); - print_line(""); - print_line("If invoked without options and without an input file " - "OpenAxiom will start as an interative program with Superman" - " as the master process, the majority of uses. If invoked " - "with a file as single argument, OpenAxiom assumes the file is a Spad " - "script and will attempt to execute it as such."); - print_line(""); - print_line("Submit bug report to " PACKAGE_BUGREPORT); -} - - // Map a option to the driver that implement that action. - struct DriverMap { - const char* action; - const Driver driver; - }; - - static const DriverMap driver_table[] = { - { "--script", script_driver }, - { "--compile", compiler_driver }, - { "--translate", compiler_driver }, - { "--build-databases", compiler_driver }, - { "--make", linker_driver }, - }; - - // Obtain the driver that implement a specific action requested - // on command line. - static Driver - option_driver(const char* opt) { - for (int i = 0; i < length(driver_table); ++i) - if (strcmp(opt, driver_table[i].action) == 0) - return driver_table[i].driver; - return unknown_driver; - } - -/* Determine driver to be used for executing `command'. */ -Driver -preprocess_arguments(Command* command, int argc, char** argv) -{ - int i; - int other = 1; - int files = 0; - Driver driver = unknown_driver; - - command->root_dir = get_systemdir(argc, argv); - for (i = 1; i < argc; ++i) - if(strcmp(argv[i], "--no-server") == 0) - driver = core_driver; - else if (strcmp(argv[i], "--server") == 0) - driver = sman_driver; - else if (strcmp(argv[i], "--config") == 0) - driver = config_driver; - else if (strcmp(argv[i], "--execute") == 0) { - driver = execute_driver; - break; - } - else if (strcmp(argv[i], "--help") == 0) { - print_usage(); - driver = null_driver; - break; - } - else if (strcmp(argv[i], "--version") == 0) { - print_version(); - driver = null_driver; - break; - } - else if (const char* val = is_prefix("--execpath=", argv[i])) { - command->exec_path = val; - } - else { - /* Apparently we will invoke the Core system; we need to - pass on this option. */ - if (const Driver d = option_driver(argv[i])) - driver = d; - else { - if (argv[i][0] == '-') - /* Maybe option for the driver. */ - ; - else if (strlen(argv[i]) > 0) - /* Assume a file. */ - ++files; - else - /* Silly. */ - continue; - } - /* Save it for the core executable. */ - argv[other++] = argv[i]; - } - - /* Determine argument vector. */ - if (driver == execute_driver) { - command->core.argc = argc - i - 1; - command->core.argv = argv + i + 1; - } - else { - command->core.argc = other; - command->core.argv = argv; - } - - if (driver != null_driver) { - /* If we have a file but not instructed to compile, assume - we are asked to interpret a script. */ - if (files > 0) - switch (driver) { - case unknown_driver: - case sman_driver: - case gui_driver: - command->core.argc += 1; - command->core.argv = - (char**) malloc((other + 2) * sizeof(char*)); - command->core.argv[0] = argv[0]; - command->core.argv[1] = (char*) "--script"; - for (i = 0; i < other; ++i) - command->core.argv[2 + i] = argv[1 + i]; - driver = script_driver; - break; - default: - /* Driver specified by user. */ - break; - } - else if (driver == unknown_driver) - driver = OPENAXIOM_DEFAULT_DRIVER; - command->core.argv[command->core.argc] = NULL; - - build_rts_options(command, driver); - } - return driver; -} - - // Return a pointer to the path to the program to execute, as - // specified by `command' and `driver'. - static const char* - executable_path(const Command* command, Driver driver) { - return command->exec_path != 0 - ? command->exec_path - : make_path_for(command->root_dir, driver); - } - - -/* Execute the Core Executable as described by `command'. On - POSIX systems, this is a non-return function on success. - See execv(). */ -int -execute_core(const Command* command, Driver driver) -{ - char* execpath = (char*) executable_path(command, driver); -#ifdef __WIN32__ - char* command_line; - int cur = strlen(command->core.argv[0]); - int command_line_length = 0; - int i; - PROCESS_INFORMATION procInfo; - STARTUPINFO startupInfo = { 0 }; - DWORD status; /* Exit code for this program masqueraded as - the child created below. */ - - /* How long is the final command line for the MS system? */ - command_line_length += cur; - for (i = 0; i < command->rt_args.size(); ++i) - command_line_length += 1 /* blank char as separator */ - + 2 /* quotes around every argument. */ - + strlen(command->rt_args[i]); /* room for each argument */ - /* Don't forget room for the doubledash string. */ - command_line_length += sizeof("--") - 1; - /* And arguments to the actual command. */ - for (i = 1; i < command->core.argc; ++i) - command_line_length += 1 + 2 + strlen(command->core.argv[i]); - - /* Now, build the actual command line. This is done by - concatenating the arguments into a single string. */ - command_line = (char*) malloc(command_line_length + 1); - strcpy(command_line, command->core.argv[0]); - for (i = 0; i < command->rt_args.size(); ++i) { - const int arg_length = strlen(command->rt_args[i]); - command_line[cur++] = ' '; - command_line[cur++] = '"'; - strcpy(command_line + cur, command->rt_args[i]); - cur += arg_length; - command_line[cur++] = '"'; - } - command_line[cur++] = ' '; - command_line[cur++] = '-'; /* start arguments to the core executable. */ - command_line[cur++] = '-'; - for (i = 1; i < command->core.argc; ++i) { - const int arg_length = strlen(command->core.argv[i]); - command_line[cur++] = ' '; - command_line[cur++] = '"'; - strcpy(command_line + cur, command->core.argv[i]); - cur += arg_length; - command_line[cur++] = '"'; - } - command_line[cur] = '\0'; /* The command line is done. */ - - if(CreateProcess(/* lpApplicationName */ execpath, - /* lpCommandLine */ command_line, - /* lpProcessAttributes */ NULL, - /* lpThreadAttributes */ NULL, - /* bInheritHandles */ TRUE, - /* dwCreationFlags */ 0, - /* lpEnvironment */ NULL, - /* lpCurrentDirectory */ NULL, - /* lpstartupInfo */ &startupInfo, - /* lpProcessInformation */ &procInfo) == 0) { - fprintf(stderr, "error %d\n", GetLastError()); - abort(); - } - WaitForSingleObject(procInfo.hProcess, INFINITE); - GetExitCodeProcess(procInfo.hProcess, &status); - CloseHandle(procInfo.hThread); - CloseHandle(procInfo.hProcess); - return status; - -#else /* __WIN32__ */ - int i; - Arguments args(command->rt_args.size() + command->core.argc + 2); - /* GCL has this oddity that it wants to believe that argv[0] has - something to tell about what GCL's own runtime is. Silly. */ - if (OPENAXIOM_BASE_RTS == gcl_runtime) - args[0] = (char*) ""; - /* And CLISP wants to believe that argv[0] is where it hides stuff - from the saved image. */ - else if (OPENAXIOM_BASE_RTS == clisp_runtime) - args[0] = execpath; - else - args[0] = command->core.argv[0]; - /* Now, make sure we copy whatever arguments are required by the - runtime system. */ - for (i = 0; i < command->rt_args.size(); ++i) - args[i + 1] = command->rt_args[i]; - - if (command->core.argc > 1) { - /* We do have arguments from the command line. We want to - differentiate this from the base runtime system arguments. - We do this by inserting a doubledash to indicate beginning - of arguments. */ - args[command->rt_args.size() + 1] = (char*) "--"; - /* Then, copy over the arguments received from the command line. */ - for (i = 1; i < command->core.argc; ++i) - args[command->rt_args.size() + i + 1] = command->core.argv[i]; - args[command->rt_args.size() + command->core.argc + 1] = NULL; - } - else - args[command->rt_args.size() + command->core.argc] = NULL; - - execv(execpath, args.data()); - perror(execpath); - return -1; -#endif /* __WIN32__ */ -} - -} |