1
/* libctl: flexible Guile-based control files for scientific software
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002, Steven G. Johnson
4
* This file may be used without restriction. It is in the public
5
* domain, and is NOT restricted by the terms of any GNU license.
7
* This library is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
* Lesser General Public License for more details.
12
* Steven G. Johnson can be contacted at stevenj@alum.mit.edu.
15
/**************************************************************************/
17
/* main program for a simulation that uses libctl.
19
You should not need to modify this file.
21
The resulting program will run any Scheme files that are passed
22
as parameters on the command line. It will automatically load
23
ctl.scm and the specification file if the CTL_SCM and SPEC_SCM
24
preprocessor symbols are defined to the corresponding filenames
25
(e.g. see the accompanying Makefile).
28
/**************************************************************************/
37
/* define a global "verbose" variable set by the --verbose command-line opt. */
40
/**************************************************************************/
42
/* Handle command-line args, returning first arg not handled.
43
Also return, in spec_file_loaded, whether we have loaded
44
the specifications file due to a command-line arg. Also return,
45
in continue_run, whether or not to continue the run. */
46
int handle_args(int argc, char *argv[],
47
boolean *spec_file_loaded, boolean *continue_run)
52
*spec_file_loaded = 0;
54
for (i = 1; i < argc; ++i) {
55
if (argv[i][0] != '-')
57
if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-V")) {
60
/* print version string, if defined: */
61
printf(VERSION_STRING);
64
printf("\nUsing libctl %s", LIBCTL_VERSION);
66
printf("\nUsing libctl");
68
guile_vers = gh_scm2newstr(gh_eval_str("(version)"), NULL);
69
printf(" and Guile %s.\n", guile_vers);
73
else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
75
else if (!strncmp(argv[i], "--spec-file=", strlen("--spec-file="))) {
76
ctl_include(argv[i] + strlen("--spec-file="));
77
*spec_file_loaded = 1;
79
else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
80
char *slash = strrchr(argv[0], '/');
81
printf("Usage: %s [options] [definitions] [ctl files]\n"
83
" --help, -h: this help\n"
84
" --version, -V: display version information\n"
85
" --verbose, -v: enable verbose output\n"
86
" --spec-file=<file>: use <file> for spec. file\n"
87
"definitions: assignments of the form "
88
"<variable>=<value>\n"
89
"ctl files: zero or more Scheme/ctl files to execute\n",
90
slash ? slash + 1 : argv[0]);
94
fprintf(stderr, "Unknown option %s! Use the --help option"
95
" for more information.\n", argv[i]);
103
/**************************************************************************/
105
#ifdef HAVE_CTL_HOOKS
106
static int ctl_stop_hook_called = 0;
108
extern void ctl_start_hook(int *argc, char **argv[]);
109
extern void ctl_stop_hook(void);
112
#ifdef HAVE_CTL_EXPORT_HOOK
113
extern void ctl_export_hook(void);
116
/* Main program. Start up Guile, declare functions, load any
117
scripts passed on the command-line, and drop into interactive
118
mode if read-input-vars was never called. */
120
void main_entry(int argc, char *argv[])
123
boolean spec_file_loaded, continue_run;
126
/* Notify Guile of functions that we are making callable from Scheme.
127
These are defined in the specifications file, from which the
128
export_external_functions routine is automatically generated. */
129
export_external_functions();
131
/* Also export the read_input_vars and write_output_vars routines
132
that are automatically generated from the specifications file: */
133
gh_new_procedure ("read-input-vars", read_input_vars, 0, 0, 0);
134
gh_new_procedure ("write-output-vars", write_output_vars, 0, 0, 0);
136
/* Export the subplex minimization routine: */
137
gh_new_procedure ("subplex", subplex_scm, 7, 0, 0);
139
#ifdef HAVE_CTL_EXPORT_HOOK
143
/* load include.scm if it was given at compile time */
145
ctl_include(INCLUDE_SCM);
148
/* load ctl.scm if it was given at compile time */
150
ctl_include(CTL_SCM);
153
i = handle_args(argc, argv, &spec_file_loaded, &continue_run);
158
/* load the specification file if it was given at compile time,
159
and if it wasn't specified on the command-line: */
161
if (!spec_file_loaded)
162
ctl_include(SPEC_SCM);
165
/* define any variables and load any scheme files specified on the
167
for (; i < argc; ++i) {
168
if (strchr(argv[i],'=')) {
170
char *definestr = (char*) malloc(sizeof(char) * (strlen("(define ") +
171
strlen(argv[i]) + 2));
173
fprintf(stderr, __FILE__ ": out of memory!\n");
176
strcpy(definestr,"(define ");
177
strcat(definestr,argv[i]);
178
strcat(definestr,")");
179
eq = strchr(definestr,'=');
181
gh_eval_str(definestr);
182
{ /* add the name of the defined variable to params-set-list */
183
char *remember_define;
184
strcpy(definestr,argv[i]);
185
eq = strchr(definestr,'=');
187
remember_define = (char*) malloc(sizeof(char) * (strlen("(set! params-set-list (cons (quote x) params-set-list))") + strlen(definestr)));
188
if (!remember_define) {
189
fprintf(stderr, __FILE__ ": out of memory!\n");
192
strcpy(remember_define, "(set! params-set-list (cons (quote ");
193
strcat(remember_define, definestr);
194
strcat(remember_define, ") params-set-list))");
195
gh_eval_str(remember_define);
196
free(remember_define);
202
ctl_include(argv[i]);
205
/* Check if we should run an interactive prompt. We do this if
206
either the Scheme variable "interactive?" is true, or if it is not
209
interactive = gh_lookup("interactive?");
210
if (interactive != SCM_BOOL_F)
211
gh_repl(argc - i, argv + i); /* skip already-handled args */
214
#ifdef HAVE_CTL_HOOKS
215
/* Note that the stop hook will never be called if we are in
216
interactive mode, because gh_repl calls exit(). Oh well. */
217
ctl_stop_hook_called = 1;
222
int main (int argc, char *argv[])
224
#ifdef HAVE_CTL_HOOKS
225
ctl_start_hook(&argc, &argv);
227
gh_enter (argc, argv, main_entry);
228
#ifdef HAVE_CTL_HOOKS
229
if (!ctl_stop_hook_called)