~ubuntu-branches/ubuntu/feisty/libctl/feisty

« back to all changes in this revision

Viewing changes to base/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2002-04-17 10:36:45 UTC
  • Revision ID: james.westby@ubuntu.com-20020417103645-29vomjspk4yf4olw
Tags: upstream-2.1
ImportĀ upstreamĀ versionĀ 2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libctl: flexible Guile-based control files for scientific software 
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, Steven G. Johnson
 
3
 *
 
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.
 
6
 *
 
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.
 
11
 * 
 
12
 * Steven G. Johnson can be contacted at stevenj@alum.mit.edu.
 
13
 */
 
14
 
 
15
/**************************************************************************/
 
16
 
 
17
/* main program for a simulation that uses libctl.
 
18
 
 
19
   You should not need to modify this file.
 
20
 
 
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).
 
26
*/
 
27
 
 
28
/**************************************************************************/
 
29
 
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
#include <guile/gh.h>
 
34
 
 
35
#include <ctl-io.h>
 
36
 
 
37
/* define a global "verbose" variable set by the --verbose command-line opt. */
 
38
int verbose = 0;
 
39
 
 
40
/**************************************************************************/
 
41
 
 
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)
 
48
{
 
49
     int i;
 
50
 
 
51
     *continue_run = 1;
 
52
     *spec_file_loaded = 0;
 
53
 
 
54
     for (i = 1; i < argc; ++i) {
 
55
          if (argv[i][0] != '-')
 
56
               break;
 
57
          if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-V")) {
 
58
               char *guile_vers;
 
59
#ifdef VERSION_STRING
 
60
               /* print version string, if defined: */
 
61
               printf(VERSION_STRING);
 
62
#endif
 
63
#ifdef LIBCTL_VERSION
 
64
               printf("\nUsing libctl %s", LIBCTL_VERSION);
 
65
#else
 
66
               printf("\nUsing libctl");
 
67
#endif
 
68
               guile_vers = gh_scm2newstr(gh_eval_str("(version)"), NULL);
 
69
               printf(" and Guile %s.\n", guile_vers);
 
70
               free(guile_vers);
 
71
               *continue_run = 0;
 
72
          }
 
73
          else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
 
74
               verbose = 1;
 
75
          else if (!strncmp(argv[i], "--spec-file=", strlen("--spec-file="))) {
 
76
               ctl_include(argv[i] + strlen("--spec-file="));
 
77
               *spec_file_loaded = 1;
 
78
          }
 
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"
 
82
                      "options:\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]);
 
91
               *continue_run = 0;
 
92
          }
 
93
          else {
 
94
               fprintf(stderr, "Unknown option %s!  Use the --help option"
 
95
                       " for more information.\n", argv[i]);
 
96
               exit(EXIT_FAILURE);
 
97
          }
 
98
     }
 
99
 
 
100
     return i;
 
101
}
 
102
 
 
103
/**************************************************************************/
 
104
 
 
105
#ifdef HAVE_CTL_HOOKS
 
106
static int ctl_stop_hook_called = 0;
 
107
 
 
108
extern void ctl_start_hook(int *argc, char **argv[]);
 
109
extern void ctl_stop_hook(void);
 
110
#endif
 
111
 
 
112
#ifdef HAVE_CTL_EXPORT_HOOK
 
113
extern void ctl_export_hook(void);
 
114
#endif
 
115
 
 
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. */
 
119
 
 
120
void main_entry(int argc, char *argv[])
 
121
{
 
122
  int i;
 
123
  boolean spec_file_loaded, continue_run;
 
124
  SCM interactive;
 
125
 
 
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();
 
130
 
 
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);
 
135
 
 
136
  /* Export the subplex minimization routine: */
 
137
  gh_new_procedure ("subplex", subplex_scm, 7, 0, 0);
 
138
 
 
139
#ifdef HAVE_CTL_EXPORT_HOOK
 
140
  ctl_export_hook();
 
141
#endif
 
142
 
 
143
  /* load include.scm if it was given at compile time */
 
144
#ifdef INCLUDE_SCM
 
145
  ctl_include(INCLUDE_SCM);
 
146
#endif
 
147
 
 
148
  /* load ctl.scm if it was given at compile time */
 
149
#ifdef CTL_SCM
 
150
  ctl_include(CTL_SCM);
 
151
#endif
 
152
 
 
153
  i = handle_args(argc, argv, &spec_file_loaded, &continue_run);
 
154
 
 
155
  if (!continue_run)
 
156
       goto done;
 
157
 
 
158
  /* load the specification file if it was given at compile time,
 
159
     and if it wasn't specified on the command-line: */
 
160
#ifdef SPEC_SCM
 
161
  if (!spec_file_loaded)
 
162
       ctl_include(SPEC_SCM);
 
163
#endif
 
164
 
 
165
  /* define any variables and load any scheme files specified on the
 
166
     command line: */
 
167
  for (; i < argc; ++i) {
 
168
    if (strchr(argv[i],'=')) {
 
169
      char *eq;
 
170
      char *definestr = (char*) malloc(sizeof(char) * (strlen("(define ") + 
 
171
                                                       strlen(argv[i]) + 2));
 
172
      if (!definestr) {
 
173
           fprintf(stderr, __FILE__ ": out of memory!\n");
 
174
           exit(EXIT_FAILURE);
 
175
      }
 
176
      strcpy(definestr,"(define ");
 
177
      strcat(definestr,argv[i]);
 
178
      strcat(definestr,")");
 
179
      eq = strchr(definestr,'=');
 
180
      *eq = ' ';
 
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,'=');
 
186
           *eq = 0;
 
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");
 
190
                exit(EXIT_FAILURE);
 
191
           }
 
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);
 
197
      }
 
198
      free(definestr);
 
199
      argv[i][0] = 0;
 
200
    }
 
201
    else if (argv[i][0])
 
202
      ctl_include(argv[i]);
 
203
  }
 
204
 
 
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
 
207
     defined. */
 
208
 
 
209
  interactive = gh_lookup("interactive?");
 
210
  if (interactive != SCM_BOOL_F)
 
211
       gh_repl(argc - i, argv + i); /* skip already-handled args */
 
212
 
 
213
 done:
 
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;
 
218
  ctl_stop_hook();
 
219
#endif
 
220
}
 
221
 
 
222
int main (int argc, char *argv[])
 
223
{
 
224
#ifdef HAVE_CTL_HOOKS
 
225
  ctl_start_hook(&argc, &argv);
 
226
#endif
 
227
  gh_enter (argc, argv, main_entry);
 
228
#ifdef HAVE_CTL_HOOKS
 
229
  if (!ctl_stop_hook_called)
 
230
       ctl_stop_hook();
 
231
#endif
 
232
  return EXIT_SUCCESS;
 
233
}