aboutsummaryrefslogtreecommitdiff
path: root/src/driver
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2011-06-02 23:04:55 +0000
committerdos-reis <gdr@axiomatics.org>2011-06-02 23:04:55 +0000
commit640477f91eae7560dd7b46499caf0818e51dfb9e (patch)
tree4bc692e5d3c1a709b4ca690073a79d40ea86baf4 /src/driver
parent761e0f5d002dc199db16b996aafa60d6df6afcd7 (diff)
downloadopen-axiom-640477f91eae7560dd7b46499caf0818e51dfb9e.tar.gz
more utility code consolidation
Diffstat (limited to 'src/driver')
-rw-r--r--src/driver/Makefile.in8
-rw-r--r--src/driver/utils.cc548
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__ */
-}
-
-}