NEURON
ivocmain.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <../nrnpython/nrnpython_config.h>
3 
5 
6 #if !HAVE_IV
7 #define Session void
8 int hoc_main1(int, const char**, const char**);
9 void hoc_main1_init(const char*, const char**);
10 #endif
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #if HAVE_UNISTD_H
15 #include <unistd.h>
16 #if !defined(__APPLE__)
17 extern char** environ;
18 #else
19 #include <crt_externs.h>
20 #endif
21 #endif
22 
23 #if HAVE_IV
24 #ifdef WIN32
25 #include <IV-Win/MWlib.h>
26 void iv_display_scale(float);
27 #endif
28 
29 #include <ivstream.h>
30 #include <assert.h>
31 #include "ivoc.h"
32 #include "idraw.h"
33 #include <InterViews/style.h>
34 #endif
35 #include <OS/string.h>
36 #include "string.h"
37 #include "oc2iv.h"
38 #include "nrnmpi.h"
39 
40 #if defined(IVX11_DYNAM)
41 #include <IV-X11/ivx11_dynam.h>
42 #endif
43 
44 #if defined(carbon)
45 #undef MAC
46 #endif
47 
48 #if 1
49 void pr_profile();
50 #define PR_PROFILE pr_profile();
51 #else
52 #define PR_PROFILE /**/
53 #endif
54 /*****************************************************************************/
55 
56 #if HAVE_IV
57 static PropertyData properties[] = {{"*gui", "sgimotif"},
58  {"*PopupWindow*overlay", "true"},
59  {"*PopupWindow*saveUnder", "on"},
60  {"*TransientWindow*saveUnder", "on"},
61  {"*background", "#ffffff"},
62  {"*brush_width", "0"},
63  {"*double_buffered", "on"},
64  {"*flat", "#aaaaaa"},
65 #ifdef MINGW
66  {"*font", "*Arial*bold*--12*"},
67  {"*MenuBar*font", "*Arial*bold*--12*"},
68  {"*MenuItem*font", "*Arial*bold*--12*"},
69 #endif
70  {"*foreground", "#000000"},
71  {"*synchronous", "off"},
72  {"*malloc_debug", "on"},
73 
74  {"*Scene_background", "#ffffff"},
75  {"*Scene_foreground", "#000000"},
76  {"*FieldEditor*background", "#ffffff"},
77  //{"*background", "#cfffff"},
78  {"*default_brush", "0"},
79  {"*view_margin", ".25"},
80  {"*pwm_dismiss_button", "Iconify"},
81  {"*dismiss_button", "Close"},
82  {"*use_transient_windows", "yes"},
83  {"*nrn_library", " $(NEURONHOME)/lib"},
84  {"*view_pick_epsilon", "2"},
85  {"*pwm_canvas_height", "120"},
86  {"*pwm_paper_height", "11"},
87  {"*pwm_paper_width", "8.5"},
88  {"*pwm_paper_resolution", ".5"},
89  {"*pwm_pixel_resolution", "0"},
90  {"*window_manager_offset_x", "5."},
91  {"*window_manager_offset_y", "26."},
92  {"*pwm_print_file_filter", "*.ps"},
93  {"*pwm_idraw_file_filter", "*.id"},
94  {"*pwm_ascii_file_filter", "*"},
95  {"*pwm_save_file_filter", "*.ses"},
96  {"*pwm_idraw_prologue", "$(NEURONHOME)/lib/prologue.id"},
97  {"*pwm_postscript_filter", "sed 's;/Adobe-;/;'"},
98  {"*SlowSlider*autorepeatStart", "0."},
99  {"*scene_print_border", "1"},
100  {"*radioScale", ".9"},
101  {"*stepper_size", "20."},
102  {"*xvalue_field_size_increase", "10."},
103  {"*xvalue_format", "%.5g"},
104  {"*graph_axis_default", "0"},
105  {"*shape_scale_file", "$(NEURONHOME)/lib/shape.cm2"},
106  {"*shape_quadedge", "0"},
107  {"*CBWidget_ncolor", "10"},
108  {"*CBWidget_nbrush", "10"},
109  {"*units_on_flag", "on"},
110  {"*NFRAME", "0"}, // see src/oc/code.cpp for the default value
111  {"*NSTACK", "0"}, // see src/oc/code.cpp for the default value
112  {"*Py_NoSiteFlag", "0"},
113  {"*python", "off"},
114  {"*nopython", "off"},
115  {"*err_dialog", "off"},
116  {"*banner", "on"},
117  {"*pyexe", ""},
118  {NULL}};
119 
120 static OptionDesc options[] = {{"-dismissbutton", "*dismiss_button", OptionValueImplicit, "Close"},
121  {"-extrapipeinput", "*extrapipeinput", OptionValueNext},
122  {"-dll", "*nrnmechdll", OptionValueNext},
123  {"-showwinio", "*showwinio", OptionValueImplicit, "on"},
124  {"-hidewinio", "*showwinio", OptionValueImplicit, "off"},
125  {"-isatty", "*isatty", OptionValueImplicit, "1"},
126  {"-notatty", "*isatty", OptionValueImplicit, "-1"},
127  {"-neosim", "*neosim", OptionValueImplicit, "on"},
128  {"-bbs_nhost", "*bbs_nhost", OptionValueNext},
129  {"-NSTACK", "*NSTACK", OptionValueNext},
130  {"-NFRAME", "*NFRAME", OptionValueNext},
131  {"--version", "*print_nrn_version", OptionValueImplicit, "on"},
132  {"-python", "*python", OptionValueImplicit, "on"},
133  {"-nopython", "*nopython", OptionValueImplicit, "on"},
134  {"-pyexe", "*pyexe", OptionValueNext},
135  {"-Py_NoSiteFlag", "*Py_NoSiteFlag", OptionValueImplicit, "1"},
136  {"-nobanner", "*banner", OptionValueImplicit, "off"},
137 #if defined(WIN32)
138  {"-mswin_scale", "*mswin_scale", OptionValueNext},
139 #endif
140  {NULL}};
141 #endif // HAVE_IV
142 
143 extern int hoc_obj_run(const char*, Object*);
144 extern int nrn_istty_;
145 extern char* nrn_version(int);
146 extern int nrn_nobanner_;
147 extern void hoc_final_exit();
148 void ivoc_final_exit();
149 #if (defined(NRNMECH_DLL_STYLE) || defined(WIN32))
150 extern const char* nrn_mech_dll;
151 #endif
152 #if defined(USE_PYTHON)
153 int nrn_nopython;
154 extern int use_python_interpreter;
155 extern int (*p_nrnpython_start)(int);
156 char* nrnpy_pyexe;
157 #endif
158 
159 /*****************************************************************************/
160 // exported initialized data so shared libraries can have assert pure-text
161 #if HAVE_IV
162 int Oc::refcnt_ = 0;
163 Session* Oc::session_ = 0;
165 ostream* OcIdraw::idraw_stream = 0;
166 #endif
167 /*****************************************************************************/
168 extern void ivoc_cleanup();
169 #if OCSMALL
170 static char* ocsmall_argv[] = {0, "difus.hoc"};
171 #endif
172 #if defined(WIN32) && HAVE_IV
173 extern HWND hCurrWnd;
174 #endif
175 
176 
177 extern void setneuronhome(const char*);
178 extern const char* neuron_home;
179 int hoc_xopen1(const char* filename, const char* rcs);
180 extern int units_on_flag_;
181 extern double hoc_default_dll_loaded_;
182 extern int hoc_print_first_instance;
184 
185 #if !defined(MINGW) && !MAC
186 extern void setneuronhome(const char*) {
187  neuron_home = getenv("NEURONHOME");
188 }
189 #endif
190 
191 #if 0
192 void penv() {
193  int i;
194  for (i=0; environ[i]; ++i) {
195  printf("%p %s\n", environ[i], environ[i]);
196  }
197 }
198 #endif
199 
200 #if DARWIN || defined(__linux__)
201 #include "nrnwrap_dlfcn.h"
202 #include <string>
203 
204 /* It is definitely now the case on mac and I think sometimes the case on
205 linux that dlopen needs a full path to the file. A path to the binary
206 is not necessarily sufficent as one may launch python or nrniv on the
207 target machine and the lib folder cannot be derived from the location of
208 the python executable.This seems to be robust if nrn_version is inside a
209 shared library.
210 The return value ends with a '/' and if the prefix cannot be determined
211 the return value is "".
212 */
213 const char* path_prefix_to_libnrniv() {
214  static char* path_prefix_to_libnrniv_ = NULL;
215  if (!path_prefix_to_libnrniv_) {
216  Dl_info info;
217  int rval = dladdr((void*) nrn_version, &info);
218  std::string name;
219  if (rval) {
220  if (info.dli_fname) {
221  name = info.dli_fname;
222  if (info.dli_fname[0] == '/') { // likely full path
223  size_t last_slash = name.rfind("/");
224  path_prefix_to_libnrniv_ = strndup(name.c_str(), last_slash + 1);
225  path_prefix_to_libnrniv_[last_slash + 1] = '\0';
226  }
227  }
228  }
229  if (!path_prefix_to_libnrniv_) {
230  path_prefix_to_libnrniv_ = strdup("");
231  }
232  }
233  return path_prefix_to_libnrniv_;
234 }
235 #endif // DARWIN || defined(__linux__)
236 
237 #if MAC
238 #include <string.h>
239 #include <sioux.h>
240 extern bool mac_load_dll(const char*);
241 void mac_open_doc(const char* s) {
242  // only chdir and load dll on the first opendoc
243  static bool done = false;
244  char cs[256];
245  strncpy(cs, s, 256);
246  char* cp = strrchr(cs, ':');
247  if (cp && !done) {
248  *cp = '\0';
249  if (chdir(cs) == 0) {
250  done = true;
251  printf("current directory is \"%s\"\n", cs);
252  if (mac_load_dll("nrnmac.dll")) {
254  }
255  }
256  }
257  hoc_xopen1(s, 0);
258 }
259 void mac_open_app() {
260  hoc_xopen1(":lib:hoc:macload.hoc", 0);
261 }
262 #endif
263 
264 #ifdef MAC
265 #pragma export on
266 #endif
267 
268 int ivocmain(int, const char**, const char**);
269 int ivocmain_session(int, const char**, const char**, int start_session);
270 int (*p_neosim_main)(int, const char**, const char**);
271 extern int nrn_global_argc;
272 extern const char** nrn_global_argv;
274 extern int nrn_is_python_extension;
275 extern void hoc_nrnmpi_init();
276 #if NRNMPI_DYNAMICLOAD
277 extern void nrnmpi_stubs();
278 extern char* nrnmpi_load(int is_python);
279 #endif
280 
281 // some things are defined in libraries earlier than they are used so...
282 #include <nrnisaac.h>
283 static void force_load() {
284  if (always_false) {
285  nrnisaac_new();
286  }
287 }
288 
289 #ifdef MINGW
290 // see iv/src/OS/directory.cpp
291 #include <sys/stat.h>
292 static bool isdir(const char* p) {
293  struct stat st;
294  bool b = stat(p, &st) == 0 && S_ISDIR(st.st_mode);
295  // printf("isdir %s returns %d\n", p, b);
296  return b;
297 }
298 #endif
299 
300 #ifdef MAC
301 #pragma export off
302 #endif
303 
304 // in case we are running without IV then get some important args this way
305 static bool nrn_optarg_on(const char* opt, int* argc, char** argv);
306 static char* nrn_optarg(const char* opt, int* argc, char** argv);
307 static int nrn_optargint(const char* opt, int* argc, char** argv, int dflt);
308 
309 static bool nrn_optarg_on(const char* opt, int* pargc, const char** argv) {
310  char* a;
311  int i;
312  for (i = 0; i < *pargc; ++i) {
313  if (strcmp(opt, argv[i]) == 0) {
314  *pargc -= 1;
315  for (; i < *pargc; ++i) {
316  argv[i] = argv[i + 1];
317  }
318  // printf("nrn_optarg_on %s return true\n", opt);
319  return true;
320  }
321  }
322  return false;
323 }
324 
325 static const char* nrn_optarg(const char* opt, int* pargc, const char** argv) {
326  const char* a;
327  int i;
328  for (i = 0; i < *pargc - 1; ++i) {
329  if (strcmp(opt, argv[i]) == 0) {
330  a = argv[i + 1];
331  *pargc -= 2;
332  for (; i < *pargc; ++i) {
333  argv[i] = argv[i + 2];
334  }
335  // printf("nrn_optarg %s return %s\n", opt, a);
336  return a;
337  }
338  }
339  return 0;
340 }
341 
342 static int nrn_optargint(const char* opt, int* pargc, const char** argv, int dflt) {
343  const char* a;
344  int i;
345  i = dflt;
346  a = nrn_optarg(opt, pargc, argv);
347  if (a) {
348  sscanf(a, "%d", &i);
349  }
350  // printf("nrn_optargint %s return %d\n", opt, i);
351  return i;
352 }
353 
354 #if USENRNJAVA
355 void nrn_InitializeJavaVM();
356 #endif
357 
358 #if 0 // for debugging
359 void prargs(const char* s, int argc, const char** argv) {
360  int i;
361  printf("%s argc=%d\n", s, argc);
362  for (i=0; i < argc; ++i) {
363  printf(" %d |%s|\n", i, argv[i]);
364  }
365 }
366 #endif
367 
369 #if NRNMPI
370  if (!nrnmpi_use) {
371 #if NRNMPI_DYNAMICLOAD
372  nrnmpi_stubs();
373  const char* pmes = nrnmpi_load(1);
374  if (pmes) {
375  printf("%s\n", pmes);
376  }
377 #endif
378 
379  char** foo = (char**) nrn_global_argv;
380  nrnmpi_init(2, &nrn_global_argc, &foo);
381  // if (nrnmpi_myid == 0) {printf("hoc_nrnmpi_init called nrnmpi_init\n");}
382  // turn off gui for all ranks > 0
383  if (nrnmpi_myid_world > 0) {
384  hoc_usegui = 0;
386  }
387  }
388 #endif
389  hoc_ret();
390  hoc_pushx(0.0);
391 }
392 
393 /**
394  * Main entrypoint function into the HOC interpeter
395  *
396  * This function simply calls ivocmain_session with the \c start_session = 1.
397  *
398  * \note This is part of NEURON's public interface
399  *
400  * \note \c env argument should not be used as it might become invalid
401  *
402  * \param argc argument count as found in C/C++ \c main functions
403  * \param argv argument vector as found in C/C++ \c main functions
404  * \param env environment variable array as optionally found in main functions.
405  * \return 0 on success, otherwise error code.
406  */
407 int ivocmain(int argc, const char** argv, const char** env) {
408  return ivocmain_session(argc, argv, env, 1);
409 }
410 /**
411  * This used to be ivocmain, the main entrypoint to the HOC interpreter
412  *
413  * ivocmain_session parses command line argument, calls of initialization
414  * functions and drops into an interactive HOC session.
415  * This function is called for example by the "real main" in \c nrnmain.cpp ,
416  * but can be also called from other external user applications that use
417  * NEURON.
418  * Additionally to the original implemenation a new parameter \c start_session
419  * was introduced to control whether an interactive HOC session shoudl be started
420  * or simply NEURON and all data structures be initialized and control returned
421  * to the caller.
422  *
423  * \note \c env argument should not be used as it might become invalid
424  *
425  * \param argc argument count as found in C/C++ \c main functions
426  * \param argv argument vector as found in C/C++ \c main functions
427  * \param env environment variable array as optionally found in main functions.
428  * \param start_session set to 1 for default behavior (drop into interactive HOC session
429  * otherwise set to 0. If set to 1, but compiled with python support this function will
430  * still directly return (since in that mode we don't need an interactive HOC session
431  * either.
432  * \return 0 on success, otherwise error code.
433  */
434 int ivocmain_session(int argc, const char** argv, const char** env, int start_session) {
435  // third arg should not be used as it might become invalid
436  // after putenv or setenv. Instead, if necessary use
437  // #include <unistd.h>
438  // extern char** environ;
439  int i;
440  // prargs("at beginning", argc, argv);
441  force_load();
443  // https://en.cppreference.com/w/cpp/language/main_function, note that argv is
444  // of length argc + 1 and argv[argc] is null.
445  nrn_global_argv = new const char*[argc + 1];
446  for (i = 0; i < argc + 1; ++i) {
447  nrn_global_argv[i] = argv[i];
448  }
450  if (nrn_optarg_on("-help", &argc, argv) || nrn_optarg_on("-h", &argc, argv)) {
451  printf(
452  "nrniv [options] [fileargs]\n\
453  options:\n\
454  -dll filename dynamically load the linked mod files.\n\
455  -h print this help message\n\
456  -help print this help message\n\
457  -isatty unbuffered stdout, print prompt when waiting for stdin\n\
458  -mpi launched by mpirun or mpiexec, in parallel environment\n\
459  -mswin_scale float scales gui on screen\n\
460  -music launched as a process of the MUlti SImulator Coordinator\n\
461  -NSTACK integer size of stack (default 1000)\n\
462  -NFRAME integer depth of function call nesting (default 200)\n\
463  -nobanner do not print startup banner\n\
464  -nogui do not send any gui info to screen\n\
465  -notatty buffered stdout and no prompt\n\
466  -python Python is the interpreter\n\
467  -pyexe path Python to use if python (or python3 fallback) not right.\n\
468  -nopython Do not initialize Python\n\
469  -Py_NoSiteFlag Set Py_NoSiteFlag=1 before initializing Python\n\
470  -realtime For hard real-time simulation for dynamic clamp\n\
471  --version print version info\n\
472  and all InterViews and X11 options\n\
473  fileargs: any number of following\n\
474  - input from stdin til ^D (end of file)\n\
475  -c \"statement\" execute next statement\n\
476  filename execute contents of filename\n\
477 ");
478  exit(0);
479  }
480  if (nrn_optarg_on("--version", &argc, argv)) {
481  printf("%s\n", nrn_version(1));
482  exit(0);
483  }
484  if (nrn_optarg_on("-nobanner", &argc, argv)) {
485  nrn_nobanner_ = 1;
486  }
487  if (nrn_optarg_on("-Py_NoSiteFlag", &argc, argv)) {
488  nrnpy_nositeflag = 1;
489  }
490 
492  hoc_usegui = 1;
493  if (nrn_optarg_on("-nogui", &argc, argv)) {
494  hoc_usegui = 0;
496  }
497  if (nrnmpi_numprocs > 1) {
498  hoc_usegui = 0;
500  }
501 #if NRNMPI
502  if (nrnmpi_use) {
503  hoc_usegui = 0;
505  }
506 #else
507 
508  // check if user is trying to use -mpi or -p4 when it was not
509  // enabled at build time. If so, issue a warning.
510 
511  int b;
512  b = 0;
513  for (i = 0; i < argc; ++i) {
514  if (strncmp("-p4", (argv)[i], 3) == 0) {
515  b = 1;
516  break;
517  }
518  if (strcmp("-mpi", (argv)[i]) == 0) {
519  b = 1;
520  break;
521  }
522  }
523  if (b) {
524  printf(
525  "Warning: detected user attempt to enable MPI, but MPI support was disabled at build "
526  "time.\n");
527  }
528 
529 #endif
530 
531 #if defined(IVX11_DYNAM)
532  if (hoc_usegui && ivx11_dyload()) {
533  hoc_usegui = 0;
535  }
536 #endif
537 
538 #if NRN_MUSIC
539  nrn_optarg_on("-music", &argc, argv);
540 #else
541  if (nrn_optarg_on("-music", &argc, argv)) {
542  printf("Warning: attempt to enable MUSIC but MUSIC support was disabled at build time.\n");
543  }
544 #endif
545 
546 #if !HAVE_IV
547  hoc_usegui = 0;
549 #endif
550  int our_argc = argc;
551  const char** our_argv = argv;
552  int exit_status = 0;
553  Session* session = NULL;
554 #if !defined(MINGW) && !defined(MAC)
555  // Gary Holt's first pass at this was:
556  //
557  // Set the NEURONHOME environment variable. This should override any setting
558  // in the environment, so someone doesn't accidently use data files from an
559  // old version of neuron.
560  //
561  // But I have decided to use the environment variable if it exists
562  neuron_home = getenv("NEURONHOME");
563  if (!neuron_home) {
564 #if defined(HAVE_PUTENV)
565  // the only reason the following is static is to prevent valgrind
566  // from complaining it is a memory leak.
567  static char* buffer = new char[strlen(NEURON_DATA_DIR) + 12];
568  sprintf(buffer, "NEURONHOME=%s", NEURON_DATA_DIR);
569  putenv(buffer);
570  neuron_home = NEURON_DATA_DIR;
571 #elif defined(HAVE_SETENV)
572  setenv("NEURONHOME", NEURON_DATA_DIR, 1);
573  neuron_home = NEURON_DATA_DIR;
574 #else
575 #error "I don't know how to set environment variables."
576 // Maybe in this case the user will have to set it by hand.
577 #endif
578  // putenv and setenv may invalidate env but we no longer
579  // use it so following should not be needed
580 #if 0
581 #if HAVE_UNISTD_H && !defined(__APPLE__)
582  env = environ;
583 #endif
584 #if defined(__APPLE__)
585  env = (*_NSGetEnviron());
586 #endif
587 #endif
588  }
589 
590 #else // Not unix:
591  neuron_home = getenv("NEURONHOME");
592  if (!neuron_home) {
593  setneuronhome((argc > 0) ? argv[0] : 0);
594  }
595  if (!neuron_home) {
596 #if defined(WIN32) && HAVE_IV
597  MessageBox(0,
598  "No NEURONHOME environment variable.",
599  "NEURON Incomplete Installation",
600  MB_OK);
601 #else
602  neuron_home = ".";
603  fprintf(stderr,
604  "Warning: no NEURONHOME environment variable-- setting\
605  to %s\n",
606  neuron_home);
607 #endif
608  }
609 #endif // !unix.
610 
611 #if HAVE_IV
612 #if OCSMALL
613  our_argc = 2;
614  our_argv = new char*[2];
615  our_argv[0] = "Neuron";
616  our_argv[1] = ":lib:hoc:macload.hoc";
617  session = new Session("NEURON", our_argc, our_argv, options, properties);
618 #else
619 #if MAC
620  our_argc = 1;
621  our_argv = new char*[1];
622  our_argv[0] = "Neuron";
623  session = new Session("NEURON", our_argc, our_argv, options, properties);
624  SIOUXSettings.asktosaveonclose = false;
625 #else
626 #if defined(WIN32) || carbon
627  IFGUI
628  session = new Session("NEURON", our_argc, (char**) our_argv, options, properties);
629  ENDGUI
630 #else
631  IFGUI
632  if (getenv("DISPLAY")) {
633  session = new Session("NEURON", our_argc, (char**) our_argv, options, properties);
634  } else {
635  fprintf(stderr,
636  "Warning: no DISPLAY environment variable.\
637 \n--No graphics will be displayed.\n");
638  hoc_usegui = 0;
639  }
640  ENDGUI
641 #endif
642 #endif
643  char* nrn_props;
644  nrn_props = new char[strlen(neuron_home) + 20];
645  if (session) {
646  sprintf(nrn_props, "%s/%s", neuron_home, "lib/nrn.defaults");
647 #ifdef WIN32
648  FILE* f;
649  if ((f = fopen(nrn_props, "r")) != (FILE*) 0) {
650  fclose(f);
651  session->style()->load_file(String(nrn_props), -5);
652  } else {
653 #ifdef MINGW
654  sprintf(nrn_props, "%s/%s", neuron_home, "lib/nrn.def");
655 #else
656  sprintf(nrn_props, "%s\\%s", neuron_home, "lib\\nrn.def");
657 #endif
658  if ((f = fopen(nrn_props, "r")) != (FILE*) 0) {
659  fclose(f);
660  session->style()->load_file(String(nrn_props), -5);
661  } else {
662  char buf[256];
663  sprintf(buf, "Can't load NEURON resources from %s[aults]", nrn_props);
664  printf("%s\n", buf);
665  }
666  }
667 #else
668  session->style()->load_file(String(nrn_props), -5);
669 #endif
670 #if !MAC
671  char* h = getenv("HOME");
672  if (h) {
673  sprintf(nrn_props, "%s/%s", h, ".nrn.defaults");
674  session->style()->load_file(String(nrn_props), -5);
675  }
676 #endif
677  }
678  delete[] nrn_props;
679 
680 #endif /*OCSMALL*/
681 
682  if (session) {
683  session->style()->find_attribute("NSTACK", hoc_nstack);
684  session->style()->find_attribute("NFRAME", hoc_nframe);
685  IFGUI
686  if (session->style()->value_is_on("err_dialog")) {
688  }
689  ENDGUI
690  } else
691 #endif // HAVE_IV
692  {
693  hoc_nstack = nrn_optargint("-NSTACK", &our_argc, our_argv, 0);
694  hoc_nframe = nrn_optargint("-NFRAME", &our_argc, our_argv, 0);
695  }
696 
697 #if defined(USE_PYTHON)
698  nrn_nopython = 0;
700 #if HAVE_IV
701  if (session) {
702  if (session->style()->value_is_on("nopython")) {
703  nrn_nopython = 1;
704  }
705  String str;
706  if (session->style()->find_attribute("pyexe", str)) {
707  nrnpy_pyexe = strdup(str.string());
708  }
709  } else
710 #endif
711  {
712  if (nrn_optarg_on("-nopython", &our_argc, our_argv)) {
713  nrn_nopython = 1;
714  }
715  const char* buf = nrn_optarg("-pyexe", &our_argc, our_argv);
716  if (buf) {
717  nrnpy_pyexe = strdup(buf);
718  }
719  }
720  }
721 #endif // USE_PYTHON
722 
723 #if defined(WIN32) && HAVE_IV
724  IFGUI
725  double scale = 1.;
726  int pw = GetSystemMetrics(SM_CXVIRTUALSCREEN);
727  if (pw < 1100) {
728  scale = 1200. / double(pw);
729  }
730  session->style()->find_attribute("mswin_scale", scale);
731  iv_display_scale(float(scale));
732  ENDGUI
733 #endif
734 
735  // just eliminate from arg list
736  nrn_optarg_on("-mpi", &our_argc, our_argv);
737 
738 #if (defined(NRNMECH_DLL_STYLE) || defined(WIN32))
739  String str;
740 #if HAVE_IV
741  if (session) {
742  if (session->style()->find_attribute("nrnmechdll", str)) {
743  nrn_mech_dll = str.string();
744  }
745  } else
746 #endif
747  { // if running without IV.
748  nrn_mech_dll = nrn_optarg("-dll", &our_argc, our_argv);
749  // may be duplicated since nrnbbs adds all args to special
750  // which is often a script that adds a -dll arg
751  nrn_optarg("-dll", &our_argc, our_argv);
752  }
753 #if NRNMPI
754  if (nrnmpi_use && !nrn_mech_dll) {
755  // for heterogeneous clusters, mpirun allows different programs
756  // but not different arguments. So the -dll is insufficient.
757  // Therefore we check to see if it makes sense to load
758  // a dll from the usual location.
759  // Actually this is done by default in src/nrnoc/init.cpp
760  }
761 #endif
762 
763 #endif // NRNMECH_DLL_STYLE
764 
765 
766 #if HAVE_IV
767  if (session) {
768  long i;
769  if (session->style()->find_attribute("isatty", i)) {
770  nrn_istty_ = i;
771  }
772  } else
773 #endif
774  {
775  nrn_istty_ = nrn_optarg_on("-isatty", &our_argc, our_argv);
776  if (nrn_istty_ == 0) {
777  nrn_istty_ = nrn_optarg_on("-notatty", &our_argc, our_argv);
778  if (nrn_istty_ == 1) {
779  nrn_istty_ = -1;
780  }
781  }
782  }
783 
784 #if HAVE_IV
785  if (session && session->style()->value_is_on("units_on_flag")) {
786  units_on_flag_ = 1;
787  }
788  Oc oc(session, our_argv[0], env);
789 #else
790  hoc_main1_init(our_argv[0], env);
791 #endif // HAVE_IV
792 
793 #if USENRNJAVA
794  nrn_InitializeJavaVM();
795 #endif
796 #if OCSMALL
797  if (argc == 1) {
798  ocsmall_argv[0] = our_argv[0];
799  exit_status = oc.run(2, ocsmall_argv);
800  } else
801 #endif
802 #if defined(USE_PYTHON)
803 #if HAVE_IV
804  if (session && session->style()->value_is_on("python")) {
805  use_python_interpreter = 1;
806  }
807 #endif
808  if (nrn_optarg_on("-python", &our_argc, our_argv)) {
809  use_python_interpreter = 1;
810  }
811 
813  return 0;
814  }
815  // printf("p_nrnpython_start = %p\n", p_nrnpython_start);
816  if (p_nrnpython_start) {
817  (*p_nrnpython_start)(1);
818  }
819  if (use_python_interpreter && !p_nrnpython_start) {
820  fprintf(stderr, "Python not available\n");
821  exit(1);
822  }
823 #endif
824  if (start_session) {
825 #if HAVE_IV
826  exit_status = oc.run(our_argc, our_argv);
827 #else
828  exit_status = hoc_main1(our_argc, our_argv, env);
829 #endif
830  } else {
831  return 0;
832  }
833 #if HAVE_IV
834  if (session && session->style()->value_is_on("neosim")) {
835  if (p_neosim_main) {
836  (*p_neosim_main)(argc, argv, env);
837  } else {
838  printf(
839  "neosim not available.\nModify nrn/src/nrniv/Imakefile and remove "
840  "nrniv/$CPU/netcvode.o\n");
841  }
842  }
843 #endif
844  PR_PROFILE
845 #if defined(USE_PYTHON)
846  if (use_python_interpreter) {
847  // process the .py files and an interactive interpreter
848  if (p_nrnpython_start && (*p_nrnpython_start)(2) != 0) {
849  // We encountered an error when processing the -c argument or Python
850  // script given on the commandline.
851  exit_status = 1;
852  }
853  }
854  if (p_nrnpython_start) {
855  (*p_nrnpython_start)(0);
856  }
857 #endif
858  hoc_final_exit();
859  ivoc_final_exit();
860  return exit_status;
861 }
862 
864 #if NRNMPI
866 #endif
867 }
868 
869 extern "C" {
870 extern double* getarg(int i);
871 extern int ifarg(int);
872 } // extern "C"
873 
874 extern void hoc_ret(), hoc_pushx(double);
875 
877 #if HAVE_IV
878  IFGUI
879  void single_event_run();
880 
882  ENDGUI
883 #endif
884  hoc_ret();
885  hoc_pushx(1.);
886 }
887 
888 #if !HAVE_IV
890  return 1;
891 }
893 #endif
#define OptionDesc
Definition: _defines.h:193
#define PropertyData
Definition: _defines.h:213
#define String
Definition: enter-scope.h:48
Definition: ivoc.h:36
int run(int argc, const char **argv)
static Session * session_
Definition: ivoc.h:82
static int refcnt_
Definition: ivoc.h:81
static HandleStdin * handleStdin_
Definition: ivoc.h:83
static ostream * idraw_stream
Definition: idraw.h:85
Definition: string.h:34
const char * string() const
Definition: string.h:139
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
DLFCN_EXPORT int dladdr(const void *addr, Dl_info *info)
Definition: dlfcn.c:731
char buf[512]
Definition: init.cpp:13
void ivoc_final_exit()
Definition: ivocmain.cpp:863
void hoc_ret()
int hoc_usegui
Definition: hoc.cpp:148
char * nrn_mech_dll
Definition: hoc_init.cpp:405
#define IFGUI
Definition: hocdec.h:372
#define ENDGUI
Definition: hocdec.h:373
static char * env[]
Definition: inithoc.cpp:233
static int argc
Definition: inithoc.cpp:53
static char ** argv
Definition: inithoc.cpp:54
int nrn_err_dialog_active_
Definition: ivoc.cpp:39
bool mac_load_dll(const char *name)
Definition: ivocmac.cpp:152
void setneuronhome(const char *)
Definition: ivocmain.cpp:186
int nrnpy_nositeflag
Definition: ivocmain.cpp:183
int ivocmain_session(int, const char **, const char **, int start_session)
This used to be ivocmain, the main entrypoint to the HOC interpreter.
Definition: ivocmain.cpp:434
int ivocmain(int, const char **, const char **)
Main entrypoint function into the HOC interpeter.
Definition: ivocmain.cpp:407
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:322
const char * neuron_home
Definition: hoc_init.cpp:404
void hoc_final_exit()
Definition: hoc.cpp:1131
int(* p_neosim_main)(int, const char **, const char **)
Definition: ivocmain.cpp:270
int units_on_flag_
Definition: code2.cpp:17
double * getarg(int i)
Definition: code.cpp:1630
int nrn_global_argc
Definition: nrnpython.cpp:34
long hoc_nstack
Definition: ivocmain.cpp:4
void hoc_nrnmpi_init()
Definition: ivocmain.cpp:368
int nrn_istty_
Definition: hoc.cpp:882
void ivoc_cleanup()
Definition: ocnoiv1.cpp:17
int nrn_nobanner_
Definition: init.cpp:106
#define Session
Definition: ivocmain.cpp:7
int hoc_print_first_instance
Definition: hoc_oop.cpp:38
int nrn_is_python_extension
Definition: fileio.cpp:842
static char * nrn_optarg(const char *opt, int *argc, char **argv)
void pr_profile()
Definition: hoc.cpp:123
char * nrn_version(int)
Definition: nrnversion.cpp:27
void hoc_notify_value()
Definition: ivocmain.cpp:892
static int nrn_optargint(const char *opt, int *argc, char **argv, int dflt)
int ifarg(int)
Definition: code.cpp:1581
void hoc_main1_init(const char *, const char **)
Definition: hoc.cpp:887
void hoc_single_event_run()
Definition: ivocmain.cpp:876
const char ** nrn_global_argv
Definition: nrnpython.cpp:35
#define PR_PROFILE
Definition: ivocmain.cpp:50
int hoc_main1(int, const char **, const char **)
Definition: hoc.cpp:983
void hoc_pushx(double)
static bool nrn_optarg_on(const char *opt, int *argc, char **argv)
double hoc_default_dll_loaded_
Definition: hoc_init.cpp:402
int always_false
Definition: ivocmain.cpp:273
int hoc_xopen1(const char *filename, const char *rcs)
Definition: fileio.cpp:207
int run_til_stdin()
Definition: ivocmain.cpp:889
static void force_load()
Definition: ivocmain.cpp:283
long hoc_nframe
Definition: ivocmain.cpp:4
char * getenv(const char *s)
Definition: macprt.cpp:67
#define i
Definition: md1redef.h:12
char * name
Definition: init.cpp:16
static int nrnmpi_use
Definition: multisplit.cpp:48
#define printf
Definition: mwprefix.h:26
#define putenv
Definition: mwprefix.h:37
#define fprintf
Definition: mwprefix.h:30
void single_event_run()
static List * info
#define nrn_assert(ex)
Definition: nrnassrt.h:53
size_t p
void * nrnisaac_new(void)
Definition: nrnisaac.cpp:12
void nrnmpi_init(int nrnmpi_under_nrncontrol, int *pargc, char ***pargv)
Definition: nrnmpi.cpp:58
void nrnmpi_terminate()
Definition: nrnmpi.cpp:180
int nrnmpi_numprocs
int nrnmpi_myid_world
int nrn_nopython
int(* p_nrnpython_start)(int)
char * nrnpy_pyexe
static double done(void *v)
Definition: ocbbs.cpp:282
FILE * fopen()
#define NULL
Definition: sptree.h:16
Definition: hocdec.h:227
Definition: dlfcn.h:72