1 #ifndef __INTEL_LLVM_COMPILER
3 #pragma float_control(precise, on)
5 #pragma STDC FENV_ACCESS ON
8 #include <../../nrnconf.h>
27 #include "../nrniv/backtrace_utils.h"
29 #include "../utils/profile/profiler_interface.h"
32 #include <condition_variable>
39 #include "utils/logger.hpp"
48 #if defined(USE_PYTHON)
49 int use_python_interpreter = 0;
56 #define use_rl_getc_function
63 #define FEEXCEPT (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW)
65 const int e = std::fetestexcept(
FEEXCEPT);
69 fprintf(stderr,
"Floating exception: Divide by zero\n");
72 fprintf(stderr,
"Floating exception: Invalid (no well defined result\n");
75 fprintf(stderr,
"Floating exception: Overflow\n");
87 #if NRN_FLOAT_EXCEPTION
131 #define CHAR signed char
135 #define TMPBUFSIZE 512
147 #define EPS hoc_epsilon
159 #include <execinfo.h>
175 extern void ivoc_win32_cleanup();
178 static int follow(
int expect,
int ifyes,
int ifno);
185 printf(
"NEURON exiting abnormally, press return to quit\n");
192 #define HAS_SIGPIPE 0
194 #define HAS_SIGPIPE 1
199 fprintf(stderr,
"writing to a broken pipe\n");
219 #define YYNEEDMORE -3
224 static int lexstate = 0;
265 if ((
c =
getnb()) == EOF) {
268 if (
c ==
'/' &&
follow(
'*', 1, 0))
280 if (
c ==
'.' || isdigit(
c))
296 if (*npt ==
'.' && !isdigit(npt[1])) {
300 if (
c ==
'E' ||
c ==
'e') {
309 IGNORE(sscanf(npt,
"%lf", &d));
315 if (isalpha(
c) ||
c ==
'_') {
317 char sbuf[256], *
p = sbuf;
319 if (
p >= (sbuf + 255)) {
327 if (strncmp(sbuf,
"__nrnsec_0x", 11) == 0) {
329 return INTERNALSECTIONNAME;
339 if (strcmp(sbuf,
"_pysec") == 0) {
342 "Must be of form _pysec.secname where secname is the literal result of "
343 "nrn.Section.name() .",
358 "Must be of form _pysec.cellname.secname where cellname.secname is the "
359 "literal result of nrn.Section.name() .",
373 return s->type == UNDEF ? VAR :
s->type;
389 n = 10 *
n +
c -
'0';
408 if (
n >= sbuf->
size - 1) {
429 return follow(
'=', GE, GT);
431 return follow(
'=', LE, LT);
446 if (
follow(
'=', EQ,
'=') == EQ) {
468 return follow(
'\n',
'\n',
'\n');
477 }
else if (
follow(
'=', 1, 0)) {
489 static char transtab[] =
"b\bf\fn\nr\rt\t";
493 if (islower(
c) && strchr(transtab,
c))
494 return strchr(transtab,
c)[1];
498 static int follow(
int expect,
int ifyes,
int ifno)
520 if ((
OPVAL(sp) = (
double*)
hoc_Ecalloc((
unsigned)
i,
sizeof(
double))) == (
double*) 0) {
522 Fprintf(stderr,
"Not enough space for array %s\n", sp->
name);
529 double total, subscpt;
542 total = total * subscpt;
569 if (sp->
type == VAR) {
582 if (a->
a_varn != (
unsigned*) 0)
583 free((
char*) (a->
a_varn));
642 sigaddset(&set, SIGINT);
643 sigprocmask(SIG_UNBLOCK, &set,
NULL);
649 std::string message{
"hoc_execerror: "};
652 message.append(1,
' ');
685 const size_t nframes = 12;
686 void* frames[nframes];
688 char** bt_strings =
NULL;
690 size_t funcname_size = 256;
692 char* symbol =
static_cast<char*
>(malloc(
sizeof(
char) * funcname_size));
694 char* funcname =
static_cast<char*
>(malloc(
sizeof(
char) * funcname_size));
696 char* offset =
static_cast<char*
>(malloc(
sizeof(
char) * 10));
700 size = backtrace(frames, nframes);
703 Fprintf(stderr,
"Backtrace:\n");
705 bt_strings = backtrace_symbols(frames, size);
709 for (
i = 2;
i < size; ++
i) {
715 Fprintf(stderr,
"\t%s : %s+%s\n", bt_strings[
i], funcname, offset);
717 Fprintf(stderr,
"\t%s : %s()+%s\n", bt_strings[
i], symbol, offset);
720 Fprintf(stderr,
"\t%s\n", bt_strings[
i]);
729 Fprintf(stderr,
"No backtrace info available.\n");
737 #if NRN_FLOAT_EXCEPTION
740 Fprintf(stderr,
"Floating point exception\n");
752 Fprintf(stderr,
"Segmentation violation\n");
763 Fprintf(stderr,
"Bus error\n");
769 hoc_execerror(
"Aborting. ",
"See $NEURONHOME/lib/help/oc.help");
774 return (
int) getpid();
820 "Copyright 1992 - Michael Hines, Neurobiology Dept., DUMC, Durham, NC. 27710\n");
832 hs->
buf =
static_cast<char*
>(
emalloc(size + 1));
868 int exit_status = EXIT_SUCCESS;
870 extern void hoc_set_unhandled_exception_filter();
871 hoc_set_unhandled_exception_filter();
888 if (
argc > 2 && strcmp(
argv[1],
"-bbs_nhost") == 0) {
896 static const char* stdinonly[] = {
"-"};
916 }
catch (std::exception
const& e) {
917 Fprintf(stderr, fmt::format(
"hoc_main1 caught exception: {}\n", e.what()).c_str());
924 std::mutex inputMutex_;
925 std::condition_variable inputCond_;
928 std::thread* inputReady_;
932 extern "C" int getch();
934 void inputReadyThread() {
939 std::unique_lock<std::mutex>
lock{inputMutex_};
943 inputCond_.wait(
lock);
945 printf(
"inputReadyThread done\n");
950 #if defined(USE_PYTHON)
961 #if READLINE && !defined(MINGW)
965 #if defined(WIN32) && HAVE_IV
966 ivoc_win32_cleanup();
968 auto tmp_dir = std::getenv(
"TEMP");
969 auto path = std::filesystem::path(tmp_dir ? std::string(tmp_dir) :
"/tmp") /
970 fmt::format(
"oc{}.hl",
hoc_pid());
978 #if defined(USE_PYTHON)
985 (*p_nrnpython_finalize)();
994 static const char* double_at2space(
const char*
infile) {
999 for (cp1 =
infile; *cp1; ++cp1) {
1000 if (*cp1 ==
'@' && cp1[1] ==
'@') {
1009 for (cp1 =
infile, cp2 =
buf; *cp1; ++cp1, ++cp2) {
1010 if (*cp1 ==
'@' && cp1[1] ==
'@') {
1029 if (
gargc == 0 && cygonce == 0) {
1034 #if defined(USE_PYTHON)
1035 return use_python_interpreter ? 0 : 1;
1053 char* cp = strdup(
infile + 1);
1054 for (++cp; *cp; ++cp) {
1071 #if defined(USE_PYTHON)
1072 if (use_python_interpreter) {
1082 if (strcmp(
infile,
"-") == 0) {
1086 }
else if (strcmp(
infile,
"-parallel") == 0) {
1091 }
else if (strcmp(
infile,
"-c") == 0) {
1162 signals[2] = signal(SIGSEGV, sigsegvcatch);
1164 signals[3] = signal(SIGBUS, sigbuscatch);
1188 template <
typename T>
1205 auto*
const sav_fin =
hoc_fin;
1208 auto const loop_body = []() {
1234 }
catch (std::exception
const& e) {
1236 Fprintf(stderr,
"hoc_run1: caught exception");
1237 std::string_view what{e.what()};
1238 if (!what.empty()) {
1239 Fprintf(stderr, fmt::format(
": {}", what).c_str());
1244 return EXIT_FAILURE;
1249 return EXIT_SUCCESS;
1288 if (cp[-1] ==
'\n') {
1293 if (cp[-1] !=
'\n') {
1321 auto const kernel = [
buf]() {
1344 }
catch (std::exception
const& e) {
1345 os <<
"hoc_oc caught exception: " << e.what() << std::endl;
1377 if (!isprint((
int) (*cp)) && !isspace((
int) (*cp))) {
1379 "%scharacter \\%03o at position %ld is not printable\n",
1381 ((
int) (*cp) & 0xff),
1468 }
while (
i ==
'\n');
1473 #define INTERVIEWS 1
1487 extern "C" int (*rl_getc_function)(void);
1488 extern "C" int rl_getc(
void);
1489 static int getc_hook(
void) {
1492 inputReady_ =
new std::thread{inputReadyThread};
1494 inputMutex_.unlock();
1497 while (!inputReadyFlag_) {
1501 inputReadyFlag_ = 0;
1502 int i = inputReadyVal_;
1504 inputCond_.notify_one();
1509 #if defined(use_rl_getc_function)
1512 extern int iv_dialog_is_running;
1513 extern "C" int (*rl_getc_function)(void);
1514 static int getc_hook(
void) {
1522 if ((r =
read(0, &
c,
sizeof(
c))) ==
sizeof(
c)) {
1535 if (errno != EINTR) {
1544 extern int (*rl_event_hook)(void);
1545 static int event_hook(
void) {
1585 if (
c == EOF ||
c == nl1 ||
c == nl2) {
1601 if (bufstr->
size <=
i) {
1606 bufstr->
buf[
i + 1] =
'\0';
1615 hoc_execerror(
"Internal error:",
"Not finished with previous input line");
1640 rl_getc_function = getc_hook;
1643 rl_getc_function = rl_getc;
1647 #if defined(use_rl_getc_function)
1649 rl_getc_function = getc_hook;
1652 rl_getc_function = getc_hook;
1656 rl_event_hook = event_hook;
1659 rl_event_hook =
NULL;
1665 extern int hoc_notify_stop;
1669 for (
int i = 0;
i <
n; ++
i) {
1670 if (!isascii(line[
i])) {
1671 hoc_execerr_ext(
"Non-ASCII character value 0x%hhx at input position %d\n",
1683 if (line && *line) {
1731 hoc_warning(
"Help only available from version with ivoc library", 0);
int cxx_demangle(const char *symbol, char **funcname, size_t *funcname_sz)
int parse_bt_symbol(char *backtrace_line, void **addr, char *symbol, char *offset)
char * hoc_strgets(char *cbuf, int nc)
int hoc_strgets_need(void)
double chkarg(int, double low, double high)
void hoc_audit_command(const char *buf)
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
void hoc_execerror(const char *s, const char *t)
int hoc_arayinfo_install(Symbol *sp, int nsub)
void hoc_final_exit(void)
int hoc_errno_check(void)
int hoc_ParseExec(int yystart)
void hoc_freearay(Symbol *sp)
void * hoc_sec_internal_name2ptr(const char *s, int eflag)
void * nrn_parsing_pysec_
Symbol * hoc_install(const char *, int, double, Symlist **)
void hoc_oop_initaftererror(void)
void hoc_audit_from_final_exit(void)
int hoc_oc(const char *buf)
void hoc_warning(const char *s, const char *t)
void ivoc_help(const char *)
void * hoc_pysec_name2ptr(const char *s, int)
int hoc_main1(int argc, const char **argv, const char **envp)
void hoc_free_val_array(double *, std::size_t)
void hoc_audit_from_hoc_main1(int argc, const char **argv, const char **envp)
void hoc_execerror_mes(const char *s, const char *t, int prnt)
size_t hoc_total_array(Symbol *s)
Symbol * hoc_lookup(const char *)
void hoc_free_arrayinfo(Arrayinfo *a)
int nrn_mpiabort_on_error_
static void unGetc(int c, NrnFILEWrap *fp)
static void set_signals(void)
int nrn_try_catch_nest_depth
How many NEURON try { ...
char * fgets_unlimited(HocStr *s, NrnFILEWrap *f)
static int debug_message_
void hoc_main1_init(const char *pname, const char **envp)
void hoc_defnonly(const char *s)
int hoc_execerror_messages
void add_history(const char *)
static void matherr1(void)
static CHAR * fgets_unlimited_nltrans(HocStr *s, NrnFILEWrap *f, int nltrans)
HocStr * hocstr_create(size_t size)
int hoc_print_first_instance
void nrn_feenableexcept()
static SignalType * signals[4]
static int Getc(NrnFILEWrap *fp)
void oc_restore_input_info(const char *i1, int i2, int i3, NrnFILEWrap *i4)
size_t hoc_xopen_file_size_
void hocstr_copy(HocStr *hs, const char *buf)
static void restore_signals(void)
CHAR * hoc_fgets_unlimited(HocStr *bufstr, NrnFILEWrap *f)
void hoc_arayinstal(void)
const char * hoc_promptstr
void oc_save_input_info(const char **i1, int *i2, int *i3, NrnFILEWrap **i4)
__attribute__((noreturn)) void sigsegvcatch(int)
static int backslash(int c)
static void nrn_inputbuf_getline(void)
void hocstr_resize(HocStr *hs, size_t n)
void hoc_coredump_on_error(void)
static char * optarray(char *buf)
char * readline(const char *prompt)
static const char * nrn_inputbufptr
void hocstr_delete(HocStr *hs)
void hoc_show_errmess_always(void)
static void sigpipe_handler(int sig)
static int follow(int expect, int ifyes, int ifno)
void rl_deprep_terminal(void)
int(* p_nrnpy_pyrun)(const char *fname)
void start_profile(int i)
void hoc_acterror(const char *, const char *)
void(* p_nrnpython_finalize)()
void nrn_err_dialog(const char *mes)
void move(Item *q1, Item *q2, Item *q3)
static void finalize_profile()
void * erealloc(void *ptr, size_t size)
static void * emalloc(size_t size)
impl_ptrs methods
Collection of pointers to functions with python-version-specific implementations.
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
@ read
variable is ready only
static void prnt(const TQItem *b, int level)
#define nrn_fw_eq(fw, ff)
#define nrn_fw_set_stdin()
#define nrn_fw_ungetc(c, fw)
int const size_t const size_t n
void nrnmpi_abort(int errcode)
void * hoc_Ecalloc(std::size_t n, std::size_t size)
int nrnmpi_numprocs_world
HOC interpreter function declarations (included by hocdec.h)
static double remove(void *v)
static const char ** pname(void *v)
void(* interpreter_set_path)(std::string_view)
int(* interpreter_start)(int)
temporarily_change(T &global, T new_value)
Helper type for incrementing/decrementing nrn_try_catch_nest_depth.
int Fprintf(FILE *stream, const char *fmt, Args... args)