1 #include <../../nrnconf.h>
33 #define EXTERNAL_TYPE 2
52 auto const code =
hoc_oc(
"objref hoc_obj_[2]\n");
88 for (
i = a->
nsub - 1;
i >= 0; --
i) {
113 for (
i = a->
nsub - 1;
i >= 0; --
i) {
152 if (sym->
type != UNDEF) {
172 OPSTR(sym) = (
char**) 0;
195 #define NTEMPLATESTACK 20
206 #define pushtemplatesym(arg) \
208 (templatestackp++)->sym = arg
209 #define pushtemplatesymlist(arg) \
211 (templatestackp++)->symlist = arg
212 #define pushtemplatei(arg) \
214 (templatestackp++)->i = arg
215 #define pushtemplateodata(arg) \
217 (templatestackp++)->odata = arg
218 #define pushtemplateo(arg) \
220 (templatestackp++)->o = arg
232 #define OBJ_STACK_SIZE 10
239 hoc_execerror(
"Can't do object_push for built-in class",
nullptr);
242 hoc_execerror(
"too many object context stack depth",
nullptr);
328 hoc_execerror(
"Can't execute in a built-in class context",
nullptr);
358 auto pbuf_size = 256;
359 if (strlen(cmd) > 256 - 10) {
362 pbuf_size = hs->
size + 1;
365 std::snprintf(pbuf, pbuf_size,
"%s\n", cmd + 1);
367 std::snprintf(pbuf, pbuf_size,
"{%s}\n", cmd);
453 printf(
"new object from template %s created.\n", symtemp->
name);
513 if (
s->cpublic != 2) {
517 ++
s->arayinfo->refcount;
520 obd[
s->u.oboff].
pval = (
double*)
emalloc(total *
sizeof(
double));
521 for (
i = 0;
i < total;
i++) {
522 (obd[
s->u.oboff].
pval)[
i] = 0.;
529 **(obd[
s->u.oboff].
ppstr) =
'\0';
533 ++
s->arayinfo->refcount;
537 for (
i = 0;
i < total;
i++) {
540 if (strcmp(
s->name,
"this") == 0) {
541 obd[
s->u.oboff].
pobj[0] = ob;
546 ++
s->arayinfo->refcount;
594 Object** obp = hoc_look_inside_stack<Object**>(
narg);
603 hoc_execerror(
"Assignment to $o only allowed if caller arg was declared as objref",
622 [ob]() -> std::string {
624 rval.append(
" constructor");
649 Inst *pcsav, callcode[4];
664 auto const error_prefix_generator = [ob, sym]() {
667 rval.append(sym->
name);
670 if (sym->
type == OBFUNCTION) {
682 }
else if (sym->
type == STRFUNCTION) {
698 callcode[1].
sym = sym;
699 callcode[2].
i =
narg;
706 if (sym->
type == PROCEDURE) {
726 Inst *stmtbegin, *stmtend;
736 stmtobj = hoc_look_inside_stack<Object*>(
narg + 1);
737 stmtbegin =
pc +
pc->i;
739 stmtend =
pc +
pc->i;
758 printf(
"declareing %s as objectvar\n", sym->
name);
760 if (sym->
type == OBJECTVAR) {
763 for (
i = 0;
i < total;
i++) {
769 sym->
type = OBJECTVAR;
779 for (
i = 0;
i < size;
i++) {
800 printf(
"code for hoc_objectvar()\n");
830 printf(
"code for hoc_objectarg()\n");
869 if (!sym || sym->
type != TEMPLATE) {
924 if (sym->
type == RANGEVAR) {
979 int nindex,
narg, cplus, isfunc;
986 printf(
"code for hoc_object_component()\n");
1004 int expect_stack_nsub{0};
1007 hoc_execerror(
"[...](...) syntax only allowed for array range variables:", sym0->
name);
1012 expect_stack_nsub = 1;
1051 auto err = fmt::format(
"'{}' not a public member of '{}'",
1054 Fprintf(stderr, fmt::format(
"{}\n", err).c_str());
1072 switch (sym->
type) {
1151 if (expect_stack_nsub) {
1167 case HOCOBJFUNCTION:
1170 if (expect_stack_nsub) {
1270 if ((
pc++)->
i != ITERATOR) {
1315 auto dh = hoc_pop_handle<double>();
1344 printf(
"code for hoc_object_eval\n");
1350 auto* d_sym = hoc_look_inside_stack<Symbol*>(0);
1351 if (d_sym->type == RANGEVAR) {
1362 }
else if (d_sym->type == VAR && d_sym->subtype ==
USERPROPERTY) {
1370 printf(
"code for hoc_ob_pointer\n");
1375 auto* d_sym = hoc_look_inside_stack<Symbol*>(0);
1376 if (d_sym->type == RANGEVAR) {
1380 double x = nindex ?
hoc_xpop() : .5;
1382 }
else if (d_sym->type == VAR && d_sym->subtype ==
USERPROPERTY) {
1404 auto* sym = hoc_look_inside_stack<Symbol*>(1);
1405 if (sym->type == RANGEVAR) {
1407 }
else if (sym->type == VAR && sym->subtype ==
USERPROPERTY) {
1411 if (type2 == RANGEVAR && type1 == NUMBER) {
1450 hoc_execerror(
"Invalid assignment operator for object",
nullptr);
1467 hoc_execerror(
"Invalid assignment operator for string",
nullptr);
1479 hoc_execerror(
"Invalid assignment operator for PythonObject",
nullptr);
1493 if (
s->type != TEMPLATE) {
1496 if (!s1 || s1->
type != TEMPLATE) {
1516 printf(
"begin template %s\n",
t->name);
1519 if (
type == TEMPLATE) {
1523 }
else if (
type != UNDEF) {
1524 hoc_execerror(
t->name,
"already used as something besides template");
1528 t->u.ctemplate->sym =
t;
1529 t->u.ctemplate->symtable = (
Symlist*) 0;
1530 t->u.ctemplate->dataspace_size = 0;
1531 t->u.ctemplate->constructor = 0;
1532 t->u.ctemplate->destructor = 0;
1533 t->u.ctemplate->is_point_ = 0;
1534 t->u.ctemplate->steer = 0;
1551 printf(
"end template %s\n",
t->name);
1554 if (strcmp(ts->
name,
t->name) != 0) {
1570 if (
s &&
s->type != PROCEDURE) {
1571 hoc_execerror(
"'init' can only be used as the initialization procedure for new objects",
1575 if (
s &&
s->type != PROCEDURE) {
1577 "'unref' can only be used as the callback procedure when the reference count is "
1605 t->constructor =
cons;
1612 s->u.u_proc->defn.pfd_vp = m[
i].
member;
1616 for (
i = 0; mobjret[
i].
name; ++
i) {
1618 s->u.u_proc->defn.pfo_vp = mobjret[
i].
member;
1622 for (
i = 0; strret[
i].
name; ++
i) {
1624 s->u.u_proc->defn.pfs_vp = strret[
i].
member;
1659 printf(
"public name %s with type %d\n",
s->name,
s->type);
1687 case HOCOBJFUNCTION:
1710 if (
t == OBJECTVAR) {
1715 if (
t == OBJECTVAR) {
1717 printf(
"dymnamic checking of type=%d\n",
type);
1721 }
else if (
type !=
t) {
1725 if (
t != OBJECTVAR) {
1741 if (
s->type == OBJECTVAR &&
s->cpublic != 2) {
1743 for (
i = 0;
i < total;
i++) {
1744 obp =
data[
s->u.oboff].pobj +
i;
1747 if ((*obp)->ctemplate == ctemplate) {
1753 (*obp)->u.dataspace);
1760 (*obp)->u.dataspace);
1762 if ((*obp)->ctemplate == ctemplate) {
1772 #define objectpath hoc_objectpath_impl
1773 #define pathprepend hoc_path_prepend
1814 if (
s->type == OBJECTVAR &&
s->cpublic != 2) {
1816 for (
i = 0;
i < total;
i++) {
1817 obp = od[
s->u.oboff].
pobj +
i;
1818 if (*obp && *obp != oblook &&
objectpath(ob, *obp, path, depth)) {
1835 hoc_warning(
"Couldn't find a pathname to the object pointer",
1854 if (obj == (
Object*) 0) {
1863 struct helper_in_case_dtor_throws {
1864 helper_in_case_dtor_throws(
Object* obj)
1866 ~helper_in_case_dtor_throws() {
1867 if (--m_obj->ctemplate->count <= 0) {
1870 m_obj->ctemplate =
nullptr;
1910 helper_in_case_dtor_throws _{obj};
1916 rval.append(
" destructor");
1942 if (
s->cpublic != 2) {
1955 if (strcmp(
"this",
s->name) != 0) {
1957 for (
i = 0;
i < total;
i++) {
1966 for (
i = 0;
i < total; ++
i) {
2019 if (
s->type == TEMPLATE) {
2023 for (
i = 0;
i < nspace; ++
i) {
2038 if (
s &&
s->type == TEMPLATE) {
2042 for (
i = 0;
i < nspace; ++
i) {
2067 if (
s->type == OBJECTVAR &&
s->cpublic != 2) {
2069 for (
i = 0;
i < total;
i++) {
2070 obp =
data[
s->u.oboff].pobj +
i;
2071 for (
id = 0;
id < depth;
id++) {
2075 Printf(
"obp %s[%d] -> %s with %d refs.\n",
2081 Printf(
"obp %s[%d] -> NULL\n",
s->name,
i);
2084 (*obp)->u.dataspace !=
data
2087 (*obp)->recurse = 1;
2089 (*obp)->u.dataspace,
2091 (*obp)->recurse = 0;
2104 Sprintf(
buf,
"object type is nullptr instead of");
void nrn_pushsec(Section *sec)
double cable_prop_eval(Symbol *sym)
void cable_prop_assign(Symbol *sym, double *pd, int op)
void nrn_rangeconst(Section *sec, Symbol *s, neuron::container::data_handle< double > pd, int op)
int node_index(Section *sec, double x)
returns nearest index to x
void new_sections(Object *ob, Symbol *sym, Item **pitm, int size)
Prop * nrn_mechanism_check(int type, Section *sec, int inode)
returns prop given mech type, section, and inode error if mech not at this position
neuron::container::data_handle< double > nrn_rangepointer(Section *sec, Symbol *s, double d)
void ob_sec_access_push(hoc_Item *qsec)
double * cable_prop_eval_pointer(Symbol *sym)
Symbol * hoc_table_lookup(const char *, Symlist *)
void hoc_iterator_object(Symbol *sym, int argcount, Inst *beginpc, Inst *endpc, Object *ob)
double chkarg(int, double low, double high)
static void destruct(void *v)
static void * cons(Object *o)
char * hoc_object_pathname(Object *ob)
void hoc_push_frame(Symbol *sp, int narg)
Object * hoc_name2obj(const char *name, int index)
void hoc_obj_set(int i, Object *obj)
void hoc_push_ndim(int d)
void hoc_construct_point(Object *, int)
int hoc_obj_run(const char *cmd, Object *ob)
Brief explanation of hoc_obj_run.
void * nrn_opaque_obj2pyobj(Object *ho)
void hoc_pushstr(char **d)
Object * nrn_nmodlrandom_wrap(Prop *prop, Symbol *sym)
double hoc_call_func(Symbol *s, int narg)
int ivoc_list_look(Object *ob, Object *oblook, char *path, int)
void hoc_new_object_asgn(Object **obp, Symbol *st, void *v)
size_t hoc_total_array_data(const Symbol *s, Objectdata *obd)
int hoc_arayinfo_install(Symbol *sp, int nsub)
Object ** hoc_temp_objvar(Symbol *symtemp, void *v)
void hoc_template_notify(Object *ob, int message)
void hoc_pushpx(double *d)
int hoc_inside_stacktype(int i)
void hoc_pushobj(Object **d)
int hoc_errno_check(void)
void hoc_call_ob_proc(Object *ob, Symbol *sym, int narg)
Object * hoc_obj_get(int i)
void hoc_freearay(Symbol *sp)
Symbol * hoc_install(const char *, int, double, Symlist **)
void hoc_free_object(Object *)
int hoc_is_str_arg(int narg)
void hoc_free_pstring(char **)
bool hoc_stack_type_is_ndim()
void hoc_oop_initaftererror(void)
Object * nrn_pntproc_nmodlrandom_wrap(void *v, Symbol *sym)
Objectdata * hoc_objectdata
void hoc_assign_str(char **cpp, const char *buf)
double hoc_opasgn(int op, double dest, double src)
double hoc_call_objfunc(Symbol *s, int narg, Object *ob)
Object * hoc_new_object(Symbol *symtemp, void *v)
int is_obj_type(Object *obj, const char *type_name)
int hoc_oc(const char *buf)
void check_obj_type(Object *obj, const char *type_name)
void hoc_obj_disconnect(Object *ob)
void hoc_obj_ref(Object *obj)
char * hoc_object_name(Object *ob)
void ivoc_free_alias(Object *ob)
void hoc_dec_refcount(Object **pobj)
void hoc_free_val_array(double *, std::size_t)
void hoc_install_object_data_index(Symbol *sp)
size_t hoc_total_array(Symbol *s)
Symbol * hoc_lookup(const char *)
void hoc_free_arrayinfo(Arrayinfo *a)
void hoc_obj_unref(Object *obj)
Symbol * ivoc_alias_lookup(const char *name, Object *ob)
void hoc_free_allobjects(cTemplate *ctemplate, Symlist *sl, Objectdata *data)
char * hoc_araystr(Symbol *sym, int index, Objectdata *obd)
void hoc_push_object(Object *d)
void hoc_push(neuron::container::generic_data_handle handle)
HocStr * hocstr_create(size_t size)
void hocstr_delete(HocStr *hs)
#define pushtemplatesym(arg)
void oc_save_hoc_oop(Object **a1, Objectdata **a2, int *a4, Symlist **a5)
Objectdata * hoc_objectdata_restore(Objectdata *obdsav)
static void call_constructor(Object *, Symbol *, int)
#define pushtemplatesymlist(arg)
void hoc_allobjects(void)
#define pushtemplatei(arg)
static Object * obj_stack_[OBJ_STACK_SIZE+1]
static Templatedatum * poptemplate(void)
static int connect_obsec_
void hoc_allobjectvars(void)
static Templatedatum templatestack[NTEMPLATESTACK]
void hoc_install_hoc_obj(void)
static void call_ob_iter(Object *ob, Symbol *sym, int narg)
Symbol * hoc_decl(Symbol *s)
Objectdata * hoc_objectdata_save(void)
void hoc_external_var(Symbol *s)
Symbol * nrnpy_pyobj_sym_
void hoc_asgn_obj_to_str(void)
int hoc_max_builtin_class_id
Symbol * hoc_which_template(Symbol *s)
void hoc_constobject(void)
static void free_objectdata(Objectdata *, cTemplate *)
void hoc_obvar_declare(Symbol *sym, int type, int pmes)
std::vector< const char * > py_exposed_classes
int hoc_print_first_instance
void class2oc_base(const char *name, ctor_f *cons, dtor_f *destruct, Member_func *m, Member_ret_obj_func *mobjret, Member_ret_str_func *strret)
struct Section * nrn_sec_pop()
static void hoc_list_allobjref(Symlist *, Objectdata *, int)
#define pushtemplateo(arg)
void hoc_ob_check(int type)
void hoc_endtemplate(Symbol *t)
Object * hoc_newobj1(Symbol *sym, int narg)
static Templatedatum * templatestackp
void hoc_object_push(void)
void hoc_newobj_ret(void)
void hoc_object_component()
static void hoc_allobjects2(Symbol *s, int nspace)
void hoc_object_eval(void)
void hoc_object_pushed(void)
static int icntobjectdata
Object * nrn_get_gui_redirect_obj()
static void chktemplate(void)
void hoc_begintemplate(Symbol *t1)
void class2oc(const char *name, ctor_f *cons, dtor_f *destruct, Member_func *m, Member_ret_obj_func *mobjret, Member_ret_str_func *strret)
void oc_restore_hoc_oop(Object **a1, Objectdata **a2, int *a4, Symlist **a5)
void hoc_object_pop(void)
void hoc_objvardecl(void)
void hoc_ob_pointer(void)
static void range_suffix(Symbol *sym, int nindex, int narg)
void hoc_add_publiclist(Symbol *s)
void connect_obsec_syntax(void)
constexpr std::size_t hoc_object_pathname_bufsize
static void hoc_allobjects1(Symlist *sl, int nspace)
Objectdata * hoc_top_level_data
void hoc_newobj_arg(void)
#define pushtemplateodata(arg)
void hoc_push_current_object(void)
void hoc_known_type(void)
int hoc_resize_toplevel(int more)
static Object * gui_redirect_obj_
bool is_array(const Symbol &sym)
hoc_List * hoc_l_newlist()
hoc_Item * hoc_l_lappendobj(hoc_List *, struct Object *)
void hoc_l_delete(hoc_Item *)
int special_pnt_call(Object *ob, Symbol *sym, int narg)
Object ** hoc_objgetarg(int)
Symlist * hoc_top_level_symlist
int hoc_araypt(Symbol *, int)
#define ITERATE(itm, lst)
void move(Item *q1, Item *q2, Item *q3)
void hoc_execerror(const char *s1, const char *s2)
void * erealloc(void *ptr, size_t size)
void * ecalloc(size_t n, size_t size)
static void * emalloc(size_t size)
void hoc_warning(const char *s1, const char *s2)
constexpr do_not_search_t do_not_search
decltype(auto) invoke_method_that_may_throw(Callable message_prefix, Args &&... args)
Execute C++ code that may throw and propagate HOC information.
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.
void sec_free(hoc_Item *)
int const size_t const size_t n
void destroy_point_process(void *)
Object * hoc_obj_look_inside_stack(int)
Object ** hoc_objpop()
Pop pointer to object pointer and return top elem from stack.
void hoc_tobj_unref(Object **)
static void * opaque_obj2pyobj(Object *ho)
Section * nrn_sectionref_steer(Section *sec, Symbol *sym, int *pnindex)
Object ** hoc_temp_objptr(Object *)
void hoc_free_symspace(Symbol *)
Symlist * hoc_built_in_symlist
struct Object **(* member)(void *)
const char **(* member)(void *)
struct Symbol::@45::@46 rng
void(* destructor)(void *)
void *(* constructor)(struct Object *)
void(* hpoasgn)(Object *, int)
void *(* opaque_obj2pyobj)(Object *)
void(* py2n_component)(Object *, Symbol *, int, int)
int Fprintf(FILE *stream, const char *fmt, Args... args)
int Printf(const char *fmt, Args... args)