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