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