aboutsummaryrefslogtreecommitdiff
path: root/src/driver
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2010-11-28 23:57:59 +0000
committerdos-reis <gdr@axiomatics.org>2010-11-28 23:57:59 +0000
commitdea4d75caba3466cdc8595d333c31a5393912c69 (patch)
treeafd0a96708651f2d6b483705f85c80588e7906c0 /src/driver
parenta53a740a2a1cb6cbfa58cc79caedd4e947ff1ca0 (diff)
downloadopen-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.c103
-rw-r--r--src/driver/utils.c121
-rw-r--r--src/driver/utils.h93
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 */