NEURON
fileio.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/oc/fileio.cpp,v 1.34 1999/09/14 13:11:46 hines Exp */
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <cstdarg>
7 #include <unistd.h>
8 #include "hoc.h"
9 #include "ocmisc.h"
10 #include "hocstr.h"
11 #include "hoclist.h"
12 #include "parse.hpp"
13 #include "hocparse.h"
14 #include <setjmp.h>
15 #include <errno.h>
16 #include "nrnfilewrap.h"
17 
18 
19 extern jmp_buf begin;
20 extern char* neuron_home;
21 
23 FILE* fout;
24 
25 #if 0 && MAC
26 #include <stdarg.h>
27 
28 void debugfile(const char* format, ...) {
29  va_list args;
30  static FILE* df;
31  if (!df) {
32  df = fopen("debugfile", "w");
33  }
34  va_start(args, format);
35  vfprintf(df, format, args);
36  fflush(df);
37 }
38 #endif
39 
40 void hoc_stdout(void) {
41  static int prev = -1;
42  if (ifarg(1)) {
43  FILE* f1;
44  if (prev != -1) {
45  hoc_execerror("stdout already switched", (char*) 0);
46  }
47  prev = dup(1);
48  if (prev < 0) {
49  hoc_execerror("Unable to backup stdout", (char*) 0);
50  }
51  f1 = fopen(gargstr(1), "wb");
52 
53  if (!f1) {
54  hoc_execerror("Unable to open ", gargstr(1));
55  }
56  if (dup2(fileno(f1), 1) < 0) {
57  hoc_execerror("Unable to attach stdout to ", gargstr(1));
58  }
59  fclose(f1);
60  } else if (prev > -1) {
61  if (dup2(prev, 1) < 0) {
62  hoc_execerror("Unable to restore stdout", (char*) 0);
63  }
64  close(prev);
65  prev = -1;
66  }
67  ret();
68  pushx((double) fileno(stdout));
69 }
70 
71 void ropen(void) /* open file for reading */
72 {
73  double d;
74  char* fname;
75 
76  if (ifarg(1))
77  fname = gargstr(1);
78  else
79  fname = "";
80  d = 1.;
81  if (!nrn_fw_eq(frin, stdin))
84  if (fname[0] != 0) {
85  if ((frin = nrn_fw_fopen(fname, "r")) == (NrnFILEWrap*) 0) {
86  const char* retry;
87  retry = expand_env_var(fname);
88  if ((frin = nrn_fw_fopen(retry, "r")) == (NrnFILEWrap*) 0) {
89  d = 0.;
91  }
92  }
93  }
94  errno = 0;
95  ret();
96  pushx(d);
97 }
98 
99 void wopen(void) /* open file for writing */
100 {
101  char* fname;
102  double d;
103 
104  if (ifarg(1))
105  fname = gargstr(1);
106  else
107  fname = "";
108  d = 1.;
109  if (fout != stdout)
110  ERRCHK(IGNORE(fclose(fout));)
111  fout = stdout;
112  if (fname[0] != 0)
113  ERRCHK(if ((fout = fopen(expand_env_var(fname), "w")) == (FILE*) 0) {
114  d = 0.;
115  fout = stdout;
116  })
117  errno = 0;
118  ret();
119  pushx(d);
120 }
121 
122 extern "C" const char* expand_env_var(const char* s) {
123  static HocStr* hs;
124  const char* cp1;
125  char* cp2;
126  int n;
127  int begin = 1; /* only needed for mac when necessary to prepend a : */
128  if (!hs) {
129  hs = hocstr_create(256);
130  }
131  hocstr_resize(hs, strlen(s) + 2);
132  for (cp1 = s, cp2 = hs->buf + begin; *cp1; ++cp1) {
133  if (*cp1 == '$' && cp1[1] == '(') {
134  char* cp3;
135  char buf[200];
136  cp1 += 2;
137  for (cp3 = buf; *cp1 && *cp1 != ')'; ++cp1) {
138  *cp3++ = *cp1;
139  assert(cp3 - buf < 200);
140  }
141  if (*cp1) {
142  *cp3 = '\0';
143  if (strcmp(buf, "NEURONHOME") == 0) {
144  cp3 = neuron_home;
145  } else {
146  cp3 = getenv(buf);
147  }
148  if (cp3) {
149  n = cp2 - hs->buf;
150  hocstr_resize(hs, n + strlen(cp3) + strlen(s) + 2);
151  cp2 = hs->buf + n;
152  while (*cp3) {
153  *cp2++ = *cp3++;
154  }
155  }
156  } else {
157  --cp1;
158  }
159  } else {
160  *cp2++ = *cp1;
161  }
162  }
163  *cp2 = '\0';
164 #if MAC && !defined(DARWIN)
165  /* convert / to : */
166  for (cp1 = hs->buf + begin; *cp1; ++cp1) {
167  if (*cp1 == '/') {
168  *cp1 = ':';
169  }
170  }
171  /* if a : in the original name then assume already mac and done */
172  /* if $ in original name then done since NEURONHOME already has correct prefix */
173  /* if first is : then remove it, otherwise prepend it */
174  if (!strchr(s, ':') && !strchr(s, '$')) {
175  if (hs->buf[begin] == ':') {
176  begin = 2;
177  } else {
178  begin = 0;
179  hs->buf[0] = ':';
180  }
181  }
182  for (cp1 = hs->buf + begin, cp2 = cp1; *cp1;) {
183  if (cp1[0] == ':' && cp1[1] == '.') {
184  if (cp1[2] == ':') {
185  cp1 += 2;
186  continue;
187  } else if (cp1[2] == '.' && cp1[3] == ':') {
188  cp1 += 3;
189  *cp2++ = ':';
190  continue;
191  }
192  }
193  *cp2++ = *cp1++;
194  }
195  *cp2 = '\0';
196 #endif
197  return hs->buf + begin;
198 }
199 
202 
203 char* hoc_current_xopen(void) {
204  return hoc_xopen_file_;
205 }
206 
207 int hoc_xopen1(const char* name, const char* rcs) /* read and execute a hoc program */
208 {
209  /*printf("hoc_xopen1 %d %s\n", strlen(name), name);*/
210  NrnFILEWrap* savfin;
211  int savpipflag, save_lineno;
212  char* savname;
213  char* fname = strdup(name);
214  assert(fname);
215 #if 1
216  if (rcs) {
217  if (rcs[0] != '\0') {
218  int sz = 2 * (strlen(rcs) + strlen(name)) + 20;
219  free(fname);
220  fname = static_cast<char*>(emalloc(sz));
221  Sprintf(fname, "co -p%s %s > %s-%s", rcs, name, name, rcs);
222  ERRCHK(if (system(fname) != 0) {
223  free(fname);
224  hoc_execerror(name, "\nreturned error in hoc_co system call");
225  })
226  Sprintf(fname, "%s-%s", name, rcs);
227  }
228  } else if (hoc_retrieving_audit()) {
230  free(fname);
231  return 0;
232  }
233 #endif
234  savpipflag = pipeflag;
235  savfin = fin;
236  pipeflag = 0;
237 
238  errno = EINTR;
239  while (errno == EINTR) {
240  errno = 0;
241 #if MAC
242  if ((fin = nrn_fw_fopen(fname, "rb")) == NULL) {
243 #else
244  if ((fin = nrn_fw_fopen(fname, "r")) == NULL) {
245 #endif
246  const char* retry;
247  retry = expand_env_var(fname);
248  free(fname);
249  nrn_assert((fname = strdup(retry)));
250 #if MAC
251  if ((fin = nrn_fw_fopen(retry, "rb")) == NULL) {
252 #else
253  if ((fin = nrn_fw_fopen(retry, "r")) == NULL) {
254 #endif
255  fin = savfin;
256  pipeflag = savpipflag;
257  free(fname);
258  execerror("Can't open ", retry);
259  }
260  }
261  }
262 
263  save_lineno = hoc_lineno;
264  hoc_lineno = 0;
265  nrn_assert((savname = strdup(hoc_xopen_file_)));
266  if (strlen(fname) >= hoc_xopen_file_size_) {
267  hoc_xopen_file_size_ = strlen(fname) + 100;
269  }
270  strcpy(hoc_xopen_file_, fname);
271  if (fin) {
273  IGNORE(hoc_xopen_run((Symbol*) 0, (char*) 0));
274  }
275  if (fin && !nrn_fw_eq(fin, stdin)) {
277  }
278  fin = savfin;
279  pipeflag = savpipflag;
280  if (rcs && rcs[0]) {
281  unlink(fname);
282  }
283  free(fname);
284  hoc_xopen_file_[0] = '\0';
285  hoc_lineno = save_lineno;
286  strcpy(hoc_xopen_file_, savname);
287  free(savname);
288  return 0;
289 }
290 
291 void xopen(void) /* read and execute a hoc program */
292 {
293  if (ifarg(2)) {
294  hoc_xopen1(gargstr(1), gargstr(2));
295  } else {
296  hoc_xopen1(gargstr(1), 0);
297  }
298  ret();
299  pushx(1.);
300 }
301 
302 void Fprint(void) /* fprintf function */
303 {
304  char* buf;
305  double d;
306 
307  hoc_sprint1(&buf, 1);
308  d = (double) fprintf(fout, "%s", buf);
309  ret();
310  pushx(d);
311 }
312 
313 void PRintf(void) /* printf function */
314 {
315  char* buf;
316  double d;
317 
318  hoc_sprint1(&buf, 1);
319  d = (int) strlen(buf);
321  fflush(stdout);
322  ret();
323  pushx(d);
324 }
325 
326 
327 void hoc_Sprint(void) /* sprintf function */
328 {
329  char** cpp;
330  char* buf;
331  /* This is not guaranteed safe since we may be pointing to double */
332  cpp = hoc_pgargstr(1);
333  hoc_sprint1(&buf, 2);
334  hoc_assign_str(cpp, buf);
335  ret();
336  pushx(1.);
337 }
338 
339 double hoc_scan(FILE* fi) {
340  double d;
341  char fs[256];
342 
343  for (;;) {
344  if (fscanf(fi, "%255s", fs) == EOF) {
345  execerror("EOF in fscan", (char*) 0);
346  }
347  if (fs[0] == 'i' || fs[0] == 'n' || fs[0] == 'I' || fs[0] == 'N') {
348  continue;
349  }
350  if (sscanf(fs, "%lf", &d) == 1) {
351  /* but if at end of line, leave at beginning of next*/
352  if (fscanf(fi, "\n")) {
353  ;
354  } /* ignore return value */
355  break;
356  }
357  }
358  return d;
359 }
360 
362  double d;
363  char fs[256];
364 
365  for (;;) {
366  if (nrn_fw_fscanf(fi, "%255s", fs) == EOF) {
367  execerror("EOF in fscan", (char*) 0);
368  }
369  if (fs[0] == 'i' || fs[0] == 'n' || fs[0] == 'I' || fs[0] == 'N') {
370  continue;
371  }
372  if (sscanf(fs, "%lf", &d) == 1) {
373  /* but if at end of line, leave at beginning of next*/
374  nrnignore = nrn_fw_fscanf(fi, "\n");
375  break;
376  }
377  }
378  return d;
379 }
380 
381 void Fscan(void) /* read a number from input file */
382 {
383  double d;
384  NrnFILEWrap* fi;
385 
386  if (nrn_fw_eq(frin, stdin)) {
387  fi = fin;
388  } else {
389  fi = frin;
390  }
391  d = hoc_fw_scan(fi);
392  ret();
393  pushx(d);
394 }
395 
396 void hoc_Getstr(void) /* read a line (or word) from input file */
397 {
398  char* buf;
399  char** cpp;
400  NrnFILEWrap* fi;
401  int word = 0;
402  if (nrn_fw_eq(frin, stdin)) {
403  fi = fin;
404  } else {
405  fi = frin;
406  }
407  cpp = hoc_pgargstr(1);
408  if (ifarg(2)) {
409  word = (int) chkarg(2, 0., 1.);
410  }
411  if (word) {
412  buf = hoc_tmpbuf->buf;
413  if (nrn_fw_fscanf(fi, "%s", buf) != 1) {
414  execerror("EOF in getstr", (char*) 0);
415  }
416  } else {
417  if ((buf = fgets_unlimited(hoc_tmpbuf, fi)) == (char*) 0) {
418  execerror("EOF in getstr", (char*) 0);
419  }
420  }
421  hoc_assign_str(cpp, buf);
422  ret();
423  pushx((double) strlen(buf));
424 }
425 
426 void hoc_sprint1(char** ppbuf, int argn) { /* convert args to right type for conversion */
427  /* argn is argument number where format is */
428  static HocStr* hs;
429  char *pbuf, *pfmt, *pfrag, frag[120];
430  int n, convflag, lflag, didit; //, hoc_argtype();
431  char *fmt, *cp;
432 
433  if (!hs) {
434  hs = hocstr_create(512);
435  }
436  fmt = gargstr(argn++);
437  convflag = lflag = didit = 0;
438  pbuf = hs->buf;
439  pfrag = frag;
440  *pfrag = 0;
441  *pbuf = 0;
442 
443  for (pfmt = fmt; *pfmt; pfmt++) {
444  *pfrag++ = *pfmt;
445  *pfrag = 0;
446  if (convflag) {
447  switch (*pfmt) {
448  case 'l':
449  lflag += 1;
450  break;
451 
452  case 'd':
453  case 'o':
454  case 'x':
455  if (lflag) {
456  if (lflag == 1) {
457  pfrag[1] = pfrag[0];
458  pfrag[0] = pfrag[-1];
459  pfrag[-1] = 'l';
460  }
461  Sprintf(pbuf, frag, (long long) *getarg(argn));
462  } else {
463  Sprintf(pbuf, frag, (int) *getarg(argn));
464  }
465  didit = 1;
466  break;
467 
468  case 'c':
469  Sprintf(pbuf, frag, (char) *getarg(argn));
470  didit = 1;
471  break;
472 
473  case 'f':
474  case 'e':
475  case 'g':
476  Sprintf(pbuf, frag, *getarg(argn));
477  didit = 1;
478  break;
479 
480  case 's':
481  if (hoc_is_object_arg(argn)) {
482  cp = hoc_object_name(*hoc_objgetarg(argn));
483  } else {
484  cp = gargstr(argn);
485  }
486  n = pbuf - hs->buf;
487  hocstr_resize(hs, n + strlen(cp) + 100);
488  pbuf = hs->buf + n;
489  Sprintf(pbuf, frag, cp);
490  didit = 1;
491  break;
492 
493  case '%':
494  pfrag[-1] = 0;
495  strcpy(pbuf, frag);
496  didit = 1;
497  argn--; /* an arg was not consumed */
498  break;
499 
500  default:
501  break;
502  }
503  } else if (*pfmt == '%') {
504  convflag = 1;
505  } else if (pfrag - frag > 100) {
506  n = pbuf - hs->buf;
507  hocstr_resize(hs, n + strlen(frag) + 100);
508  pbuf = hs->buf + n;
509  Sprintf(pbuf, "%s", frag);
510  pfrag = frag;
511  *pfrag = 0;
512  while (*pbuf) {
513  pbuf++;
514  }
515  }
516 
517  if (didit) {
518  int n;
519  argn++;
520  lflag = 0;
521  convflag = 0;
522  didit = 0;
523  pfrag = frag;
524  *pfrag = 0;
525  while (*pbuf) {
526  pbuf++;
527  }
528  n = pbuf - hs->buf;
529  hocstr_resize(hs, n + 100);
530  pbuf = hs->buf + n;
531  }
532  }
533  if (pfrag != frag)
534  Sprintf(pbuf, "%s", frag);
535  *ppbuf = hs->buf;
536 }
537 
538 #if defined(__TURBOC__) || defined(__GO32__) || defined(WIN32) || defined(MAC)
539 static FILE* oc_popen(char* cmd, char* type) {
540  FILE* fp;
541  char buf[1024];
542  assert(strlen(cmd) + 20 < 1024);
543  sprintf(buf, "sh %s > hocload.tmp", cmd);
544  if (system(buf) != 0) {
545  return (FILE*) 0;
546  } else if ((fp = fopen("hocload.tmp", "r")) == (FILE*) 0) {
547  return (FILE*) 0;
548  } else {
549  return fp;
550  }
551 }
552 static void oc_pclose(FILE* fp) {
553  fclose(fp);
554  unlink("hocload.tmp");
555 }
556 #else
557 #define oc_popen popen
558 #define oc_pclose pclose
559 #endif
560 
561 static int hoc_Load_file(int, const char*);
562 
563 static void hoc_load(const char* stype) {
564  int i = 1;
565  char* s;
566  Symbol* sym;
567  char cmd[1024];
568  FILE* p;
569  char file[1024], *f;
570 
571  while (ifarg(i)) {
572  s = gargstr(i);
573  ++i;
574  sym = hoc_lookup(s);
575  if (!sym || sym->type == UNDEF) {
576  assert(strlen(stype) + strlen(s) + 50 < 1024);
577  sprintf(cmd, "$NEURONHOME/lib/hocload.sh %s %s %d", stype, s, hoc_pid());
578  p = oc_popen(cmd, "r");
579  if (p) {
580  f = fgets(file, 1024, p);
581  if (f) {
582  f[strlen(f) - 1] = '\0';
583  }
584  oc_pclose(p);
585  if (f) {
586  fprintf(stderr, "Getting %s from %s\n", s, f);
587  hoc_Load_file(0, f);
588  } else {
589  fprintf(stderr, "Couldn't find a file that declares %s\n", s);
590  }
591  } else {
592  hoc_execerror("can't run:", cmd);
593  }
594  }
595  }
596 }
597 
598 void hoc_load_proc(void) {
599  hoc_load("proc");
600  ret();
601  pushx(1.);
602 }
603 void hoc_load_func(void) {
604  hoc_load("func");
605  ret();
606  pushx(1.);
607 }
608 void hoc_load_template(void) {
609  hoc_load("begintemplate");
610  ret();
611  pushx(1.);
612 }
613 
614 void hoc_load_file(void) {
615  int iarg = 1;
616  int i = 0;
617  if (hoc_is_double_arg(iarg)) {
618  i = (int) chkarg(iarg, 0., 1.);
619  iarg = 2;
620  }
621  if (!ifarg(iarg + 1) || !hoc_lookup(gargstr(iarg + 1))) {
622  i = hoc_Load_file(i, gargstr(iarg));
623  }
624  ret();
625  pushx((double) i);
626 }
627 
628 static int hoc_Load_file(int always, const char* name) {
629  /*
630  if always is 0 then
631  xopen only if file of that name not already loaded with one of
632  the load_xxx functions
633  and search in the current, $HOC_LIBRARY_PATH,
634  $NEURONHOME/lib/hoc directories (in that order) for
635  the file if there is no directory prefix.
636  Temporarily change to the directory containing the file so
637  that it can xopen files relative to its location.
638  */
639 #define hoc_load_file_size_ 1024
640  static hoc_List* loaded;
641  hoc_Item* q;
642  int b, is_loaded;
643  int goback;
644  char expname[hoc_load_file_size_];
645  const char* base;
646  char path[hoc_load_file_size_], old[hoc_load_file_size_];
648 #if USE_NRNFILEWRAP
649  int f;
650 #else
651  FILE* f;
652 #endif
653 
654  old[0] = '\0';
655  goback = 0;
656  /* has the file already been loaded */
657  is_loaded = 0;
658  if (!loaded) {
659  loaded = hoc_l_newlist();
660  }
661  ITERATE(q, loaded) {
662  if (strcmp(STR(q), name) == 0) {
663  if (!always) {
664  return 1;
665  } else {
666  is_loaded = 1;
667  }
668  }
669  }
670 
671  /* maybe the name already has an explicit path */
672  expname[hoc_load_file_size_ - 1] = '\0';
673  strncpy(expname, expand_env_var(name), hoc_load_file_size_);
674  assert(expname[hoc_load_file_size_ - 1] == '\0');
675  name = expname;
676  if ((base = strrchr(name, '/')) != NULL) {
677  strncpy(path, name, base - name);
678  path[base - name] = '\0';
679  ++base;
680 #if USE_NRNFILEWRAP
681  f = nrn_fw_readaccess(name);
682 #else
683  f = fopen(name, "r");
684 #endif
685  } else {
686  base = name;
687  path[0] = '\0';
688  /* otherwise find the file in the default directories */
689 #if USE_NRNFILEWRAP
690  f = nrn_fw_readaccess(base);
691 #else
692  f = fopen(base, "r"); /* cwd */
693 #endif
694 #if !MAC
695  if (!f) { /* try HOC_LIBRARY_PATH */
696  char* hlp;
697  hlp = getenv("HOC_LIBRARY_PATH");
698  while (hlp && *hlp) {
699  char* cp = strchr(hlp, ':');
700  if (!cp) {
701  cp = strchr(hlp, ' ');
702  }
703  if (!cp) {
704  cp = hlp + strlen(hlp);
705  }
706  assert(cp - hlp < hoc_load_file_size_);
707  strncpy(path, hlp, cp - hlp);
708  path[cp - hlp] = '\0';
709  if (*cp) {
710  hlp = cp + 1;
711  } else {
712  hlp = 0;
713  }
714  if (path[0]) {
715  nrn_assert(snprintf(fname, hoc_load_file_size_, "%s/%s", path, base) <
717 #if USE_NRNFILEWRAP
718  f = nrn_fw_readaccess(expand_env_var(fname));
719 #else
720  f = fopen(expand_env_var(fname), "r");
721 #endif
722  if (f) {
723  break;
724  }
725  } else {
726  break;
727  }
728  }
729  }
730 #endif
731  if (!f) { /* try NEURONHOME/lib/hoc */
732  sprintf(path, "$(NEURONHOME)/lib/hoc");
733  assert(strlen(path) + strlen(base) + 1 < hoc_load_file_size_);
734  nrn_assert(snprintf(fname, hoc_load_file_size_, "%s/%s", path, base) <
736 #if USE_NRNFILEWRAP
737  f = nrn_fw_readaccess(expand_env_var(fname));
738 #else
739  f = fopen(expand_env_var(fname), "r");
740 #endif
741  }
742  }
743  /* add the name to the list of loaded packages */
744  if (f) {
745  if (!is_loaded) {
746  hoc_l_lappendstr(loaded, name);
747  }
748 #if USE_NRNFILEWRAP == 0
749  fclose(f);
750 #endif
751  b = 1;
752  } else {
753  b = 0;
754  hoc_warning("Couldn't find:", name);
755  path[0] = '\0';
756  }
757  /* change to the right directory*/
758  if (b && path[0]) {
759  goback = (getcwd(old, 1000) != 0);
760  errno = 0;
761  if (chdir(expand_env_var(path)) == -1) {
762  hoc_warning("Couldn't change directory to:", path);
763  path[0] = '\0';
764  b = 0;
765  }
766  /*printf("load_file cd to %s\n", path);*/
767  }
768  /* xopen the file */
769  if (b) {
770  /*printf("load_file xopen %s\n", base);*/
771  nrn_assert(strlen(base) < hoc_load_file_size_);
772  snprintf(cmd,
773  hoc_load_file_size_ + 50,
774  "hoc_ac_ = execute1(\"{xopen(\\\"%s\\\")}\")\n",
775  base);
776  b = hoc_oc(cmd);
777  b = (int) hoc_ac_;
778  }
779  /* change back */
780  if (path[0] && goback) {
781  if (hoc_chdir(old) == -1) {
782  hoc_warning("Couldn't change directory back to:", old);
783  b = 0;
784  }
785  /*printf("load_file cd back to %s\n", old);*/
786  }
787 
788  return b;
789 }
790 extern "C" char* hoc_back2forward(char*);
791 void hoc_getcwd(void) {
792  int len;
793  static char* buf;
794  if (!buf) {
795  buf = static_cast<char*>(emalloc(hoc_load_file_size_));
796  }
797  if (!getcwd(buf, hoc_load_file_size_)) {
798  hoc_execerror("getcwd failed. Perhaps the path length is > hoc_load_file_size_", (char*) 0);
799  }
800 #if defined(WIN32)
801  { strcpy(buf, hoc_back2forward(buf)); }
802 #endif
803  len = strlen(buf);
804 #if defined(MAC)
805  if (buf[len - 1] != ':') {
806  buf[len] = ':';
807  buf[len + 1] = '\0';
808  }
809 #else
810  if (buf[len - 1] != '/') {
811  buf[len] = '/';
812  buf[len + 1] = '\0';
813  }
814 #endif
815  hoc_ret();
816  hoc_pushstr(&buf);
817 }
818 
819 void hoc_machine_name(void) {
820 #if !defined(__GO32__) && !defined(WIN32) && !defined(MAC)
821  /*----- functions called -----*/
822  /*----- local variables -----*/
823  char buf[20];
824 
825  gethostname(buf, 20);
827 #endif
828  ret();
829  pushx(0.);
830 }
831 
832 int hoc_chdir(const char* path) {
833  return chdir(expand_env_var(path));
834 }
835 
836 void hoc_Chdir(void) {
837  int i = hoc_chdir(gargstr(1));
838  ret();
839  pushx((double) i);
840 }
841 
843 static int (*nrnpy_pr_stdoe_callback)(int, char*);
844 static int (*nrnpy_pass_callback)();
845 
846 extern "C" void nrnpy_set_pr_etal(int (*cbpr_stdoe)(int, char*), int (*cbpass)()) {
848  nrnpy_pr_stdoe_callback = cbpr_stdoe;
849  nrnpy_pass_callback = cbpass;
850  }
851 }
852 
853 void nrnpy_pass() {
854  if (nrnpy_pass_callback) {
855  if ((*nrnpy_pass_callback)() != 1) {
856  hoc_execerror("nrnpy_pass", 0);
857  }
858  }
859 }
860 
861 static int vnrnpy_pr_stdoe(FILE* stream, const char* fmt, va_list ap) {
862  int size = 0;
863  char* p = NULL;
864 
865  if (!nrnpy_pr_stdoe_callback || (stream != stderr && stream != stdout)) {
866  size = vfprintf(stream, fmt, ap);
867  return size;
868  }
869 
870  /* Determine required size */
871  va_list apc;
872 #ifndef va_copy
873 #if defined(__GNUC__) || defined(__clang__)
874 #define va_copy(dest, src) __builtin_va_copy(dest, src)
875 #else
876 #define va_copy(dest, src) (dest = src)
877 #endif
878 #endif
879  va_copy(apc, ap);
880  size = vsnprintf(p, size, fmt, apc);
881  va_end(apc);
882 
883  if (size < 0)
884  return 0;
885 
886  size++; /* For '\0' */
887  p = static_cast<char*>(malloc(size));
888  if (p == NULL)
889  return 0;
890 
891  size = vsnprintf(p, size, fmt, ap);
892  if (size < 0) {
893  free(p);
894  return 0;
895  }
896 
897  // if any non-ascii translate to '?' or nrnpy_pr will raise an exception.
898  if (stream == stderr) {
899  for (int i = 0; p[i] != '\0'; ++i) {
900  if (!isascii((unsigned char) p[i])) {
901  p[i] = '?';
902  }
903  }
904  }
905 
906  (*nrnpy_pr_stdoe_callback)((stream == stderr) ? 2 : 1, p);
907 
908  free(p);
909  return size;
910 }
911 
912 int nrnpy_pr(const char* fmt, ...) {
913  int n;
914  va_list ap;
915  va_start(ap, fmt);
916  n = vnrnpy_pr_stdoe(stdout, fmt, ap);
917  va_end(ap);
918  return n;
919 }
920 
921 int Fprintf(FILE* stream, const char* fmt, ...) {
922  int n;
923  va_list ap;
924  va_start(ap, fmt);
925  n = vnrnpy_pr_stdoe(stream, fmt, ap);
926  va_end(ap);
927  return n;
928 }
929 
930 /** printf style specification of hoc_execerror message. (512 char limit) **/
931 void hoc_execerr_ext(const char* fmt, ...) {
932  int size; // vsnprintf returns -1 on error.
933  va_list ap;
934 
935  // determine the message size
936  va_start(ap, fmt);
937  size = vsnprintf(NULL, 0, fmt, ap);
938  va_end(ap);
939 
940  if (size >= 0) {
941  constexpr size_t maxsize = 512;
942  char s[maxsize + 1];
943  va_start(ap, fmt);
944  size = vsnprintf(s, maxsize, fmt, ap);
945  va_end(ap);
946  if (size >= 0) {
947  s[maxsize] = '\0'; // truncate if too long
948  hoc_execerror(s, NULL);
949  }
950  }
951  hoc_execerror("hoc_execerr_ext failure with format:", fmt);
952 }
short type
Definition: cabvars.h:9
static Frame * fp
Definition: code.cpp:161
void pushx(double d)
Definition: code.cpp:658
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)
double chkarg(int, double low, double high)
Definition: code2.cpp:638
static int vnrnpy_pr_stdoe(FILE *stream, const char *fmt, va_list ap)
Definition: fileio.cpp:861
void hoc_load_template(void)
Definition: fileio.cpp:608
void hoc_Sprint(void)
Definition: fileio.cpp:327
static void hoc_load(const char *stype)
Definition: fileio.cpp:563
static int(* nrnpy_pass_callback)()
Definition: fileio.cpp:844
#define va_copy(dest, src)
void xopen(void)
Definition: fileio.cpp:291
char * hoc_xopen_file_
Definition: fileio.cpp:201
void hoc_load_file(void)
Definition: fileio.cpp:614
double hoc_fw_scan(NrnFILEWrap *fi)
Definition: fileio.cpp:361
#define oc_pclose
Definition: fileio.cpp:558
NrnFILEWrap * frin
Definition: fileio.cpp:22
void ropen(void)
Definition: fileio.cpp:71
void Fprint(void)
Definition: fileio.cpp:302
static int(* nrnpy_pr_stdoe_callback)(int, char *)
Definition: fileio.cpp:843
int nrn_is_python_extension
Definition: fileio.cpp:842
void hoc_getcwd(void)
Definition: fileio.cpp:791
static int hoc_Load_file(int, const char *)
Definition: fileio.cpp:628
size_t hoc_xopen_file_size_
Definition: fileio.cpp:200
void PRintf(void)
Definition: fileio.cpp:313
void hoc_load_func(void)
Definition: fileio.cpp:603
#define oc_popen
Definition: fileio.cpp:557
void hoc_machine_name(void)
Definition: fileio.cpp:819
void hoc_load_proc(void)
Definition: fileio.cpp:598
jmp_buf begin
Definition: hoc.cpp:193
char * hoc_back2forward(char *)
void wopen(void)
Definition: fileio.cpp:99
void nrnpy_set_pr_etal(int(*cbpr_stdoe)(int, char *), int(*cbpass)())
Definition: fileio.cpp:846
FILE * fout
Definition: fileio.cpp:23
char * hoc_current_xopen(void)
Definition: fileio.cpp:203
char * neuron_home
Definition: hoc_init.cpp:404
void hoc_Getstr(void)
Definition: fileio.cpp:396
void hoc_stdout(void)
Definition: fileio.cpp:40
#define hoc_load_file_size_
void hoc_Chdir(void)
Definition: fileio.cpp:836
void Fscan(void)
Definition: fileio.cpp:381
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
char buf[512]
Definition: init.cpp:13
int hoc_xopen1(const char *name, const char *rcs)
Definition: fileio.cpp:207
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
void hoc_xopen_from_audit(const char *fname)
Definition: audit.cpp:254
void hoc_pushstr(char **d)
Definition: code.cpp:680
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
Definition: fileio.cpp:931
void hoc_audit_from_xopen1(const char *fname, const char *rcs)
Definition: audit.cpp:130
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2350
const char * expand_env_var(const char *s)
Definition: fileio.cpp:122
void hoc_ret()
int hoc_oc(const char *buf)
Definition: hoc.cpp:1471
void hoc_warning(const char *, const char *)
int hoc_is_double_arg(int narg)
Definition: code.cpp:744
int nrnpy_pr(const char *fmt,...)
Definition: fileio.cpp:912
int hoc_xopen_run(Symbol *sp, const char *str)
Definition: code.cpp:595
int hoc_chdir(const char *path)
Definition: fileio.cpp:832
int hoc_retrieving_audit(void)
Definition: audit.cpp:185
double hoc_ac_
Definition: hoc_init.cpp:397
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:72
void nrnpy_pass()
Definition: fileio.cpp:853
int nrnignore
Definition: hoc.cpp:26
void hoc_sprint1(char **ppbuf, int argn)
Definition: fileio.cpp:426
Symbol * hoc_lookup(const char *)
int Fprintf(FILE *stream, const char *fmt,...)
Definition: fileio.cpp:921
double hoc_scan(FILE *fi)
Definition: fileio.cpp:339
int hoc_pid(void)
Definition: hoc.cpp:877
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1599
char * fgets_unlimited(HocStr *s, NrnFILEWrap *f)
Definition: hoc.cpp:955
HocStr * hoc_tmpbuf
Definition: hoc.cpp:164
HocStr * hocstr_create(size_t size)
Definition: hoc.cpp:945
int pipeflag
Definition: hoc.cpp:147
void hocstr_resize(HocStr *hs, size_t n)
Definition: hoc.cpp:964
#define assert(ex)
Definition: hocassrt.h:32
void * erealloc(void *ptr, size_t n)
Definition: symbol.cpp:263
#define ERRCHK(c1)
Definition: hocdec.h:369
#define getarg
Definition: hocdec.h:15
#define gargstr
Definition: hocdec.h:14
#define NOT_PARALLEL_SUB(c1)
Definition: hocdec.h:379
hoc_Item * hoc_l_lappendstr(hoc_List *, const char *)
hoc_List * hoc_l_newlist()
int hoc_lineno
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
int ifarg(int)
Definition: code.cpp:1581
void debugfile(const char *,...)
char * getenv(const char *s)
Definition: macprt.cpp:67
static char * format
Definition: matrixio.c:386
#define i
Definition: md1redef.h:12
#define STR(q)
Definition: model.h:87
#define ITERATE(itm, lst)
Definition: model.h:25
#define IGNORE(arg)
Definition: model.h:247
#define Sprintf
Definition: model.h:233
char * name
Definition: init.cpp:16
Item * prev(Item *item)
Definition: list.cpp:93
char * emalloc(unsigned n)
Definition: list.cpp:166
#define fprintf
Definition: mwprefix.h:30
#define nrn_assert(ex)
Definition: nrnassrt.h:53
#define nrn_fw_eq(fw, ff)
Definition: nrnfilewrap.h:43
#define nrn_fw_fclose
Definition: nrnfilewrap.h:44
#define nrn_fw_set_stdin()
Definition: nrnfilewrap.h:45
#define nrn_fw_fscanf
Definition: nrnfilewrap.h:50
#define NrnFILEWrap
Definition: nrnfilewrap.h:39
#define nrn_fw_fopen
Definition: nrnfilewrap.h:46
int const size_t const size_t n
Definition: nrngsl.h:11
size_t q
size_t p
#define plprint
Definition: redef.h:110
#define ret
Definition: redef.h:123
#define fin
Definition: redef.h:60
#define execerror
Definition: section.h:36
FILE * fopen()
#define NULL
Definition: sptree.h:16
Definition: hocstr.h:7
char * buf
Definition: hocstr.h:8
Definition: model.h:57
short type
Definition: model.h:58
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113