aboutsummaryrefslogtreecommitdiff
path: root/src/driver
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2008-02-10 04:48:39 +0000
committerdos-reis <gdr@axiomatics.org>2008-02-10 04:48:39 +0000
commit6b365f926f1f0430c34498392e1dddbff126bc48 (patch)
treebdbc548cea2b0968863d9695bbdfc1732b16c3c5 /src/driver
parent06e82157a75ebb6f14dae6a76a9e3a2b883b2c7a (diff)
downloadopen-axiom-6b365f926f1f0430c34498392e1dddbff126bc48.tar.gz
Add support for batch processing.
Diffstat (limited to 'src/driver')
-rw-r--r--src/driver/Makefile.in15
-rw-r--r--src/driver/main.c163
-rw-r--r--src/driver/utils.c281
-rw-r--r--src/driver/utils.h79
4 files changed, 391 insertions, 147 deletions
diff --git a/src/driver/Makefile.in b/src/driver/Makefile.in
index 0a1ba801..f64cfab0 100644
--- a/src/driver/Makefile.in
+++ b/src/driver/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, Gabriel Dos Reis.
+# Copyright (C) 2007-2008, Gabriel Dos Reis.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -30,11 +30,11 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-bin_PROGRAMS = axiom$(EXEEXT)
+bin_PROGRAMS = open-axiom$(EXEEXT)
-axiom_SOURCES = main.c
+open_axiom_SOURCES = main.c utils.c
-axiom_objects = $(axiom_SOURCES:.c=.lo)
+open_axiom_objects = $(open_axiom_SOURCES:.c=.lo)
.PHONY: all all-ax all-driver
@@ -55,8 +55,11 @@ stamp: $(bin_PROGRAMS)
-DOPENAXIOM_ROOT_DIRECTORY="\"$(open_axiom_installdir)\"" \
$(axiom_includes) $<
-axiom$(EXEEXT): $(axiom_objects)
- $(LINK) -o $@ $<
+utils.lo: utils.h
+main.lo: utils.h
+
+open-axiom$(EXEEXT): $(open_axiom_objects)
+ $(LINK) -o $@ $(open_axiom_objects)
mostlyclean-local:
@rm -f $(axiom_objects)
diff --git a/src/driver/main.c b/src/driver/main.c
index 313f9115..82e51384 100644
--- a/src/driver/main.c
+++ b/src/driver/main.c
@@ -37,57 +37,11 @@
as the seesion manager. */
-#include "axiom-c-macros.h"
+#include "utils.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef __WIN32__
-# include <windows.h>
-#endif
-
-/* 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
-
-/* 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
-
-/* Return a path to the running system, either as specified on command
- line through --system=, or as specified at configuration time. */
-static 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;
-}
#define OPENAXIOM_GLOBAL_ENV "AXIOM"
@@ -114,106 +68,33 @@ publish_systemdir(const char* dir)
}
-/* Return a path for PROG specified as a relative path to PREFIX. */
-static const char*
-make_path_for(const char* prefix, const char* prog)
-{
- const int prefix_length = strlen(prefix);
- char* execpath = (char*) malloc(prefix_length + strlen(prog) + 1);
- strcpy(execpath, prefix);
- strcpy(execpath + prefix_length, prog);
- return execpath;
-}
-
-
int
main(int argc, char* argv[])
{
- const char* root_dir = get_systemdir(argc, argv);
- const char* execpath =
- make_path_for(root_dir,
- OPENAXIOM_USE_SMAN ?
- OPENAXIOM_SMAN_PATH : OPENAXIOM_CORE_PATH);
-#ifdef __WIN32__
- char* command_line;
- int cur = strlen(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. */
-
- command_line_length += cur;
- for (i = 1; i < argc; ++i)
- command_line_length += 1 /* blank char as separator */
- + strlen(argv[i]); /* room for each argument */
-
- /* Don't forget room for the doubledash string. */
- command_line_length += sizeof("--") - 1;
-
- command_line = (char*) malloc(command_line_length + 1);
-
- strcpy(command_line, argv[0]);
- command_line[cur++] = ' ';
-
- /* Now start arguments to the core executable. */
- command_line[cur++] = '-';
- command_line[cur++] = '-';
-
- /* Concatenate the arguments into a single string. */
- for (i = 1; i < argc; ++i) {
- const int arg_length = strlen(argv[i]);
- command_line[cur++] = ' ';
- /* Note that strcpy will terminate `command_line' with a NUL
- character, and since the next iteration will write the
- blank precisely where the NUL character is, the whole command
- line string will be a proper C-style string when the loop
- normally exits. */
- strcpy(command_line + cur, argv[i]);
- cur += arg_length;
- }
-
- publish_systemdir(root_dir);
- 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, GetLastError());
+ openaxiom_command command = { };
+ openaxiom_driver driver =
+ openaxiom_preprocess_arguments(&command, argc, argv);
+
+ switch (driver) {
+ case openaxiom_core_driver:
+ case openaxiom_script_driver:
+ case openaxiom_compiler_driver:
+ return openaxiom_execute_core(&command, driver);
+
+ case openaxiom_sman_driver:
+ break;
+
+ default:
abort();
}
- WaitForSingleObject(procInfo.hProcess, INFINITE);
- GetExitCodeProcess(procInfo.hProcess, &status);
- CloseHandle(procInfo.hThread);
- CloseHandle(procInfo.hProcess);
- return status;
-
+
+#ifdef __WIN32__
+ /* Should not happen on MS platforms. */
+ abort();
#else /* __WIN32__ */
- int i;
- char** args = (char**) malloc(sizeof (char*) * (argc + 2));
- publish_systemdir(root_dir);
-
- /* Pretend that we are still running the OpenAxiom driver, even if
- it is actually the session manager or the core executable running.
- We don't want to expose implementation details to users. */
- args[0] = argv[0];
- /* If we are running the core executable, we need to insert a
- doubledash to indicate beginning of arguments. The session manager
- does not need that temporary necessary obfuscation, and will
- be confused. */
- if (!OPENAXIOM_USE_SMAN)
- args[1] = "--";
- for (i = 1; i < argc; ++i)
- args[i + !OPENAXIOM_USE_SMAN] = argv[i];
- args[argc + !OPENAXIOM_USE_SMAN] = NULL;
-
- execv(execpath, args);
+ publish_systemdir(command.root_dir);
+ execv(openaxiom_make_path_for(command.root_dir, openaxiom_sman_driver),
+ argv);
perror(strerror(errno));
return -1;
#endif /* __WIN32__ */
diff --git a/src/driver/utils.c b/src/driver/utils.c
new file mode 100644
index 00000000..04148015
--- /dev/null
+++ b/src/driver/utils.c
@@ -0,0 +1,281 @@
+/*
+ Copyright (C) 2008, 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 "axiom-c-macros.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "utils.h"
+#include <stdio.h>
+
+/* 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
+
+/* 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|"
+
+
+/* Return a path to the running system, either as specified on command
+ line through --system=, or as specified at configuration time. */
+const char*
+openaxiom_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_name(openaxiom_driver driver)
+{
+ switch (driver) {
+ case openaxiom_sman_driver:
+ return OPENAXIOM_SMAN_PATH;
+
+ case openaxiom_script_driver:
+ case openaxiom_compiler_driver:
+ case openaxiom_core_driver:
+ return OPENAXIOM_CORE_PATH;
+
+ default:
+ abort();
+ }
+}
+
+
+/* Return a path for PROG specified as a relative path to PREFIX. */
+const char*
+openaxiom_make_path_for(const char* prefix, openaxiom_driver driver)
+{
+ const int prefix_length = strlen(prefix);
+ const char* prog = get_driver_name(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
+openaxiom_build_rts_options(openaxiom_command* command,
+ openaxiom_driver driver)
+{
+ switch (driver) {
+ case openaxiom_sman_driver:
+ case openaxiom_unknown_driver:
+ break;
+
+ case openaxiom_core_driver:
+ break;
+
+ case openaxiom_compiler_driver:
+ case openaxiom_script_driver:
+ switch (OPENAXIOM_BASE_RTS) {
+ case openaxiom_gcl_runtime:
+ command->rt_argc = 3;
+ command->rt_argv = (char **)
+ malloc(command->rt_argc * sizeof (char*));
+ command->rt_argv[0] = "-batch";
+ command->rt_argv[1] = "-eval";
+ command->rt_argv[2] = "(" OPENAXIOM_LISP_CORE_ENTRY_POINT ")";
+ break;
+
+ default:
+ abort();
+ }
+ break;
+
+ default:
+ abort();
+ }
+}
+
+#ifdef __WIN32__
+# define OPENAXIOM_DEFAULT_DRIVER openaxiom_core_driver
+#elif OPENAXIOM_USE_SMAN
+# define OPENAXIOM_DEFAULT_DRIVER openaxiom_sman_driver
+#else
+# define OPENAXIOM_DEFAULT_DRIVER openaxiom_unknown_driver
+#endif
+
+
+/* Determine driver to be used for executing `command'. */
+openaxiom_driver
+openaxiom_preprocess_arguments(openaxiom_command* command,
+ int argc, char** argv)
+{
+ int i;
+ openaxiom_driver driver = OPENAXIOM_DEFAULT_DRIVER;
+
+ command->core_argc = argc;
+ command->core_argv = argv;
+ command->root_dir = openaxiom_get_systemdir(argc, argv);
+ for (i = 1; i < argc; ++i)
+ if (strcmp(argv[i], "--script") == 0)
+ driver = openaxiom_script_driver;
+ else if(strcmp(argv[i], "--compile") == 0)
+ driver = openaxiom_compiler_driver;
+
+ openaxiom_build_rts_options(command, driver);
+ return driver;
+}
+
+
+
+
+/* Execute the Core Executable as described by `command'. On
+ POSIX systems, this is a non-return function on success.
+ See execv(). */
+int
+openaxiom_execute_core(const openaxiom_command* command,
+ openaxiom_driver driver)
+{
+ const char* execpath =
+ openaxiom_make_path_for(command->root_dir, 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 < comand->rt_argc; ++i)
+ command_line_length += 1 /* blank char as separator */
+ + strlen(command->rt_argv[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 < comand->core_argc; ++i)
+ command_line_length += 1 + 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]);
+ command_line[cur++] = ' ';
+ for (i = 0; i < command->rt_argc; ++i) {
+ const int arg_length = strlen(command->rt_argv[i]);
+ command_line[cur++] = ' ';
+ /* Note that strcpy will terminate `command_line' with a NUL
+ character, and since the next iteration will write the
+ blank precisely where the NUL character is, the whole command
+ line string will be a proper C-style string when the loop
+ normally exits. */
+ strcpy(command_line + cur, command->rt_argv[i]);
+ cur += arg_length;
+ }
+ 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++] = ' ';
+ strcpy(command_line + cur, command->core_argv[i]);
+ cur += arg_length;
+ }
+
+ 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, GetLastError());
+ abort();
+ }
+ WaitForSingleObject(procInfo.hProcess, INFINITE);
+ GetExitCodeProcess(procInfo.hProcess, &status);
+ CloseHandle(procInfo.hThread);
+ CloseHandle(procInfo.hProcess);
+ return status;
+
+#else /* __WIN32__ */
+ int i;
+ char** args = (char**)
+ malloc(sizeof (char*) * (command->rt_argc + command->core_argc + 2));
+ args[0] = command->core_argv[0];
+ for (i = 0; i < command->rt_argc; ++i)
+ args[i + 1] = command->rt_argv[i];
+ if (command->core_argc > 1) {
+ /* Insert a doubledash to indicate beginning of arguments. */
+ args[command->rt_argc + 1] = "--";
+ 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;
+ }
+ else
+ args[command->rt_argc + command->core_argc] = NULL;
+
+ execv(execpath, args);
+ perror(strerror(errno));
+ return -1;
+#endif /* __WIN32__ */
+}
diff --git a/src/driver/utils.h b/src/driver/utils.h
new file mode 100644
index 00000000..41d7c345
--- /dev/null
+++ b/src/driver/utils.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2008, 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.
+*/
+
+#ifndef OPENAXIOM_UTILS_INCLUDED
+#define OPENAXIOM_UTILS_INCLUDED
+
+#include "axiom-c-macros.h"
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef __WIN32__
+# include <windows.h>
+#endif
+
+/* A list of drivers for OpenAxiom. */
+typedef enum openaxiom_driver {
+ openaxiom_unknown_driver,
+ openaxiom_sman_driver,
+ openaxiom_core_driver,
+ openaxiom_script_driver,
+ openaxiom_compiler_driver
+} openaxiom_driver;
+
+/* A list of runtime support systems for OpenAxiom. */
+typedef enum openaxiom_runtime {
+ openaxiom_unknown_runtime,
+ openaxiom_gcl_runtime,
+ openaxiom_sbcl_runtime,
+ openaxiom_clisp_runtime,
+ openaxiom_ecl_runtime,
+ openaxiom_bemol_runtime
+} openaxiom_runtime;
+
+/* A description of external command to be executed. */
+typedef struct openaxiom_command {
+ char** core_argv; /* arguments for the actual executable. */
+ int core_argc; /* number of such arguments. */
+ 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. */
+} openaxiom_command;
+
+const char* openaxiom_get_systemdir(int argc, char*[]);
+const char* openaxiom_make_path_for(const char*, openaxiom_driver);
+
+int openaxiom_execute_core(const openaxiom_command*, openaxiom_driver);
+void openaxiom_build_rts_options(openaxiom_command*, openaxiom_driver);
+
+#endif /* OPENAXIOM_UTILS_INCLUDED */