diff options
author | dos-reis <gdr@axiomatics.org> | 2010-11-28 23:57:59 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2010-11-28 23:57:59 +0000 |
commit | dea4d75caba3466cdc8595d333c31a5393912c69 (patch) | |
tree | afd0a96708651f2d6b483705f85c80588e7906c0 /src/driver | |
parent | a53a740a2a1cb6cbfa58cc79caedd4e947ff1ca0 (diff) | |
download | open-axiom-dea4d75caba3466cdc8595d333c31a5393912c69.tar.gz |
(all-lisp): Require all-driver.
* driver/utils.c: Tidy.
* driver/utils.h: Likewise.
* sman/sman.c: Likewise.
Diffstat (limited to 'src/driver')
-rw-r--r-- | src/driver/main.c | 103 | ||||
-rw-r--r-- | src/driver/utils.c | 121 | ||||
-rw-r--r-- | src/driver/utils.h | 93 |
3 files changed, 186 insertions, 131 deletions
diff --git a/src/driver/main.c b/src/driver/main.c index 002ccef8..ad2eac1d 100644 --- a/src/driver/main.c +++ b/src/driver/main.c @@ -50,69 +50,70 @@ namespace OpenAxiom { -/* Publish the system exec prefix for use by sub-processes. */ -static void -publish_systemdir(const char* dir) -{ - if (!oa_setenv(OPENAXIOM_GLOBAL_ENV, dir)) { - perror("publish_systemdir"); - abort(); + // Publish the system exec prefix for use by sub-processes. + static void + publish_systemdir(const char* dir) + { + if (!oa_setenv(OPENAXIOM_GLOBAL_ENV, dir)) { + perror("publish_systemdir"); + abort(); + } } -} - -static void -augment_variable(const char* name, const char* value) { - const char* oldval = oa_getenv(name); - const int value_length = strlen(value); - const int oldval_length = oldval == 0 ? 0 : strlen(oldval); - const int newval_length = value_length + 1 + oldval_length; - char* newval = (char*) malloc(newval_length + 1); - - strcpy(newval,value); - if (oldval != 0) { - newval[value_length] = openaxiom_ifs; - strcpy(newval + value_length + 1, oldval); + + static void + augment_variable(const char* name, const char* value) { + const char* oldval = oa_getenv(name); + const int value_length = strlen(value); + const int oldval_length = oldval == 0 ? 0 : strlen(oldval); + const int newval_length = value_length + 1 + oldval_length; + char* newval = (char*) malloc(newval_length + 1); + + strcpy(newval,value); + if (oldval != 0) { + newval[value_length] = openaxiom_ifs; + strcpy(newval + value_length + 1, oldval); + } + + if (!oa_setenv(name, newval)) + perror("oa_augment_environment_variable"); } - if (!oa_setenv(name, newval)) - perror("oa_augment_environment_variable"); -} - -static void -upgrade_environment(const char* sysdir) { - augment_variable("TEXINPUTS", - oa_concatenate_string(sysdir, OPENAXIOM_TEXINPUTS_PATH)); - augment_variable("BIBINPUTS", - oa_concatenate_string(sysdir, OPENAXIOM_BIBINPUTS_PATH)); - publish_systemdir(sysdir); -} + static void + upgrade_environment(const char* sysdir) { + augment_variable("TEXINPUTS", + oa_concatenate_string(sysdir, OPENAXIOM_TEXINPUTS_PATH)); + augment_variable("BIBINPUTS", + oa_concatenate_string(sysdir, OPENAXIOM_BIBINPUTS_PATH)); + augment_variable("LD_LIBRARY_PATH", + oa_concatenate_string(sysdir, "/lib")); + publish_systemdir(sysdir); + } -/* Print configuration info. */ -static int -print_configuration_info(Command* command) { - int i; - for (i = 1; i < command->core.argc; ++i) { - if (strcmp(command->core.argv[i], "include") == 0) - printf("\"%s\"/include ", command->root_dir); - else if (strcmp(command->core.argv[i], "lib") == 0) - printf(" -L\"%s\"/lib -lOpenAxiom", command->root_dir); - else { - fprintf(stderr, "open-axiom: invalid request %s\n", - command->core.argv[i]); - return 1; + // Print configuration info. + static int + print_configuration_info(Command* command) { + int i; + for (i = 1; i < command->core.argc; ++i) { + if (strcmp(command->core.argv[i], "include") == 0) + printf("\"%s\"/include ", command->root_dir); + else if (strcmp(command->core.argv[i], "lib") == 0) + printf(" -L\"%s\"/lib -lOpenAxiom", command->root_dir); + else { + fprintf(stderr, "open-axiom: invalid request %s\n", + command->core.argv[i]); + return 1; + } } + fflush(stdout); + return 0; } - fflush(stdout); - return 0; -} - } int main(int argc, char* argv[]) { using namespace OpenAxiom; - Command command = { }; + Command command; Driver driver = preprocess_arguments(&command, argc, argv); upgrade_environment(command.root_dir); diff --git a/src/driver/utils.c b/src/driver/utils.c index 5122ca9b..20e130fb 100644 --- a/src/driver/utils.c +++ b/src/driver/utils.c @@ -62,7 +62,42 @@ namespace 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() + { } + + // -- 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; + } + + /* Return a path to the running system, either as specified on command line through --system=, or as specified at configuration time. */ const char* @@ -97,6 +132,9 @@ get_driver_name(Driver driver) case core_driver: return OPENAXIOM_CORE_PATH; + case alien_driver: + return 0; + default: abort(); } @@ -115,15 +153,6 @@ make_path_for(const char* prefix, Driver driver) return execpath; } -/* Allocate a nul-terminated vector for holding pointers to arguments - for the base Lisp runtime. */ -static void -openaxiom_allocate_argv(Command* command, int n) { - command->rt_argc = n; - command->rt_argv = (char**) malloc((n + 1) * sizeof(char*)); - command->rt_argv[n] = 0; -} - /* Build arguments, if any, to be supplied to the runtime system of `driver'. */ void @@ -134,6 +163,7 @@ build_rts_options(Command* command, Driver driver) case sman_driver: case execute_driver: case unknown_driver: + case alien_driver: break; case core_driver: @@ -143,31 +173,31 @@ build_rts_options(Command* command, Driver driver) case script_driver: switch (OPENAXIOM_BASE_RTS) { case gcl_runtime: - openaxiom_allocate_argv(command, 3); - command->rt_argv[0] = (char*) "-batch"; - command->rt_argv[1] = (char*) "-eval"; - command->rt_argv[2] = + 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: - openaxiom_allocate_argv(command, 4); - command->rt_argv[0] = (char*) "--noinform"; - command->rt_argv[1] = (char*) "--end-runtime-options"; - command->rt_argv[2] = (char*) "--noprint"; - command->rt_argv[3] = (char*) "--end-toplevel-options"; + 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: - openaxiom_allocate_argv(command, 2); - command->rt_argv[0] = (char*) "--quiet"; - command->rt_argv[1] = (char*) "--batch"; + command->rt_args.allocate(2); + command->rt_args[0] = (char*) "--quiet"; + command->rt_args[1] = (char*) "--batch"; break; case clisp_runtime: - openaxiom_allocate_argv(command, 2); - command->rt_argv[0] = (char*) "--quiet"; - command->rt_argv[1] = (char*) "-norc"; + command->rt_args.allocate(2); + command->rt_args[0] = (char*) "--quiet"; + command->rt_args[1] = (char*) "-norc"; break; default: @@ -266,6 +296,11 @@ preprocess_arguments(Command* command, int argc, char** argv) driver = null_driver; break; } + else if (const char* val = is_prefix("--execpath=", argv[i])) { + command->exec_path = val; + driver = alien_driver; + break; + } else { /* Apparently we will invoke the Core system; we need to pass on this option. */ @@ -327,7 +362,14 @@ preprocess_arguments(Command* command, int argc, char** argv) 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 @@ -336,7 +378,7 @@ preprocess_arguments(Command* command, int argc, char** argv) int execute_core(const Command* command, Driver driver) { - char* execpath = (char*) make_path_for(command->root_dir, driver); + char* execpath = (char*) executable_path(command, driver); #ifdef __WIN32__ char* command_line; int cur = strlen(command->core.argv[0]); @@ -349,10 +391,10 @@ execute_core(const Command* command, Driver driver) /* How long is the final command line for the MS system? */ command_line_length += cur; - for (i = 0; i < command->rt_argc; ++i) + 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_argv[i]); /* room for each 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. */ @@ -363,11 +405,11 @@ execute_core(const Command* command, Driver driver) 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_argc; ++i) { - const int arg_length = strlen(command->rt_argv[i]); + 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_argv[i]); + strcpy(command_line + cur, command->rt_args[i]); cur += arg_length; command_line[cur++] = '"'; } @@ -405,8 +447,7 @@ execute_core(const Command* command, Driver driver) #else /* __WIN32__ */ int i; - char** args = (char**) - malloc(sizeof (char*) * (command->rt_argc + command->core.argc + 2)); + 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) @@ -419,24 +460,24 @@ execute_core(const Command* command, Driver driver) 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_argc; ++i) - args[i + 1] = command->rt_argv[i]; + 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_argc + 1] = (char*) "--"; + 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_argc + i + 1] = command->core.argv[i]; - args[command->rt_argc + command->core.argc + 1] = NULL; + 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_argc + command->core.argc] = NULL; + args[command->rt_args.size() + command->core.argc] = NULL; - execv(execpath, args); + execv(execpath, args.data()); perror(strerror(errno)); return -1; #endif /* __WIN32__ */ diff --git a/src/driver/utils.h b/src/driver/utils.h index 4f973973..70b5bb85 100644 --- a/src/driver/utils.h +++ b/src/driver/utils.h @@ -42,47 +42,60 @@ # include <windows.h> #endif -namespace OpenAxiom { - -/* A list of drivers for OpenAxiom. */ -enum Driver { - unknown_driver, /* unknown driver */ - null_driver, /* do nothing */ - config_driver, /* print out configuration information */ - sman_driver, /* start Superman as master process */ - core_driver, /* start the core system as master process */ - script_driver, /* start the core system in script mode. */ - compiler_driver, /* start the core system in compiler mode. */ - execute_driver /* Execute a command. */ -}; - -/* A list of runtime support systems for OpenAxiom. */ -enum Runtime { - unknown_runtime, - gcl_runtime, /* GCL-based runtime */ - sbcl_runtime, /* SBCL-based runtime */ - clisp_runtime, /* CLISP-based runtime */ - ecl_runtime, /* ECL-based runtime */ - clozure_runtime, /* Clozure CL-based runtime */ - bemol_runtime /* Bemol-based runtime */ -}; - -/* A description of external command to be executed. */ -struct Command { - Process core; /* arguments for actual executable. */ - char** rt_argv; /* arguments to the base RT, if any. */ - int rt_argc; /* number of such arguments. */ - const char* root_dir; /* path to the OpenAxiom system. */ -}; - -const char* get_systemdir(int argc, char*[]); -const char* make_path_for(const char*, Driver); - -int execute_core(const Command*, Driver); -void build_rts_options(Command*, Driver); - -Driver preprocess_arguments(Command*, int, char**); +#include <vector> +namespace OpenAxiom { + // A list of drivers for OpenAxiom. + enum Driver { + unknown_driver, // unknown driver + null_driver, // do nothing + config_driver, // print out configuration information + sman_driver, // start Superman as master process + core_driver, // start the core system as master process + script_driver, // start the core system in script mode. + compiler_driver, // start the core system in compiler mode. + execute_driver, // Execute a command. + alien_driver // Alien driver. + }; + + // A list of runtime support systems for OpenAxiom. + enum Runtime { + unknown_runtime, + gcl_runtime, // GCL-based runtime + sbcl_runtime, // SBCL-based runtime + clisp_runtime, // CLISP-based runtime + ecl_runtime, // ECL-based runtime + clozure_runtime, // Clozure CL-based runtime + bemol_runtime // Bemol-based runtime + }; + + // Command line arguments. + // When non empty, this vector really is of length one more than + // what size() reports, as it is always null-terminated, to comply + // with POSIX-style operating system requirements. + struct Arguments : std::vector<char*> { + explicit Arguments(int n = 0); + int size() const; + void allocate(int); + char* const* data() const; + }; + + // A description of external command to be executed. + struct Command { + Process core; // arguments for actual executable. + Arguments rt_args; // arguments to the base RT, if any. + const char* root_dir; // path to the OpenAxiom system. + const char* exec_path; // path to the program to execute. + Command(); + }; + + const char* get_systemdir(int argc, char*[]); + const char* make_path_for(const char*, Driver); + + int execute_core(const Command*, Driver); + void build_rts_options(Command*, Driver); + + Driver preprocess_arguments(Command*, int, char**); } #endif /* OPENAXIOM_UTILS_INCLUDED */ |