NEURON
hoc.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #include "../nrnpython/nrnpython_config.h"
4 #include "hoc.h"
5 #include "hocstr.h"
6 #include "equation.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <math.h>
11 #include <errno.h>
12 #include "parse.hpp"
13 #include "hocparse.h"
14 #include "ocfunc.h"
15 #include "ocmisc.h"
16 #include "nrnmpi.h"
17 #include "nrnfilewrap.h"
18 #if defined(__GO32__)
19 #include <dos.h>
20 #include <go32.h>
21 #endif
22 #include "../nrniv/backtrace_utils.h"
23 
24 
25 /* for eliminating "ignoreing return value" warnings. */
27 
28 /* only set in ivoc */
31 
32 #if defined(USE_PYTHON)
33 int use_python_interpreter = 0;
34 int (*p_nrnpython_start)(int);
36 #endif
38 int (*p_nrnpy_pyrun)(const char* fname);
39 
40 #if 0 /* defined by cmake if rl_event_hook is not available */
41 #define use_rl_getc_function
42 #endif
43 
44 #if carbon || defined(MINGW)
45 #include <pthread.h>
46 extern int stdin_event_ready();
47 #endif
48 
49 #if HAVE_FEENABLEEXCEPT
50 #define NRN_FLOAT_EXCEPTION 1
51 #else
52 #define NRN_FLOAT_EXCEPTION 0
53 #endif
54 
55 #if NRN_FLOAT_EXCEPTION
56 #if !defined(__USE_GNU)
57 #define __USE_GNU
58 #endif
59 #include <fenv.h>
60 #define FEEXCEPT (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW)
61 static void matherr1(void) {
62  /* above gives the signal but for some reason fegetexcept returns 0 */
63  switch (fegetexcept()) {
64  case FE_DIVBYZERO:
65  fprintf(stderr, "Floating exception: Divide by zero\n");
66  break;
67  case FE_INVALID:
68  fprintf(stderr, "Floating exception: Invalid (no well defined result\n");
69  break;
70  case FE_OVERFLOW:
71  fprintf(stderr, "Floating exception: Overflow\n");
72  break;
73  }
74 }
75 #endif
76 
78 
79 int nrn_feenableexcept_ = 0; // 1 if feenableexcept(FEEXCEPT) is successful
80 
82  int result = -2; // feenableexcept does not exist.
84 #if NRN_FLOAT_EXCEPTION
85  if (ifarg(1) && chkarg(1, 0., 1.) == 0.) {
86  result = fedisableexcept(FEEXCEPT);
87  } else {
88  result = feenableexcept(FEEXCEPT);
89  nrn_feenableexcept_ = (result == -1) ? 0 : 1;
90  }
91 #endif
92  hoc_ret();
93  hoc_pushx((double) result);
94 }
95 
96 #if 0
97 /* performance debugging when gprof is inadequate */
98 #include <sys/time.h>
99 static unsigned long usec[30];
100 static unsigned long oldusec[30];
101 static struct timeval tp;
102 void start_profile(int i){
103  gettimeofday(&tp, 0);
104  oldusec[i] = tp.tv_usec;
105 }
106 void add_profile(int i) {
107  gettimeofday(&tp, 0);
108  if (tp.tv_usec > oldusec[i]) {
109  usec[i] += tp.tv_usec - oldusec[i];
110  }
111 }
112 void pr_profile(void) {
113  int i;
114  for (i=0; i < 30; ++i) {
115  if (usec[i]) {
116  printf("sec[%d]=%g\n", i, ((double)usec[i])/1000000.);
117  }
118  }
119 }
120 #else
121 void start_profile(int i) {}
122 void add_profile(int i) {}
123 void pr_profile(void) {}
124 #endif
125 
126 #ifdef MAC
127 #define READLINE 0
128 #endif
129 
130 #if OCSMALL
131 #define READLINE 0
132 #endif
133 
134 #ifndef READLINE
135 #define READLINE 1
136 #endif
137 
138 #if READLINE
139 extern "C" {
140 extern char* readline(const char* prompt);
141 extern void rl_deprep_terminal(void);
142 extern void add_history(const char*);
143 }
144 #endif
145 
149 #if 1
150 /* no longer necessary to distinguish signed from unsigned since EOF
151  never stored in a buffer.
152  */
153 #define CHAR char
154 #else
155 #if - 1 == '\377'
156 #define CHAR char
157 #else
158 #define CHAR signed char
159 #endif
160 #endif
161 /* buffers will grow automatically if an input line exceeds the following*/
162 #define TMPBUFSIZE 512
163 #define CBUFSIZE 512
166 const char* hoc_promptstr;
167 static CHAR* cbuf;
170 
171 extern char* RCS_hoc_version;
172 extern char* RCS_hoc_date;
173 extern char* neuron_home;
174 extern int hoc_print_first_instance;
175 
176 #define EPS hoc_epsilon
177 /*
178 used to be a FILE* but had fopen problems when 128K cores on BG/P
179 tried to fopen the same file for reading at once.
180 */
181 NrnFILEWrap* fin; /* input file pointer */
182 
183 #include <ctype.h>
184 const char* progname; /* for error messages */
185 int lineno;
186 
187 #if HAVE_EXECINFO_H
188 #include <execinfo.h>
189 #endif
190 #include <signal.h>
191 #include <setjmp.h>
192 static int control_jmpbuf = 0; /* don't change jmp_buf if being controlled */
193 jmp_buf begin;
194 static int hoc_oc_jmpbuf;
195 static jmp_buf hoc_oc_begin;
196 int intset; /* safer interrupt handling */
197 int indef;
198 const char* infile; /* input file name */
199 extern size_t hoc_xopen_file_size_;
200 extern char* hoc_xopen_file_;
201 const char** gargv; /* global argument list */
202 int gargc;
203 static int c = '\n'; /* global for use by warning() */
204 
205 #if defined(WIN32) || MAC
206 void set_intset() {
207  intset++;
208 }
209 #endif
210 #ifdef WIN32
211 extern void hoc_win32_cleanup();
212 #endif
213 
214 static int follow(int expect, int ifyes, int ifno); /* look ahead for >=, etc. */
215 static int Getc(NrnFILEWrap* fp);
216 static void unGetc(int c, NrnFILEWrap* fp);
217 static int backslash(int c);
218 
219 extern "C" void nrn_exit(int i) {
220 #if defined(WIN32)
221  printf("NEURON exiting abnormally, press return to quit\n");
222  fgetc(stdin);
223 #endif
224  exit(i);
225 }
226 
227 #if LINDA
228 
229 int hoc_retreat_flag;
230 #define RETREAT_SIGNAL SIGHUP
231 
232 static RETSIGTYPE retreat_handler(int sig) /* catch interrupt */
233 {
234  /*ARGSUSED*/
235  if (hoc_retreat_flag++) {
236  /* never managed the first one properly */
237  nrn_exit(1);
238  }
239  if (!lookup("linda_retreat")) {
240  hoc_retreat_flag = 0;
241  /* user did not give us a safe retreat so it would be nice */
242  /* to take up later exactly at this point */
243  nrn_exit(1);
244  }
245  IGNORE(signal(RETREAT_SIGNAL, retreat_handler));
246 }
247 
248 void hoc_retreat(void) {
249  hoc_obj_run("linda_retreat()\n", nullptr);
250  exit(0);
251 }
252 
253 #endif
254 
255 #if defined(WIN32) || defined(MAC)
256 #define HAS_SIGPIPE 0
257 #else
258 #define HAS_SIGPIPE 1
259 #endif
260 #if HAS_SIGPIPE
261 /*ARGSUSED*/
262 static RETSIGTYPE sigpipe_handler(int sig) {
263  fprintf(stderr, "writing to a broken pipe\n");
264  signal(SIGPIPE, sigpipe_handler);
265 }
266 #endif
267 
268 int getnb(void) /* get next non-white character */
269 {
270  int c;
271 
272  /*EMPTY*/
273  while ((c = Getc(fin)) == ' ' || c == '\t') {
274  ;
275  }
276  return c;
277 }
278 
279 /* yylex modified to return -3 when at end of cbuf. The parser can
280  return and take up where it left off later. Supported by modification
281  of bison.simple to allow event driven programming.
282 */
283 #define YYNEEDMORE -3
284 /* for now we say comments or strings that span lines on stdin are in error */
285 #if 0
286 #define INCOMMENT 1;
287 #define INSTRING 2;
288 static int lexstate = 0;
289 #endif
290 /* sometimes is... doesn't work with -3. Hence Getc returns null and look
291  at eos to see if true.*/
292 static int eos;
293 
294 static char* optarray(char* buf) {
295  int c;
296  if ((c = Getc(fin)) == '[') {
297  char* s = buf + strlen(buf);
298  *s++ = c;
299  while (isdigit(c = Getc(fin)) && (s - buf) < 200) {
300  *s++ = c;
301  }
302  if (c == ']') {
303  *s++ = c;
304  *s = '\0';
305  } else {
306  *s = '\0';
307  acterror(buf, " not literal name[int]");
308  }
309  } else {
310  unGetc(c, fin);
311  }
312  return buf;
313 }
314 
315 int yylex(void) /* hoc6 */
316 {
317 restart: /* when no token in between comments */
318  eos = 0;
319 #if 0 /* do we really want to have several states? */
320  switch (lexstate) {
321 
322  case INCOMMENT:
323  goto incomment;
324  case INSTRING:
325  goto instring;
326  }
327 #endif
328 
329  if ((c = getnb()) == EOF) {
330  return 0;
331  }
332  if (c == '/' && follow('*', 1, 0)) /* comment */
333  {
334  while ((c = Getc(fin)) != '*' || follow('/', 0, 1)) {
335  if (c == EOF)
336  return (0);
337  /* if (c == YYNEEDMORE) {*/
338  if (eos) {
339  acterror("comment not complete", " in cbuf");
340  }
341  }
342  goto restart;
343  }
344  if (c == '.' || isdigit(c)) /* number */
345  {
346  char* npt;
347  double d;
348  IGNORE(unGetc(c, fin));
349  npt = (char*) ctp;
350  /*EMPTY*/
351  while (isdigit(c = Getc(fin))) {
352  ;
353  }
354  if (c == '.') {
355  /*EMPTY*/
356  while (isdigit(c = Getc(fin))) {
357  ;
358  }
359  }
360  if (*npt == '.' && !isdigit(npt[1])) {
361  IGNORE(unGetc(c, fin));
362  return (int) (*npt);
363  }
364  if (c == 'E' || c == 'e') {
365  if (isdigit(c = Getc(fin)) || c == '+' || c == '-') {
366  /*EMPTY*/
367  while (isdigit(c = Getc(fin))) {
368  ;
369  }
370  }
371  }
372  IGNORE(unGetc(c, fin));
373  IGNORE(sscanf(npt, "%lf", &d));
374  if (d == 0.)
375  return NUMZERO;
376  yylval.sym = install("", NUMBER, d, &p_symlist);
377  return NUMBER;
378  }
379  if (isalpha(c) || c == '_') {
380  Symbol* s;
381  char sbuf[256], *p = sbuf;
382  do {
383  if (p >= (sbuf + 255)) {
384  sbuf[255] = '\0';
385  hoc_execerror("Name too long:", sbuf);
386  }
387  *p++ = c;
388  } while ((c = Getc(fin)) != EOF && (isalnum(c) || c == '_'));
389  IGNORE(unGetc(c, fin));
390  *p = '\0';
391  if (strncmp(sbuf, "__nrnsec_0x", 11) == 0) {
392  yylval.ptr = hoc_sec_internal_name2ptr(sbuf, 1);
393  return INTERNALSECTIONNAME;
394  }
395  /* _pysec.name[int] or _pysec.name[int].name[int] where
396  [int] is optional must resolve to Section at parse time.
397  void* nrn_parsing_pysec_ is 1 to signal the beginning
398  of parsing and as a sub-dictionary pointer in case the
399  first level __psec.name[int] is the name of a cell.
400  On error or success in parse.ypp, nrn_parsing_pysec_ is
401  set back to NULL.
402  */
403  if (strcmp(sbuf, "_pysec") == 0) {
404  if (c != '.') {
405  hoc_acterror(
406  "Must be of form _pysec.secname where secname is the literal result of "
407  "nrn.Section.name() .",
408  NULL);
409  }
410  yylval.ptr = NULL;
411  nrn_parsing_pysec_ = (void*) 1;
412  return PYSEC;
413  }
414  if (nrn_parsing_pysec_) {
415  yylval.ptr = hoc_pysec_name2ptr(optarray(sbuf), 1);
416  if (nrn_parsing_pysec_ > (void*) 1) { /* there will be a second part */
417  c = Getc(fin);
418  unGetc(c, fin);
419  if (c != '.') { /* so there must be a . */
421  hoc_acterror(
422  "Must be of form _pysec.cellname.secname where cellname.secname is the "
423  "literal result of nrn.Section.name() .",
424  NULL);
425  }
426  }
427  if (yylval.ptr == NULL) {
428  return PYSECOBJ;
429  } else {
431  return PYSECNAME;
432  }
433  }
434  if ((s = lookup(sbuf)) == 0)
435  s = install(sbuf, UNDEF, 0.0, &symlist);
436  yylval.sym = s;
437  return s->type == UNDEF ? VAR : s->type;
438  }
439  if (c == '$') { /* argument? */
440  int ith;
441  int n = 0;
442  int retval = follow('o', OBJECTARG, ARG);
443  if (retval == ARG)
444  retval = follow('s', STRINGARG, ARG);
445  if (retval == ARG)
446  retval = follow('&', ARGREF, ARG);
447  ith = follow('i', 1, 0);
448  if (ith) {
449  yylval.narg = 0;
450  return retval;
451  }
452  while (isdigit(c = Getc(fin)))
453  n = 10 * n + c - '0';
454  IGNORE(unGetc(c, fin));
455  if (n == 0)
456  acterror("strange $...", (char*) 0);
457  yylval.narg = n;
458  return retval;
459  }
460  if (c == '"') /* quoted string */
461  {
462  static HocStr* sbuf;
463  char* p;
464  int n;
465  if (!sbuf) {
466  sbuf = hocstr_create(256);
467  }
468  for (p = sbuf->buf; (c = Getc(fin)) != '"'; p++) {
469  if (c == '\n' || c == EOF || c == YYNEEDMORE)
470  acterror("missing quote", "");
471  n = p - sbuf->buf;
472  if (n >= sbuf->size - 1) {
473  hocstr_resize(sbuf, n + 200);
474  p = sbuf->buf + n;
475  }
476  *p = backslash(c);
477  }
478  *p = 0;
479  yylval.sym = install("", CSTRING, 0.0, &p_symlist);
480 
481  (yylval.sym)->u.cstr = (char*) emalloc((unsigned) (strlen(sbuf->buf) + 1));
482  Strcpy((yylval.sym)->u.cstr, sbuf->buf);
483  return CSTRING;
484  }
485  switch (c) {
486  case 0: {
487  if (eos)
488  return YYNEEDMORE;
489  else
490  return 0;
491  }
492  case '>':
493  return follow('=', GE, GT);
494  case '<':
495  return follow('=', LE, LT);
496  case '!':
497  return follow('=', NE, NOT);
498 
499  case '+':
500  case '-':
501  case '*': {
502  if (follow('=', 1, 0)) {
503  yylval.narg = c;
504  return ROP;
505  } else {
506  return c;
507  }
508  }
509  case '=': {
510  if (follow('=', EQ, '=') == EQ) {
511  return EQ;
512  }
513  if (do_equation) {
514  return EQNEQ;
515  }
516  yylval.narg = 0;
517  return ROP;
518  }
519  case '|':
520  return follow('|', OR, '|');
521  case '&':
522  return follow('&', AND, '&');
523  case '\\': {
524  int i; /* continuation line if last char in line is \ */
525  i = follow('\n', 1000, '\\');
526  if (i == 1000) {
527  return yylex();
528  }
529  return i;
530  }
531  case '\r':
532  return follow('\n', '\n', '\n');
533  case '\n':
534  return '\n';
535  case '/':
536  if (follow('/', 1, 0)) {
537  while (*ctp) {
538  ++ctp;
539  }
540  return '\n';
541  } else if (follow('=', 1, 0)) {
542  yylval.narg = c;
543  return ROP;
544  } else {
545  return '/';
546  }
547  default:
548  return c;
549  }
550 }
551 
552 static int backslash(int c) { /* get next char with \'s interpreted */
553  static char transtab[] = "b\bf\fn\nr\rt\t";
554  if (c != '\\')
555  return c;
556  c = Getc(fin);
557  if (islower(c) && strchr(transtab, c))
558  return strchr(transtab, c)[1];
559  return c;
560 }
561 
562 static int follow(int expect, int ifyes, int ifno) /* look ahead for >=, etc. */
563 {
564  int c = Getc(fin);
565 
566  if (c == expect)
567  return ifyes;
568  IGNORE(unGetc(c, fin));
569  return ifno;
570 }
571 
572 void arayinstal(void) /* allocate storage for arrays */
573 {
574  int i, nsub;
575  Symbol* sp;
576 #if defined(__TURBOC__)
577  Inst* pcc; /* sometimes pop messes up pc */
578 #endif
579 
580  nsub = (pc++)->i;
581 #if defined(__TURBOC__)
582  pcc = pc;
583 #endif
584  sp = spop();
585 
586  hoc_freearay(sp);
587  sp->type = VAR;
588  sp->s_varn = 0;
589  i = hoc_arayinfo_install(sp, nsub);
590  if ((OPVAL(sp) = (double*) hoc_Ecalloc((unsigned) i, sizeof(double))) == (double*) 0) {
591  hoc_freearay(sp);
592  Fprintf(stderr, "Not enough space for array %s\n", sp->name);
593  hoc_malchk();
594  hoc_execerror("", (char*) 0);
595  }
596 #if defined(__TURBOC__)
597  pc = pcc;
598 #endif
599 }
600 
601 int hoc_arayinfo_install(Symbol* sp, int nsub) {
602  double total, subscpt;
603  int i;
605  sp->arayinfo = (Arrayinfo*) emalloc((unsigned) (sizeof(Arrayinfo) + nsub * sizeof(int)));
606  /*printf("emalloc arrayinfo at %lx\n", sp->arayinfo);*/
607  sp->arayinfo->a_varn = (unsigned*) 0;
608  sp->arayinfo->nsub = nsub;
609  sp->arayinfo->refcount = 1;
610  total = 1.;
611  while (nsub) {
612  subscpt = floor(xpop() + EPS);
613  if (subscpt <= 0.)
614  execerror("subscript < 1", sp->name);
615  total = total * subscpt;
616  sp->arayinfo->sub[--nsub] = (int) subscpt;
617  }
618  if (total > 2e9) {
619  /*
620  following gives purify uninitialized memory read and cannot work
621  around it with anything involving i. Must be a bug in purify because
622  the i=(int)total gives the UMR when it is just above this if statement.
623  but no UMR if in present location just above return.
624  if ( (double)(i = (int)total) != total) {
625  */
626  free((char*) sp->arayinfo);
627  sp->arayinfo = (Arrayinfo*) 0;
628  execerror(sp->name, ":total subscript too large");
629  }
630  if (OPARINFO(sp)) {
631  /* probably never get here */
633  }
634  OPARINFO(sp) = sp->arayinfo;
635  ++sp->arayinfo->refcount;
636  i = (int) total;
637  return i;
638 }
639 
640 void hoc_freearay(Symbol* sp) {
641  Arrayinfo** pa = &(OPARINFO(sp));
642  if (sp->type == VAR) {
644  sp->type = UNDEF;
645  }
646  free_arrayinfo(*pa);
648  sp->arayinfo = (Arrayinfo*) 0;
649  *pa = (Arrayinfo*) 0;
650 }
651 
653  if (a != (Arrayinfo*) 0) {
654  if ((--a->refcount) <= 0) {
655  if (a->a_varn != (unsigned*) 0)
656  free((char*) (a->a_varn));
657  free((char*) a);
658  /* printf("free arrayinfo at %lx\n", a);*/
659  }
660  }
661 }
662 
663 void defnonly(const char* s) { /* warn if illegal definition */
664  if (!indef)
665  acterror(s, "used outside definition");
666 }
667 
668 /* messages can turned off but the user had better check the return
669 value of oc_run()
670 */
671 static int debug_message_;
673  double x;
674  x = chkarg(1, 0., 1.);
675  debug_message_ = (int) x;
676  ret();
677  pushx(x);
678 }
679 
681 
682 /* this is possibly non-portable since it is based on the declaration in
683  setjmp.h of
684  typedef int jmp_buf[_JBLEN];
685 */
686 void (*oc_jump_target_)(); /* see ivoc/SRC/ocjump.cpp */
687 
688 
690 
691 /* what to do about partially constructed objects at hoc_execerror */
692 extern void hoc_newobj1_err();
693 
694 /** If one of the two jmp_buf is controlling the longjmp
695  * hoc_newobj1_err needs handle to know how much to unwrap the newobj1 stack.
696  **/
698  void* jmp = hoc_oc_jmpbuf ? (void*) hoc_oc_begin : (void*) begin;
699  return jmp;
700 }
701 
702 void hoc_execerror_mes(const char* s, const char* t, int prnt) { /* recover from run-time error */
703  hoc_in_yyparse = 0;
704  yystart = 1;
706  hoc_errno_check();
707 #if 0
708  hoc_xmenu_cleanup();
709 #endif
710  if (debug_message_ || prnt) {
711  warning(s, t);
712  frame_debug();
713  nrn_err_dialog(s);
714 #if defined(__GO32__)
715  {
716  extern int egagrph;
717  if (egagrph) {
718  hoc_outtext("Error:");
719  hoc_outtext(s);
720  if (t) {
721  hoc_outtext(" ");
722  hoc_outtext(t);
723  }
724  hoc_outtext("\n");
725  }
726  }
727 #endif
728  }
729  /* in case warning not called */
730  ctp = cbuf;
731  *ctp = '\0';
732 
734  hoc_newobj1_err();
735  (*oc_jump_target_)();
736  }
737 #if NRNMPI
739  nrnmpi_abort(-1);
740  }
741 #endif
743  if (fin && pipeflag == 0 && (!nrn_fw_eq(fin, stdin) || !nrn_istty_))
744  IGNORE(nrn_fw_fseek(fin, 0L, 2)); /* flush rest of file */
746  if (hoc_oc_jmpbuf) {
747  hoc_newobj1_err();
748  longjmp(hoc_oc_begin, 1);
749  }
750  hoc_newobj1_err();
751  longjmp(begin, 1);
752 }
753 
754 extern "C" void hoc_execerror(const char* s, const char* t) /* recover from run-time error */
755 {
757 }
758 
759 RETSIGTYPE onintr(int sig) /* catch interrupt */
760 {
761  /*ARGSUSED*/
762  stoprun = 1;
763  if (intset++)
764  execerror("interrupted", (char*) 0);
765  IGNORE(signal(SIGINT, onintr));
766 }
767 
768 #if DOS
769 #include <float.h>
770 #endif
771 
772 static int coredump;
773 
775  coredump = 1;
776  ret();
777  pushx(1.);
778 }
779 
780 void print_bt() {
781 #ifdef USE_BACKWARD
783 #else
784 #if HAVE_EXECINFO_H
785  const size_t nframes = 12;
786  void* frames[nframes];
787  size_t size;
788  char** bt_strings = NULL;
789  // parsed elements from stacktrace line:
790  size_t funcname_size = 256;
791  // symbol stores the symbol at which the signal was invoked
792  char* symbol = static_cast<char*>(malloc(sizeof(char) * funcname_size));
793  // the function name where the signal was invoked
794  char* funcname = static_cast<char*>(malloc(sizeof(char) * funcname_size));
795  // offset stores the relative address from the function where the signal was invoked
796  char* offset = static_cast<char*>(malloc(sizeof(char) * 10));
797  // the memory address of the function
798  void* addr = NULL;
799  // get void*'s for maximum last 16 entries on the stack
800  size = backtrace(frames, nframes);
801 
802  // print out all the frames to stderr
803  Fprintf(stderr, "Backtrace:\n");
804  // get the stacktrace as an array of strings
805  bt_strings = backtrace_symbols(frames, size);
806  if (bt_strings) {
807  size_t i;
808  // start printing at third frame to skip the signal handler and printer function
809  for (i = 2; i < size; ++i) {
810  // parse the stack frame line
811  int status = parse_bt_symbol(bt_strings[i], &addr, symbol, offset);
812  if (status) {
813  status = cxx_demangle(symbol, &funcname, &funcname_size);
814  if (status == 0) { // demangling worked
815  Fprintf(stderr, "\t%s : %s+%s\n", bt_strings[i], funcname, offset);
816  } else { // demangling failed, fallback
817  Fprintf(stderr, "\t%s : %s()+%s\n", bt_strings[i], symbol, offset);
818  }
819  } else { // could not parse, simply print the stackframe as is
820  Fprintf(stderr, "\t%s\n", bt_strings[i]);
821  }
822  }
823  free(bt_strings);
824  }
825  free(funcname);
826  free(offset);
827  free(symbol);
828 #else
829  Fprintf(stderr, "No backtrace info available.\n");
830 #endif
831 #endif
832 }
833 
834 RETSIGTYPE fpecatch(int sig) /* catch floating point exceptions */
835 {
836  /*ARGSUSED*/
837 #if DOS
838  _fpreset();
839 #endif
840 #if NRN_FLOAT_EXCEPTION
841  matherr1();
842 #endif
843  Fprintf(stderr, "Floating point exception\n");
844  print_bt();
845  if (coredump) {
846  abort();
847  }
848  signal(SIGFPE, fpecatch);
849  execerror("Floating point exception.", (char*) 0);
850 }
851 
852 #if HAVE_SIGSEGV
853 RETSIGTYPE sigsegvcatch(int sig) /* segmentation violation probably due to arg type error */
854 {
855  Fprintf(stderr, "Segmentation violation\n");
856  print_bt();
857  /*ARGSUSED*/
858  if (coredump) {
859  abort();
860  }
861  execerror("Aborting.", (char*) 0);
862 }
863 #endif
864 
865 #if HAVE_SIGBUS
866 RETSIGTYPE sigbuscatch(int sig) {
867  Fprintf(stderr, "Bus error\n");
868  print_bt();
869  /*ARGSUSED*/
870  if (coredump) {
871  abort();
872  }
873  execerror("Aborting. ", "See $NEURONHOME/lib/help/oc.help");
874 }
875 #endif
876 
877 int hoc_pid(void) {
878  return (int) getpid();
879 } /* useful for making unique temporary file names */
880 
881 /* readline should be avoided if stdin is not a terminal */
883 
885 
886 /* has got to be called first. oc can only be event driven after this returns */
887 void hoc_main1_init(const char* pname, const char** envp) {
888  extern NrnFILEWrap* frin;
889  extern FILE* fout;
890 
891  if (!hoc_xopen_file_) {
892  hoc_xopen_file_size_ = 200;
893  hoc_xopen_file_ = static_cast<char*>(emalloc(hoc_xopen_file_size_));
894  }
895  hoc_xopen_file_[0] = '\0';
896 
897  hoc_promptstr = "oc>";
898  yystart = 1;
899  lineno = 0;
900  if (hoc_main1_inited_) {
901  return;
902  }
903 
904  /* could have been forced with the -isatty option */
905  if (nrn_istty_ == 0) { /* if not set then */
906 #ifdef HAVE_ISATTY
907  nrn_istty_ = isatty(0);
908 #else
909  /* if we do not know, then assume so */
910  nrn_istty_ = 1;
911 #endif
912  }
913  if (nrn_istty_ == -1) {
914  nrn_istty_ = 0;
915  }
918  cbuf = hoc_cbufstr->buf;
919  ctp = cbuf;
921  fout = stdout;
922  if (!parallel_sub) {
923  if (!nrn_is_cable()) {
924  Fprintf(stderr, "OC INTERPRETER %s %s\n", RCS_hoc_version, RCS_hoc_date);
925  Fprintf(
926  stderr,
927  "Copyright 1992 - Michael Hines, Neurobiology Dept., DUMC, Durham, NC. 27710\n");
928  }
929  }
930  progname = pname;
931  if (setjmp(begin)) {
932  nrn_exit(1);
933  }
934 
936 
937  hoc_init();
938  initplot();
939 #if defined(__GO32__)
940  setcbrk(0);
941 #endif
942  hoc_main1_inited_ = 1;
943 }
944 
945 HocStr* hocstr_create(size_t size) {
946  HocStr* hs;
947  hs = (HocStr*) emalloc(sizeof(HocStr));
948  hs->size = size;
949  hs->buf = static_cast<char*>(emalloc(size + 1));
950  return hs;
951 }
952 
953 static CHAR* fgets_unlimited_nltrans(HocStr* s, NrnFILEWrap* f, int nltrans);
954 
956  return fgets_unlimited_nltrans(s, f, 0);
957 }
958 
960  free(hs->buf);
961  free(hs);
962 }
963 
964 void hocstr_resize(HocStr* hs, size_t n) {
965  if (hs->size < n) {
966  /*printf("hocstr_resize to %d\n", n);*/
967  hs->buf = static_cast<char*>(erealloc(hs->buf, n + 1));
968  hs->size = n;
969  }
970 }
971 
972 void hocstr_copy(HocStr* hs, const char* buf) {
973  hocstr_resize(hs, strlen(buf) + 1);
974  strcpy(hs->buf, buf);
975 }
976 
977 #ifdef MINGW
978 static int cygonce; /* does not need the '-' after a list of hoc files */
979 #endif
980 
981 static int hoc_run1(void);
982 
983 int hoc_main1(int argc, const char** argv, const char** envp) /* hoc6 */
984 {
985  int exit_status = EXIT_SUCCESS;
986 #ifdef WIN32
987  extern void hoc_set_unhandled_exception_filter();
988  hoc_set_unhandled_exception_filter();
989 #endif
990 #if 0
991  int controlled;
992 #endif
993 #if PVM
994  init_parallel(&argc, argv);
995 #endif
997 
999  hoc_main1_init(argv[0], envp);
1000 #if LINDA
1001  signal(RETREAT_SIGNAL, retreat_handler);
1002 #endif
1003 #if HAS_SIGPIPE
1004  signal(SIGPIPE, sigpipe_handler);
1005 #endif
1006 #if 0
1007  controlled = control_jmpbuf;
1008  if (!controlled) {
1009  control_jmpbuf = 1;
1010  if (setjmp(begin)) {
1011  control_jmpbuf = 0;
1012  return 1;
1013  }
1014  }
1015  if (!controlled) {
1016  control_jmpbuf = 0;
1017  }
1018 #endif
1019  gargv = argv;
1020  gargc = argc;
1021  if (argc > 2 && strcmp(argv[1], "-bbs_nhost") == 0) {
1022  /* if IV not running this may still be here */
1023  gargv += 2;
1024  gargc -= 2;
1025  }
1026  if (argc > 1 && argv[1][0] != '-') {
1027  /* first file may be a checkpoint file */
1028  extern int hoc_readcheckpoint(char*);
1029  switch (hoc_readcheckpoint(const_cast<char*>(argv[1]))) {
1030  case 1:
1031  ++gargv;
1032  --gargc;
1033  break;
1034  case 2:
1035  nrn_exit(1);
1036  break;
1037  default:
1038  break;
1039  }
1040  }
1041 
1042  if (gargc == 1) /* fake an argument list */
1043  {
1044  static const char* stdinonly[] = {"-"};
1045 
1046 #ifdef MINGW
1047  cygonce = 1;
1048 #endif
1049  gargv = stdinonly;
1050  gargc = 1;
1051  } else {
1052  ++gargv;
1053  --gargc;
1054  }
1055  while (moreinput())
1056  exit_status = hoc_run1();
1057  return exit_status;
1058 }
1059 
1060 #if carbon
1061 #include <sys/select.h>
1062 static pthread_t* inputReady_;
1063 static pthread_mutex_t inputMutex_;
1064 static pthread_cond_t inputCond_;
1065 static int inputReadyFlag_;
1066 
1067 void* inputReadyThread(void* input) {
1068  fd_set readfds;
1069  int i, j;
1070  char c;
1071  // printf("inputReadyThread started\n");
1072  // pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &j);
1073  FD_ZERO(&readfds);
1074  FD_SET(fileno(stdin), &readfds);
1075  for (;;) {
1076  i = select(1, &readfds, 0, 0, 0);
1077  pthread_testcancel();
1078  if (FD_ISSET(fileno(stdin), &readfds)) {
1079  if (!stdin_event_ready()) {
1080  // dialog is open. cannot accept input now.
1081  printf("Discarding input til Dialog is closed.\n");
1082  read(fileno(stdin), &c, 1);
1083  continue;
1084  }
1085  }
1086  pthread_mutex_lock(&inputMutex_);
1087  pthread_cond_wait(&inputCond_, &inputMutex_);
1088  pthread_mutex_unlock(&inputMutex_);
1089  }
1090  printf("inputReadyThread done\n");
1091 }
1092 #endif
1093 
1094 #ifdef MINGW
1095 static pthread_t* inputReady_;
1096 static pthread_mutex_t inputMutex_;
1097 static pthread_cond_t inputCond_;
1098 static int inputReadyFlag_;
1099 static int inputReadyVal_;
1100 extern "C" int getch();
1101 
1102 void* inputReadyThread(void* input) {
1103  int i, j;
1104  char c;
1105  // pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &j);
1106  for (;;) {
1107  pthread_testcancel();
1108 #if 0
1109  //if (kbhit()) {
1110  if (!stdin_event_ready()) {
1111  // dialog is open. cannot accept input now.
1112 printf("Discarding input til Dialog is closed.\n");
1113  read(fileno(stdin), &c, 1);
1114  continue;
1115  }
1116  } // extern "C"
1117 #endif
1118  i = getch();
1119  // printf("see %d %c\n", i, i);
1120  pthread_mutex_lock(&inputMutex_);
1121  inputReadyFlag_ = 1;
1122  inputReadyVal_ = i;
1124  pthread_cond_wait(&inputCond_, &inputMutex_);
1125  pthread_mutex_unlock(&inputMutex_);
1126  }
1127  printf("inputReadyThread done\n");
1128 }
1129 #endif
1130 
1131 void hoc_final_exit(void) {
1132  char* buf;
1133 #if defined(USE_PYTHON)
1134  if (p_nrnpython_start) {
1135  (*p_nrnpython_start)(0);
1136  }
1137 #endif
1138  bbs_done();
1140 
1141  /* Don't close the plots for the sub-processes when they finish,
1142  by default they are then closed when the master process ends */
1144 #if READLINE && !defined(MINGW) && !defined(MAC)
1146 #endif
1147  ivoc_cleanup();
1148 #ifdef WIN32
1149  hoc_win32_cleanup();
1150 #else
1151  buf = static_cast<char*>(malloc(strlen(neuron_home) + 30));
1152  if (buf) {
1153  sprintf(buf, "%s/lib/cleanup %d", neuron_home, hoc_pid());
1154  if (system(buf)) {
1155  ;
1156  } /* ignore return value */
1157  free(buf);
1158  } /* else did not call cleanup */
1159 #endif
1160 }
1161 
1162 void hoc_quit(void) {
1163 #if carbon
1164  if (0 && inputReady_) {
1165  pthread_cancel(*inputReady_);
1166  pthread_kill(*inputReady_, SIGHUP);
1167  pthread_join(*inputReady_, 0);
1168  }
1169 #endif
1170  hoc_final_exit();
1171  ivoc_final_exit();
1172 #if defined(USE_PYTHON)
1173  /* if python was launched and neuron is an extension */
1174  if (p_nrnpython_finalize) {
1175  extern int bbs_poll_;
1176  // don't want an MPI_Iprobe after MPI_Finalize if python gui
1177  // thread calls doNotify().
1178  bbs_poll_ = -1;
1179  (*p_nrnpython_finalize)();
1180  }
1181 #endif
1182  int exit_code = ifarg(1) ? int(*getarg(1)) : 0;
1183  exit(exit_code);
1184 }
1185 
1186 #ifdef MINGW
1187 static const char* double_at2space(const char* infile) {
1188  char* buf;
1189  const char* cp1;
1190  char* cp2;
1191  int replace = 0;
1192  for (cp1 = infile; *cp1; ++cp1) {
1193  if (*cp1 == '@' && cp1[1] == '@') {
1194  replace = 1;
1195  break;
1196  }
1197  }
1198  if (!replace) {
1199  return infile;
1200  }
1201  buf = static_cast<char*>(emalloc(strlen(infile) + 1));
1202  for (cp1 = infile, cp2 = buf; *cp1; ++cp1, ++cp2) {
1203  if (*cp1 == '@' && cp1[1] == '@') {
1204  *cp2 = ' ';
1205  ++cp1;
1206  } else {
1207  *cp2 = *cp1;
1208  }
1209  }
1210  *cp2 = '\0';
1211  return buf;
1212 }
1213 #endif /*MINGW*/
1214 
1215 int moreinput(void) {
1216  if (pipeflag) {
1217  pipeflag = 0;
1218  return 1;
1219  }
1220 #if defined(WIN32)
1221  /* like mswin, do not need a '-' after hoc files, but ^D works */
1222  if (gargc == 0 && cygonce == 0) {
1223  cygonce = 1;
1224  fin = nrn_fw_set_stdin();
1225  infile = 0;
1226  hoc_xopen_file_[0] = 0;
1227 #if defined(USE_PYTHON)
1228  return use_python_interpreter ? 0 : 1;
1229 #else
1230  return 1;
1231 #endif
1232  }
1233 #endif // WIN32
1234 #if MAC
1235  if (gargc == 0) {
1236  fin = nrn_fw_set_stdin();
1237  infile = 0;
1238  hoc_xopen_file_[0] = 0;
1239 #if defined(USE_PYTHON)
1240  return use_python_interpreter ? 0 : 1;
1241 #else
1242  return 1;
1243 #endif
1244  }
1245 #endif // MAC
1246  if (fin && !nrn_fw_eq(fin, stdin)) {
1248  }
1249  fin = nrn_fw_set_stdin();
1250  infile = 0;
1251  hoc_xopen_file_[0] = 0;
1252  if (gargc-- <= 0) {
1253  return 0;
1254  }
1255  infile = *gargv++;
1256 #if defined(WIN32)
1257  if (infile[0] == '"') {
1258  char* cp = strdup(infile + 1);
1259  for (++cp; *cp; ++cp) {
1260  if (*cp == '"') {
1261  *cp = '\0';
1262  break;
1263  }
1264  }
1265  infile = cp;
1266  }
1267 #endif // WIN32
1268 #ifdef MINGW
1269  /* have difficulty passing spaces within arguments from neuron.exe
1270  through the neuron.sh shell script to nrniv.exe. Therefore
1271  neuron.exe converts the ' ' to "@@" and here we need to convert
1272  it back */
1273  infile = double_at2space(infile);
1274 #endif
1275  lineno = 0;
1276 #if defined(USE_PYTHON)
1277  if (use_python_interpreter) {
1278  /* deal only with .hoc files. The hoc files are intended
1279  only for legacy code and there is no notion of stdin interaction
1280  with the hoc interpreter.
1281  */
1282  if (strlen(infile) < 4 || strcmp(infile + strlen(infile) - 4, ".hoc") != 0) {
1283  return moreinput();
1284  }
1285  }
1286 #endif
1287  if (strcmp(infile, "-") == 0) {
1288  fin = nrn_fw_set_stdin();
1289  infile = 0;
1290  hoc_xopen_file_[0] = 0;
1291  } else if (strcmp(infile, "-parallel") == 0) {
1292  /* ignore "val" as next argument */
1293  infile = *gargv++;
1294  gargc--;
1295  return moreinput();
1296  } else if (strcmp(infile, "-c") == 0) {
1297  int hpfi, err;
1298  HocStr* hs;
1299  infile = *gargv++;
1300  gargc--;
1301 #ifdef MINGW
1302  infile = double_at2space(infile);
1303 #endif
1304  hs = hocstr_create(strlen(infile) + 2);
1305  sprintf(hs->buf, "%s\n", infile);
1306  /* now infile is a hoc statement */
1307  hpfi = hoc_print_first_instance;
1308  fin = (NrnFILEWrap*) 0;
1310  err = hoc_oc(hs->buf);
1311  hoc_print_first_instance = hpfi;
1312  hocstr_delete(hs);
1313  if (err) {
1314  hoc_warning("arg not valid statement:", infile);
1315  }
1316  return moreinput();
1317  } else if (strlen(infile) > 3 && strcmp(infile + strlen(infile) - 3, ".py") == 0) {
1318  if (!p_nrnpy_pyrun) {
1319  hoc_execerror("Python not available to interpret", infile);
1320  }
1321  (*p_nrnpy_pyrun)(infile);
1322  return moreinput();
1323  } else if ((fin = nrn_fw_fopen(infile, "r")) == (NrnFILEWrap*) 0) {
1324 #if OCSMALL
1325  hoc_menu_cleanup();
1326 #endif
1327  Fprintf(stderr, "%d %s: can't open %s\n", nrnmpi_myid_world, progname, infile);
1328 #if NRNMPI
1329  if (nrnmpi_numprocs_world > 1) {
1330  nrnmpi_abort(-1);
1331  }
1332 #endif
1333  return moreinput();
1334  }
1335  if (infile) {
1336  if (strlen(infile) >= hoc_xopen_file_size_) {
1337  hoc_xopen_file_size_ = strlen(infile) + 100;
1339  }
1340  strcpy(hoc_xopen_file_, infile);
1341  }
1342  return 1;
1343 }
1344 
1345 #if 1
1346 void hoc_run(void) {
1347  hoc_run1();
1348  while (pipeflag == 1) {
1349  pipeflag = 0;
1350  hoc_run1();
1351  }
1352 }
1353 #endif
1354 
1355 typedef RETSIGTYPE (*SignalType)(int);
1356 
1358 
1359 static void set_signals(void) {
1360  signals[0] = signal(SIGINT, onintr);
1361  signals[1] = signal(SIGFPE, fpecatch);
1362 #if HAVE_SIGSEGV
1363  signals[2] = signal(SIGSEGV, sigsegvcatch);
1364 #endif
1365 #if HAVE_SIGBUS
1366  signals[3] = signal(SIGBUS, sigbuscatch);
1367 #endif
1368 }
1369 
1370 static void restore_signals(void) {
1371  signals[0] = signal(SIGINT, signals[0]);
1372  signals[1] = signal(SIGFPE, signals[1]);
1373 #if HAVE_SIGSEGV
1374  signals[2] = signal(SIGSEGV, signals[2]);
1375 #endif
1376 #if HAVE_SIGBUS
1377  signals[3] = signal(SIGBUS, signals[3]);
1378 #endif
1379 }
1380 
1381 static int hoc_run1(void) /* execute until EOF */
1382 {
1383  int controlled = control_jmpbuf;
1384  NrnFILEWrap* sav_fin = fin;
1385  if (!controlled) {
1386  set_signals();
1387  control_jmpbuf = 1;
1388  if (setjmp(begin)) {
1389  fin = sav_fin;
1390  if (!nrn_fw_eq(fin, stdin)) {
1391  return EXIT_FAILURE;
1392  }
1393  }
1394  intset = 0;
1395  }
1397  pipeflag = 0; // reset pipeflag
1398  for (initcode(); hoc_yyparse(); initcode()) {
1399  execute(progbase);
1400  }
1401  if (intset)
1402  execerror("interrupted", (char*) 0);
1403  if (!controlled) {
1404  restore_signals();
1405  control_jmpbuf = 0;
1406  }
1407  return EXIT_SUCCESS;
1408 }
1409 
1410 /* event driven interface to oc. This routine always returns after processing
1411  its argument. The normal case is where the argument consists of a complete
1412  statement which can be parsed and executed. However this routine can
1413  be called with single tokens as well and the parsing will proceed
1414  incrementally until the last token that completes a statement is seen
1415  at which time the statement is executed.
1416  The routine can also be called with a string containing multiple statements
1417  separated by '\n's.
1418  During execution a ^C will halt
1419  processing and this routine will return to the calling statement. (if it
1420  is the controlling call for the jmp_buf; see below).
1421  Parse errors and execution errors will also result in a normal return to the
1422  calling statement.
1423 
1424  To avoid blocking other input events, this routine should not be called
1425  with statements which take too much time to execute or block
1426  waiting for input. With regard to long executing statements, at least in
1427  xview it is possible to run the event loop from the execute loop at
1428  intervals in code.cpp or else to run the event loop once via a hoc command.
1429 
1430  Where do we go in case of an hoc_execerror. We have to go to the beginning
1431  of hoc. But just maybe that is here. However hoc_oc may be called
1432  recursively. Or it may be called from the original hoc_run. Or it may be
1433  There is therefore a notion of the controlling routine for the jmp_buf begin.
1434  We only do a setjmp and set the signals
1435  when there is no other controlling routine.
1436 */
1437 
1438 /* allow hoc_oc(buf) to handle any number of multiline statements */
1439 static const char* nrn_inputbufptr;
1440 static void nrn_inputbuf_getline(void) {
1441  CHAR* cp;
1442  cp = ctp = cbuf = hoc_cbufstr->buf;
1443  while (*nrn_inputbufptr) {
1444  *cp++ = *nrn_inputbufptr++;
1445  if (cp[-1] == '\n') {
1446  break;
1447  }
1448  }
1449  if (cp != ctp) {
1450  if (cp[-1] != '\n') {
1451  *cp++ = '\n';
1452  }
1453  }
1454  *cp = '\0';
1455 }
1456 
1457 // used by ocjump.cpp
1458 extern "C" void oc_save_input_info(const char** i1, int* i2, int* i3, NrnFILEWrap** i4) {
1459  *i1 = nrn_inputbufptr;
1460  *i2 = pipeflag;
1461  *i3 = lineno;
1462  *i4 = fin;
1463 }
1464 extern "C" void oc_restore_input_info(const char* i1, int i2, int i3, NrnFILEWrap* i4) {
1465  nrn_inputbufptr = i1;
1466  pipeflag = i2;
1467  lineno = i3;
1468  fin = i4;
1469 }
1470 
1471 int hoc_oc(const char* buf) {
1472  char* cp;
1473  int controlled;
1474 #if 0
1475  int yret;
1476 #endif
1477 
1478  int sav_pipeflag = pipeflag;
1479  int sav_lineno = lineno;
1480  const char* sav_inputbufptr = nrn_inputbufptr;
1481  nrn_inputbufptr = buf;
1482  pipeflag = 3;
1483  lineno = 1;
1484  controlled = hoc_oc_jmpbuf || oc_jump_target_;
1485  if (!controlled) {
1486  hoc_oc_jmpbuf = 1;
1487  if (setjmp(hoc_oc_begin)) {
1488  hoc_oc_jmpbuf = 0;
1489  restore_signals();
1490  initcode();
1491  intset = 0;
1492  pipeflag = sav_pipeflag;
1493  nrn_inputbufptr = sav_inputbufptr;
1494  lineno = sav_lineno;
1495  return 1;
1496  }
1497  set_signals();
1498  }
1499  intset = 0;
1500 
1501  hocstr_resize(hoc_cbufstr, strlen(buf) + 10);
1503  while (*ctp || *nrn_inputbufptr) {
1505 
1506  if (intset) {
1507  execerror("interrupted", (char*) 0);
1508  }
1509  }
1510 
1511  if (!controlled) {
1512  hoc_oc_jmpbuf = 0;
1513  restore_signals();
1514  }
1515  lineno = sav_lineno;
1516  pipeflag = sav_pipeflag;
1517  nrn_inputbufptr = sav_inputbufptr;
1519  return 0;
1520 }
1521 
1522 void warning(const char* s, const char* t) /* print warning message */
1523 {
1524  CHAR* cp;
1525  char id[10];
1526  int n;
1527  if (nrnmpi_numprocs_world > 1) {
1528  sprintf(id, "%d ", nrnmpi_myid_world);
1529  } else {
1530  id[0] = '\0';
1531  }
1532  if (t) {
1533  Fprintf(stderr, "%s%s: %s %s\n", id, progname, s, t);
1534  } else {
1535  Fprintf(stderr, "%s%s: %s\n", id, progname, s);
1536  }
1537  if (hoc_xopen_file_ && hoc_xopen_file_[0]) {
1538  Fprintf(stderr, "%s in %s near line %d\n", id, hoc_xopen_file_, lineno);
1539  } else {
1540  Fprintf(stderr, "%s near line %d\n", id, lineno);
1541  }
1542  n = strlen(cbuf);
1543  for (cp = cbuf; cp < (cbuf + n); ++cp) {
1544  if (!isprint((int) (*cp)) && !isspace((int) (*cp))) {
1545  Fprintf(stderr,
1546  "%scharacter \\%03o at position %ld is not printable\n",
1547  id,
1548  ((int) (*cp) & 0xff),
1549  cp - cbuf);
1550  break;
1551  }
1552  }
1553  Fprintf(stderr, "%s %s", id, cbuf);
1554  if (nrnmpi_numprocs_world > 0) {
1555  for (cp = cbuf; cp != ctp; cp++) {
1556  Fprintf(stderr, " ");
1557  }
1558  Fprintf(stderr, "^\n");
1559  }
1560  ctp = cbuf;
1561  *ctp = '\0';
1562 }
1563 
1564 
1565 static int Getc(NrnFILEWrap* fp) {
1566  /*ARGSUSED*/
1567  if (*ctp) {
1568  ++hoc_ictp;
1569  return *ctp++;
1570  }
1571 
1572 #if 0
1573 /* don't allow parser to block. Actually partial statements were never
1574 allowed anyway */
1575  if (!pipeflag && nrn_fw_eq(fp,stdin)) {
1576  eos = 1;
1577  return 0;
1578  }
1579 #endif
1580 
1581  if (hoc_get_line() == EOF) {
1582  return EOF;
1583  }
1584  return *ctp++;
1585 }
1586 
1587 static void unGetc(int c, NrnFILEWrap* fp) {
1588  /*ARGSUSED*/
1589  if (c != EOF && c && ctp != cbuf) {
1590  *(--ctp) = c;
1591  }
1592 }
1593 
1595 
1596 int hoc_yyparse(void) {
1597  /* read line before calling yyparse() and set flag that we
1598  are inside yyparse() since re-entry is not allowed.
1599  This allows xview menus to work since most of the time
1600  we are reading a line from this point instead of in
1601  Getc which was called from yyparse().
1602  */
1603  /*
1604  the above may be obsolete.
1605  I switched to a modified bison generator from yacc which is generated
1606  a parser exactly like it used to be but may return YYNEEDMORE=-3
1607  instead of blocking in yylex. If so another call to yyparse will
1608  take up exactly where it left off. This makes it easier to
1609  support event driven processing.
1610  Maybe it's time to redo the get_line process which fills cbuf with
1611  the next line to read. A real event driven program would fill cbuf
1612  and then call yyparse() directly. yyparse() returns
1613  0 : end of file
1614  '\n' : ready to execute a command
1615  -3: need more input, not at a point where it accepts or rejects the
1616  input.
1617  */
1618 
1619  int i;
1620 
1621  if (hoc_in_yyparse) {
1622  hoc_execerror("Cannot re-enter parser", (char*) 0);
1623  }
1624  do {
1625  if (hoc_get_line() == EOF) {
1626  return 0;
1627  }
1628  hoc_in_yyparse = 1;
1629  i = yyparse();
1630  hoc_in_yyparse = 0;
1631  if (i == -3) { // need more input
1632  hoc_in_yyparse = 1;
1633  i = '\n';
1634  }
1635  } while (i == '\n');
1636  return i;
1637 }
1638 
1639 #if defined(__GO32__)
1640 #define INTERVIEWS 1
1641 #endif
1642 #ifdef WIN32
1643 #define INTERVIEWS 1
1644 #endif
1645 #ifdef MAC
1646 #define INTERVIEWS 1
1647 #endif
1648 
1650 #if INTERVIEWS
1651 extern int run_til_stdin(); /* runs the interviews event loop. Returns 1
1652  if there is input to be read. Returns 0
1653  if somebody said quit but there is no input
1654  */
1655 
1656 extern void hoc_notify_value(void);
1657 
1658 #if READLINE
1659 #if carbon
1660 extern int (*rl_event_hook)(void);
1661 static int event_hook(void) {
1662  if (!inputReady_) {
1663  inputReady_ = (pthread_t*) emalloc(sizeof(pthread_t));
1664  pthread_mutex_init(&inputMutex_, 0);
1665  pthread_cond_init(&inputCond_, 0);
1666  pthread_create(inputReady_, 0, inputReadyThread, 0);
1667  } else {
1668  pthread_mutex_unlock(&inputMutex_);
1669  }
1670  // printf("run til stdin\n");
1671  run_til_stdin();
1672  pthread_mutex_lock(&inputMutex_);
1673  pthread_cond_signal(&inputCond_);
1674  return 1;
1675 }
1676 #else /* not carbon */
1677 #ifdef MINGW
1678 extern "C" int (*rl_getc_function)(void);
1679 extern "C" int rl_getc(void);
1680 static int getc_hook(void) {
1681  int i;
1682  if (!inputReady_) {
1683  stdin_event_ready(); /* store main thread id */
1684  inputReady_ = (pthread_t*) emalloc(sizeof(pthread_t));
1685  pthread_mutex_init(&inputMutex_, 0);
1686  pthread_cond_init(&inputCond_, 0);
1687  pthread_create(inputReady_, 0, inputReadyThread, 0);
1688  } else {
1689  pthread_mutex_unlock(&inputMutex_);
1690  }
1691  // printf("run til stdin\n");
1692  while (!inputReadyFlag_) {
1693  run_til_stdin();
1694  usleep(10000);
1695  }
1696  inputReadyFlag_ = 0;
1697  i = inputReadyVal_;
1698  pthread_mutex_lock(&inputMutex_);
1699  pthread_cond_signal(&inputCond_);
1700  // printf("getc_hook returning %d\n", i);
1701  return i;
1702 }
1703 #else /* not carbon and not MINGW */
1704 
1705 #if defined(use_rl_getc_function)
1706 /* e.g. mac libedit.3.dylib missing rl_event_hook */
1707 
1708 extern int iv_dialog_is_running;
1709 extern "C" int (*rl_getc_function)(void);
1710 static int getc_hook(void) {
1711  while (1) {
1712  int r;
1713  unsigned char c;
1714  if (hoc_interviews && !hoc_in_yyparse && run_til_stdin() == 0) {
1715  // nothing in stdin (happens when windows are dismissed)
1716  continue;
1717  }
1718  if ((r = read(0, &c, sizeof(c))) == sizeof(c)) {
1719  return (int) c;
1720  } else {
1721  /* this seems consistent with the internal readline and the
1722  current master version 8.0. That is, rl_getc in the
1723  internal readline gets the return value of read and only
1724  cares about r == 1, loops if errno == EINTR, and returns
1725  EOF otherwise. (Note: internal readline does not have
1726  rl_getc_function.). Version 8.0 rl_getc is complex but in
1727  terms of read, it returns c if r == 1, returns EOF if
1728  r == 0, loops if errno == EINTR, and generally returns EOF
1729  if some other error occurred.
1730  */
1731  if (errno != EINTR) {
1732  return EOF;
1733  }
1734  }
1735  }
1736 }
1737 
1738 #else /* not use_rl_getc_function */
1739 
1740 extern int (*rl_event_hook)(void);
1741 static int event_hook(void) {
1742  int i;
1743  i = run_til_stdin();
1744  return i;
1745 }
1746 
1747 #endif /* not use_rl_getc_function */
1748 
1749 #endif /* not carbon and not MINGW */
1750 #endif /* not carbon */
1751 #endif /* READLINE */
1752 #endif /* INTERVIEWS */
1753 
1754 #if 1 || MAC
1755 /*
1756  On Mac combinations of /n /r /r/n require binary mode
1757  (otherwise /r/n is /n/n)
1758  but then /r does not end a line in fgets (keeps reading til /n)
1759  so we make our own fgets. May need to use it for data as well.
1760 */
1761 /*
1762  for unix and mac this allows files created on any machine to be
1763  read on any machine
1764 */
1766  return fgets_unlimited_nltrans(bufstr, f, 1);
1767 }
1768 
1769 static CHAR* fgets_unlimited_nltrans(HocStr* bufstr, NrnFILEWrap* f, int nltrans) {
1770  int c, i;
1771  int nl1, nl2;
1772  if (!f) {
1773  hoc_execerr_ext("No file (or stdin) for input");
1774  }
1775  if (nltrans) {
1776  nl1 = 26;
1777  nl2 = 4;
1778  } else {
1779  nl1 = nl2 = EOF;
1780  }
1781  for (i = 0;; ++i) {
1782  c = nrn_fw_getc(f);
1783  if (c == EOF || c == nl1 || c == nl2) { /* ^Z and ^D are end of file */
1784  /* some editors don't put a newline at last line */
1785  if (i > 0) {
1786  nrn_fw_ungetc(c, f);
1787  c = '\n';
1788  } else {
1789  break;
1790  }
1791  }
1792  if (c == '\r') {
1793  int c2 = nrn_fw_getc(f);
1794  if (c2 != '\n') {
1795  nrn_fw_ungetc(c2, f);
1796  }
1797  c = '\n';
1798  }
1799  if (bufstr->size <= i) {
1800  hocstr_resize(bufstr, bufstr->size * 2);
1801  }
1802  bufstr->buf[i] = c;
1803  if (c == '\n') {
1804  bufstr->buf[i + 1] = '\0';
1805  return bufstr->buf;
1806  }
1807  }
1808  return (CHAR*) 0;
1809 }
1810 #endif
1811 
1812 #if MAC
1813 int hoc_get_line(void) { /* supports re-entry. fill cbuf with next line */
1814  if (*ctp) {
1815  hoc_execerror("Internal error:", "Not finished with previous input line");
1816  }
1817  ctp = cbuf;
1818  *ctp = '\0';
1819  if (pipeflag == 3) {
1821  if (*ctp == '\0') {
1822  return EOF;
1823  }
1824  } else if (pipeflag) {
1825  if (hoc_strgets_need() > hoc_cbufstr->size) {
1827  }
1828  if (hoc_strgets(cbuf, hoc_cbufstr->size - 1) == (char*) 0) {
1829  return EOF;
1830  }
1831  } else {
1832  if (nrn_fw_wrap(fin, stdin) && hoc_interviews && !hoc_in_yyparse) {
1833 #if MAC
1834  for (;;) {
1835  extern CHAR* hoc_console_buffer;
1836  hoc_console_buffer = cbuf;
1837  if (run_til_stdin()) {
1838  // printf("%s", cbuf);
1839  // strcpy(cbuf, hoc_console_buffer);
1840  break;
1841  } else {
1842  return EOF;
1843  }
1844  }
1845 #endif
1846  } else if (hoc_fgets_unlimited(hoc_cbufstr, fin) == (CHAR*) 0) {
1847  return EOF;
1848  }
1849  }
1850  // printf("%d %s", lineno, cbuf);
1851  errno = 0;
1852  lineno++;
1853  ctp = cbuf = hoc_cbufstr->buf;
1854  hoc_ictp = 0;
1855  return 1;
1856 }
1857 
1858 #else
1859 int hoc_get_line(void) { /* supports re-entry. fill cbuf with next line */
1860  if (*ctp) {
1861  hoc_execerror("Internal error:", "Not finished with previous input line");
1862  }
1863  ctp = cbuf = hoc_cbufstr->buf;
1864  *ctp = '\0';
1865  if (pipeflag == 3) {
1867  if (*ctp == '\0') {
1868  return EOF;
1869  }
1870  } else if (pipeflag) {
1871  if (hoc_strgets_need() > hoc_cbufstr->size) {
1873  }
1874  if (hoc_strgets(cbuf, CBUFSIZE - 1) == (char*) 0) {
1875  return EOF;
1876  }
1877  } else {
1878 #if READLINE
1879  if (nrn_fw_eq(fin, stdin) && nrn_istty_) {
1880  char* line;
1881  int n;
1882 #if INTERVIEWS
1883 #ifdef MINGW
1884  IFGUI
1885  if (hoc_interviews && !hoc_in_yyparse) {
1886  rl_getc_function = getc_hook;
1887  hoc_notify_value();
1888  } else {
1889  rl_getc_function = rl_getc;
1890  }
1891  ENDGUI
1892 #else /* not MINGW */
1893 #if defined(use_rl_getc_function)
1894  if (hoc_interviews && !hoc_in_yyparse) {
1895  rl_getc_function = getc_hook;
1896  hoc_notify_value();
1897  } else {
1898  rl_getc_function = getc_hook;
1899  }
1900 #else /* not use_rl_getc_function */
1901  if (hoc_interviews && !hoc_in_yyparse) {
1902  rl_event_hook = event_hook;
1903  hoc_notify_value();
1904  } else {
1905  rl_event_hook = NULL;
1906  }
1907 #endif /* not use_rl_getc_function */
1908 #endif /* not MINGW */
1909 #endif /* INTERVIEWS */
1910  if ((line = readline(hoc_promptstr)) == (char*) 0) {
1911  extern int hoc_notify_stop;
1912  return EOF;
1913  }
1914 #if defined(__GO32__)
1915  hoc_check_intupt(0);
1916 #endif
1917  n = strlen(line);
1918  for (int i = 0; i < n; ++i) {
1919  if (!isascii(line[i])) {
1920  hoc_execerr_ext("Non-ASCII character value 0x%hhx at input position %d\n",
1921  (unsigned) line[i],
1922  i);
1923  }
1924  }
1925  if (n >= hoc_cbufstr->size - 3) {
1926  hocstr_resize(hoc_cbufstr, n + 100);
1927  ctp = cbuf = hoc_cbufstr->buf;
1928  }
1929  strcpy(cbuf, line);
1930  cbuf[n] = '\n';
1931  cbuf[n + 1] = '\0';
1932  if (line && *line) {
1933  add_history(line);
1934  }
1935  free(line);
1937  } else {
1938  fflush(stdout);
1939  if (hoc_fgets_unlimited(hoc_cbufstr, fin) == (CHAR*) 0) {
1940  return EOF;
1941  }
1942  }
1943 #else
1944 #if INTERVIEWS
1945  if (nrn_fw_eq(fin, stdin) && hoc_interviews && !hoc_in_yyparse) {
1946  run_til_stdin());
1947  }
1948 #endif
1949 #if defined(WIN32)
1950  if (nrn_fw_eq(fin, stdin)) {
1951  if (gets(cbuf) == (char*) 0) {
1952  /*DebugMessage("gets returned NULL\n");*/
1953  return EOF;
1954  }
1955  strcat(cbuf, "\n");
1956  } else
1957 #endif
1958  {
1959  if (hoc_fgets_unlimited(hoc_cbufstr, fin) == (char*) 0) {
1960  return EOF;
1961  }
1962  }
1963 #endif
1964  }
1965  errno = 0;
1966  lineno++;
1967  ctp = cbuf = hoc_cbufstr->buf;
1968  hoc_ictp = 0;
1969  return 1;
1970 }
1971 #endif
1972 
1973 void hoc_help(void) {
1974 #if INTERVIEWS
1975  if (hoc_interviews) {
1976  ivoc_help(cbuf);
1977  } else
1978 #endif
1979  {
1980  IFGUI
1981  hoc_warning("Help only available from version with ivoc library", 0);
1982  ENDGUI
1983  }
1984  ctp = cbuf + strlen(cbuf) - 1;
1985 }
1986 
1987 #if defined(__GO32__)
1988 void hoc_check_intupt(int intupt) {
1989  if (_go32_was_ctrl_break_hit()) {
1990  if (intupt) {
1991  execerror("interrupted", (char*) 0);
1992  }
1993  }
1994 }
1995 #endif
void backward_wrapper()
int parse_bt_symbol(char *backtrace_line, void **addr, char *symbol, char *offset)
int cxx_demangle(char *symbol, char **funcname, size_t *funcname_sz)
static void prnt(const TQItem *b, int level)
Definition: bbtqueue.cpp:64
#define symlist
Definition: cabcode.cpp:17
double xpop(void)
Definition: code.cpp:788
char * hoc_strgets(char *cbuf, int nc)
Definition: code.cpp:507
static Frame * fp
Definition: code.cpp:161
void pushx(double d)
Definition: code.cpp:658
Symbol * spop(void)
Definition: code.cpp:846
void initcode(void)
Definition: code.cpp:403
int hoc_strgets_need(void)
Definition: code.cpp:503
Inst * pc
Definition: code.cpp:145
Inst * progbase
Definition: code.cpp:146
void execute(Inst *p)
Definition: code.cpp:2661
double t
Definition: cvodeobj.cpp:59
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)
#define yyparse
Definition: difeqdef.h:4
#define yylval
Definition: difeqdef.h:7
double chkarg(int, double low, double high)
Definition: code2.cpp:638
jmp_buf restart
Definition: err.c:110
NrnFILEWrap * frin
Definition: fileio.cpp:22
FILE * fout
Definition: fileio.cpp:23
static int egagrph
Definition: fmenu.cpp:122
char buf[512]
Definition: init.cpp:13
NrnFILEWrap * fin
Definition: hoc.cpp:181
hoc_close_plot()
Definition: macprt.cpp:124
int stoprun
Definition: fadvance.cpp:166
void hoc_audit_command(const char *buf)
Definition: audit.cpp:122
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
Definition: fileio.cpp:931
void hoc_execerror(const char *s, const char *t)
Definition: hoc.cpp:754
void hoc_free_val_array(double *, size_t)
Definition: symbol.cpp:383
void frame_debug(void)
Definition: code.cpp:1313
int hoc_arayinfo_install(Symbol *sp, int nsub)
Definition: hoc.cpp:601
void hoc_final_exit(void)
Definition: hoc.cpp:1131
void save_parallel_argv(int, const char **)
Definition: parallel.cpp:207
void * hoc_Ecalloc(size_t nmemb, size_t size)
Definition: symbol.cpp:205
int nrn_inpython_
Definition: hoc.cpp:37
void save_parallel_envp(void)
Definition: parallel.cpp:253
int hoc_ParseExec(int yystart)
Definition: code.cpp:531
void hoc_freearay(Symbol *sp)
Definition: hoc.cpp:640
void ivoc_final_exit()
Definition: ivocmain.cpp:863
void hoc_menu_cleanup(void)
Definition: fmenu.cpp:671
void * hoc_sec_internal_name2ptr(const char *s, int eflag)
Definition: cabcode.cpp:762
void * nrn_parsing_pysec_
int hoc_errno_check(void)
Definition: math.cpp:109
void nrn_exit(int i)
Definition: hoc.cpp:219
size_t hoc_total_array(Symbol *s)
Definition: hoc_oop.cpp:82
void hoc_init(void)
Definition: hoc_init.cpp:411
void hoc_ret()
int hoc_oc(const char *buf)
Definition: hoc.cpp:1471
void hoc_warning(const char *, const char *)
initplot()
Definition: macprt.cpp:188
void ivoc_help(const char *)
Definition: ocnoiv1.cpp:16
void * hoc_pysec_name2ptr(const char *s, int eflag)
Definition: cabcode.cpp:803
int hoc_main1(int argc, const char **argv, const char **envp)
Definition: hoc.cpp:983
void hoc_audit_from_hoc_main1(int argc, const char **argv, const char **envp)
Definition: audit.cpp:56
void hoc_oop_initaftererror(void)
Definition: hoc_oop.cpp:417
int nrn_is_cable(void)
Definition: init.cpp:205
int nrnignore
Definition: hoc.cpp:26
void hoc_audit_from_final_exit(void)
Definition: audit.cpp:138
void hoc_execerror_mes(const char *s, const char *t, int prnt)
Definition: hoc.cpp:702
void bbs_done()
Definition: datapath.cpp:32
int hoc_pid(void)
Definition: hoc.cpp:877
int hoc_get_line(void)
Definition: hoc.cpp:1859
int nrn_mpiabort_on_error_
Definition: hoc.cpp:77
static void unGetc(int c, NrnFILEWrap *fp)
Definition: hoc.cpp:1587
static void set_signals(void)
Definition: hoc.cpp:1359
#define CBUFSIZE
Definition: hoc.cpp:163
int gargc
Definition: hoc.cpp:202
char * fgets_unlimited(HocStr *s, NrnFILEWrap *f)
Definition: hoc.cpp:955
static int debug_message_
Definition: hoc.cpp:671
static int coredump
Definition: hoc.cpp:772
void hoc_main1_init(const char *pname, const char **envp)
Definition: hoc.cpp:887
char * hoc_xopen_file_
Definition: fileio.cpp:201
HocStr * hoc_tmpbuf
Definition: hoc.cpp:164
void hoc_newobj1_err()
unref partially constructed objects controlled by current longjump handle
Definition: hoc_oop.cpp:546
RETSIGTYPE fpecatch(int sig)
Definition: hoc.cpp:834
int hoc_execerror_messages
Definition: hoc.cpp:680
void add_history(const char *)
int hoc_ictp
Definition: hoc.cpp:169
static CHAR * fgets_unlimited_nltrans(HocStr *s, NrnFILEWrap *f, int nltrans)
Definition: hoc.cpp:1769
#define CHAR
Definition: hoc.cpp:153
static int eos
Definition: hoc.cpp:292
RETSIGTYPE(* SignalType)(int)
Definition: hoc.cpp:1355
static int control_jmpbuf
Definition: hoc.cpp:192
int indef
Definition: hoc.cpp:197
const char * infile
Definition: hoc.cpp:198
void pr_profile(void)
Definition: hoc.cpp:123
#define TMPBUFSIZE
Definition: hoc.cpp:162
HocStr * hocstr_create(size_t size)
Definition: hoc.cpp:945
int nrn_global_argc
Definition: hoc.cpp:29
static int c
Definition: hoc.cpp:203
int nrn_istty_
Definition: hoc.cpp:882
HocStr * hoc_cbufstr
Definition: hoc.cpp:165
int lineno
Definition: hoc.cpp:185
int nrn_nobanner_
Definition: hoc.cpp:146
static jmp_buf hoc_oc_begin
Definition: hoc.cpp:195
int hoc_print_first_instance
Definition: hoc_oop.cpp:38
void(* oc_jump_target_)()
Definition: hoc.cpp:686
void nrn_feenableexcept()
Definition: hoc.cpp:81
RETSIGTYPE onintr(int sig)
Definition: hoc.cpp:759
static int Getc(NrnFILEWrap *fp)
Definition: hoc.cpp:1565
int hoc_yyparse(void)
Definition: hoc.cpp:1596
#define EPS
Definition: hoc.cpp:176
void print_bt()
Definition: hoc.cpp:780
void oc_restore_input_info(const char *i1, int i2, int i3, NrnFILEWrap *i4)
Definition: hoc.cpp:1464
void * nrn_get_hoc_jmp()
If one of the two jmp_buf is controlling the longjmp hoc_newobj1_err needs handle to know how much to...
Definition: hoc.cpp:697
static RETSIGTYPE sigpipe_handler(int sig)
Definition: hoc.cpp:262
static int hoc_oc_jmpbuf
Definition: hoc.cpp:194
int hoc_interviews
Definition: hoc.cpp:1649
size_t hoc_xopen_file_size_
Definition: fileio.cpp:200
#define READLINE
Definition: hoc.cpp:135
void hocstr_copy(HocStr *hs, const char *buf)
Definition: hoc.cpp:972
static void restore_signals(void)
Definition: hoc.cpp:1370
int hoc_in_yyparse
Definition: hoc.cpp:1594
CHAR * hoc_fgets_unlimited(HocStr *bufstr, NrnFILEWrap *f)
Definition: hoc.cpp:1765
int pipeflag
Definition: hoc.cpp:147
int nrn_feenableexcept_
Definition: hoc.cpp:79
const char * hoc_promptstr
Definition: hoc.cpp:166
#define YYNEEDMORE
Definition: hoc.cpp:283
void oc_save_input_info(const char **i1, int *i2, int *i3, NrnFILEWrap **i4)
Definition: hoc.cpp:1458
static int backslash(int c)
Definition: hoc.cpp:552
int hoc_main1_inited_
Definition: hoc.cpp:884
const char ** gargv
Definition: hoc.cpp:201
int yylex(void)
Definition: hoc.cpp:315
int getnb(void)
Definition: hoc.cpp:268
static SignalType signals[4]
Definition: hoc.cpp:1357
char ** nrn_global_argv
Definition: hoc.cpp:30
static void nrn_inputbuf_getline(void)
Definition: hoc.cpp:1440
void add_profile(int i)
Definition: hoc.cpp:122
int yystart
Definition: hoc.cpp:689
int moreinput(void)
Definition: hoc.cpp:1215
void hocstr_resize(HocStr *hs, size_t n)
Definition: hoc.cpp:964
jmp_buf begin
Definition: hoc.cpp:193
void hoc_coredump_on_error(void)
Definition: hoc.cpp:774
CHAR * ctp
Definition: hoc.cpp:168
void hoc_quit(void)
Definition: hoc.cpp:1162
int intset
Definition: hoc.cpp:196
static char * optarray(char *buf)
Definition: hoc.cpp:294
char * RCS_hoc_date
Definition: version.cpp:999
const char * progname
Definition: hoc.cpp:184
char * neuron_home
Definition: hoc_init.cpp:404
void hoc_help(void)
Definition: hoc.cpp:1973
char * RCS_hoc_version
Definition: version.cpp:998
char * readline(const char *prompt)
static const char * nrn_inputbufptr
Definition: hoc.cpp:1439
int hoc_usegui
Definition: hoc.cpp:148
void warning(const char *s, const char *t)
Definition: hoc.cpp:1522
void hocstr_delete(HocStr *hs)
Definition: hoc.cpp:959
void arayinstal(void)
Definition: hoc.cpp:572
void defnonly(const char *s)
Definition: hoc.cpp:663
void hoc_show_errmess_always(void)
Definition: hoc.cpp:672
static int follow(int expect, int ifyes, int ifno)
Definition: hoc.cpp:562
void rl_deprep_terminal(void)
void free_arrayinfo(Arrayinfo *a)
Definition: hoc.cpp:652
void hoc_run(void)
Definition: hoc.cpp:1346
int(* p_nrnpy_pyrun)(const char *fname)
Definition: hoc.cpp:38
static CHAR * cbuf
Definition: hoc.cpp:167
static int hoc_run1(void)
Definition: hoc.cpp:1381
void start_profile(int i)
Definition: hoc.cpp:121
void * erealloc(void *ptr, size_t n)
Definition: symbol.cpp:263
#define IFGUI
Definition: hocdec.h:372
#define getarg
Definition: hocdec.h:15
#define OPARINFO(sym)
Definition: hocdec.h:311
struct Arrayinfo Arrayinfo
int parallel_sub
Definition: parallel.cpp:30
#define ENDGUI
Definition: hocdec.h:373
#define NOT_PARALLEL_SUB(c1)
Definition: hocdec.h:379
#define OPVAL(sym)
Definition: hocdec.h:306
void hoc_acterror(const char *, const char *)
void(* p_nrnpython_finalize)()
static int argc
Definition: inithoc.cpp:53
static char ** argv
Definition: inithoc.cpp:54
static char line[MAXLINE]
Definition: ivecop.c:35
void
int bbs_poll_
Definition: datapath.cpp:31
void nrn_err_dialog(const char *mes)
Definition: ivoc.cpp:132
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:322
void ivoc_cleanup()
Definition: ocnoiv1.cpp:17
void hoc_notify_value()
Definition: ivocmain.cpp:892
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
int run_til_stdin()
Definition: ivocmain.cpp:889
int stdin_event_ready()
Definition: ivocwin.cpp:291
void hoc_check_intupt(int intupt)
Definition: macprt.cpp:85
#define MAC
Definition: matlab.h:50
#define input(prompt, fmt, var)
Definition: matrix.h:368
#define i
Definition: md1redef.h:12
#define IGNORE(arg)
Definition: model.h:247
#define Strcpy
Definition: model.h:238
#define Fprintf
Definition: model.h:234
floor
Definition: extdef.h:4
char * emalloc(unsigned n)
Definition: list.cpp:166
#define printf
Definition: mwprefix.h:26
#define fprintf
Definition: mwprefix.h:30
#define gets
Definition: mwprefix.h:28
#define nrn_fw_eq(fw, ff)
Definition: nrnfilewrap.h:43
#define nrn_fw_wrap(f)
Definition: nrnfilewrap.h:41
#define nrn_fw_fclose
Definition: nrnfilewrap.h:44
#define nrn_fw_set_stdin()
Definition: nrnfilewrap.h:45
#define nrn_fw_getc(fw)
Definition: nrnfilewrap.h:48
#define nrn_fw_fseek
Definition: nrnfilewrap.h:47
#define NrnFILEWrap
Definition: nrnfilewrap.h:39
#define nrn_fw_fopen
Definition: nrnfilewrap.h:46
#define nrn_fw_ungetc(c, fw)
Definition: nrnfilewrap.h:49
int const size_t const size_t n
Definition: nrngsl.h:11
return status
size_t p
size_t j
void nrnmpi_abort(int errcode)
Definition: nrnmpi.cpp:205
int nrnmpi_numprocs_world
int nrnmpi_myid_world
void hoc_malchk()
Definition: symbol.cpp:183
int(* p_nrnpython_start)(int)
static realtype retval
Symlist * p_symlist
Definition: symbol.cpp:48
int hoc_readcheckpoint(char *)
Definition: ocnoiv1.cpp:18
static const char ** pname(void *v)
Definition: ocpointer.cpp:70
#define acterror
Definition: redef.h:23
#define lookup
Definition: redef.h:90
#define do_equation
Definition: redef.h:48
#define install
Definition: redef.h:82
#define ret
Definition: redef.h:123
#define execerror
Definition: section.h:36
#define OR
Definition: spdefs.h:112
#define AND
Definition: spdefs.h:111
#define NOT
Definition: spdefs.h:110
#define NULL
Definition: sptree.h:16
unsigned * a_varn
Definition: hocdec.h:69
int nsub
Definition: hocdec.h:70
int refcount
Definition: hocdec.h:71
int sub[1]
Definition: hocdec.h:72
Definition: hocstr.h:7
size_t size
Definition: hocstr.h:9
char * buf
Definition: hocstr.h:8
Definition: model.h:57
short type
Definition: model.h:58
unsigned s_varn
Definition: hocdec.h:158
char * name
Definition: model.h:72
Arrayinfo * arayinfo
Definition: hocdec.h:159
Definition: hocdec.h:51
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113