1 #include <../../nrnconf.h>
12 #include <nrnpython_config.h>
21 void* (*nrnpy_opaque_obj2pyobj_p_)(
Object*);
30 static int connect_obsec_;
34 #define EXTERNAL_TYPE 2
52 hoc_oc(
"objref hoc_obj_[2]\n");
75 Sprintf(s,
"%s[%d]", ob->ctemplate->sym->name, ob->
index);
87 for (
i = a->
nsub - 1;
i >= 0; --
i) {
114 for (
i = a->
nsub - 1;
i >= 0; --
i) {
153 if (sym->
type != UNDEF) {
177 OPSTR(sym) = (
char**) 0;
202 #define NTEMPLATESTACK 20
213 #define pushtemplatesym(arg) \
215 (templatestackp++)->sym = arg
216 #define pushtemplatesymlist(arg) \
218 (templatestackp++)->symlist = arg
219 #define pushtemplatei(arg) \
221 (templatestackp++)->i = arg
222 #define pushtemplateodata(arg) \
224 (templatestackp++)->odata = arg
225 #define pushtemplateo(arg) \
227 (templatestackp++)->o = arg
239 #define OBJ_STACK_SIZE 10
245 if (ob->ctemplate->constructor) {
334 if (ob->ctemplate->constructor) {
335 hoc_execerror(
"Can't execute in a built-in class context", 0);
365 if (strlen(cmd) > 256 - 10) {
370 sprintf(pbuf,
"%s\n", cmd + 1);
385 pushx((
double) (err));
460 printf(
"new object from template %s created.\n", symtemp->
name);
471 ob->ctemplate->count++;
506 #define NEWOBJ1_ERR_SIZE 32
555 if (
ne->oji == oji) {
579 for (s = ob->ctemplate->symtable->first; s; s = s->
next) {
588 for (
i = 0;
i < total;
i++) {
604 for (
i = 0;
i < total;
i++) {
607 if (strcmp(s->
name,
"this") == 0) {
624 if (ob->ctemplate->is_point_) {
627 if (ob->ctemplate->init) {
678 hoc_execerror(
"Assignment to $o only allowed if caller arg was declared as objref",
NULL);
716 Inst *pcsav, callcode[4];
731 if (sym->
type == OBFUNCTION) {
742 }
else if (sym->
type == STRFUNCTION) {
759 callcode[1].
sym = sym;
760 callcode[2].
i =
narg;
767 if (sym->
type == PROCEDURE) {
787 Inst *stmtbegin, *stmtend;
798 stmtbegin =
pc +
pc->
i;
800 stmtend =
pc +
pc->
i;
819 printf(
"declareing %s as objectvar\n", sym->
name);
821 if (sym->
type == OBJECTVAR) {
824 for (
i = 0;
i < total;
i++) {
830 sym->
type = OBJECTVAR;
840 for (
i = 0;
i < size;
i++) {
863 printf(
"code for hoc_objectvar()\n");
893 printf(
"code for hoc_objectarg()\n");
932 if (!sym || sym->
type != TEMPLATE) {
960 pushx((
double) ((
size_t) ob));
965 static void range_suffix(
Symbol* sym,
int nindex,
int narg) {
980 if (sym->
type == RANGEVAR) {
1006 int nindex,
narg, cplus, isfunc;
1013 printf(
"code for hoc_object_component()\n");
1019 psym = &(
pc++)->sym;
1025 range_suffix(sym0, nindex,
narg);
1028 if (connect_obsec_) {
1035 hoc_execerror(
"[...](...) syntax only allowed for array range variables:", sym0->
name);
1062 (*nrnpy_py2n_component)(obp, sym0, nindex, isfunc);
1067 if (obp->ctemplate->id == *ptid) {
1076 "%s not a public member of %s\n",
1078 obp->ctemplate->sym->name);
1081 *ptid = obp->ctemplate->id;
1096 switch (sym->
type) {
1102 nindex =
araypt(sym, OBJECTVAR);
1128 nindex =
araypt(sym, OBJECTVAR);
1136 hoc_execerror(sym->
name,
": string can't have function arguments or array indices");
1155 case HOCOBJFUNCTION:
1202 if (connect_obsec_) {
1226 if (connect_obsec_) {
1237 nindex =
araypt(sym, OBJECTVAR);
1240 if (connect_obsec_) {
1249 if ((
pc++)->
i != ITERATOR) {
1299 printf(
"code for hoc_object_eval\n");
1307 if (d->
sym->
type == RANGEVAR) {
1330 printf(
"code for hoc_ob_pointer\n");
1337 if (d->
sym->
type == RANGEVAR) {
1370 int type1, type2, op;
1377 if (d->
sym->
type == RANGEVAR) {
1383 if (type2 == RANGEVAR && type1 == NUMBER) {
1422 hoc_execerror(
"Invalid assignment operator for object", (
char*) 0);
1440 hoc_execerror(
"Invalid assignment operator for string", (
char*) 0);
1454 hoc_execerror(
"Invalid assignment operator for PythonObject", (
char*) 0);
1456 (*nrnpy_hpoasgn)(
o, type1);
1461 hoc_execerror(
"Cannot assign to left hand side", (
char*) 0);
1469 if (s->
type != TEMPLATE) {
1472 if (!s1 || s1->
type != TEMPLATE) {
1492 printf(
"begin template %s\n",
t->name);
1495 if (
type == TEMPLATE) {
1499 }
else if (
type != UNDEF) {
1500 hoc_execerror(
t->name,
"already used as something besides template");
1504 t->u.ctemplate->sym =
t;
1505 t->u.ctemplate->symtable = (
Symlist*) 0;
1506 t->u.ctemplate->dataspace_size = 0;
1507 t->u.ctemplate->constructor = 0;
1508 t->u.ctemplate->destructor = 0;
1509 t->u.ctemplate->is_point_ = 0;
1510 t->u.ctemplate->steer = 0;
1511 t->u.ctemplate->checkpoint = 0;
1528 printf(
"end template %s\n",
t->name);
1531 if (strcmp(ts->
name,
t->name) != 0) {
1547 if (s && s->
type != PROCEDURE) {
1548 hoc_execerror(
"'init' can only be used as the initialization procedure for new objects",
1552 if (s && s->
type != PROCEDURE) {
1554 "'unref' can only be used as the callback procedure when the reference count is "
1564 int (*checkpoint)(
void**),
1582 t->constructor =
cons;
1585 t->checkpoint = checkpoint;
1593 for (
i = 0; mobjret[
i].
name; ++
i) {
1599 for (
i = 0; strret[
i].
name; ++
i) {
1654 case HOCOBJFUNCTION:
1677 if (
t == OBJECTVAR) {
1682 if (
t == OBJECTVAR) {
1684 printf(
"dymnamic checking of type=%d\n",
type);
1688 }
else if (
type !=
t) {
1692 if (
t != OBJECTVAR) {
1707 for (s =
sl->first; s; s = s->
next) {
1710 for (
i = 0;
i < total;
i++) {
1714 if ((*obp)->ctemplate == ctemplate) {
1720 (*obp)->u.dataspace);
1727 (*obp)->u.dataspace);
1729 if ((*obp)->ctemplate == ctemplate) {
1739 #define objectpath hoc_objectpath_impl
1740 #define pathprepend hoc_path_prepend
1765 hoc_warning(
"objectpath depth > 4 for", oblook->ctemplate->sym->name);
1768 if (oblook->ctemplate->constructor) {
1772 sl = oblook->ctemplate->symtable;
1779 for (s =
sl->first; s; s = s->
next) {
1782 for (
i = 0;
i < total;
i++) {
1784 if (*obp && *obp != oblook &&
objectpath(ob, *obp, path, depth)) {
1795 static char path[512];
1801 hoc_warning(
"Couldn't find a pathname to the object pointer",
1802 ob->ctemplate->sym->name);
1820 if (obj == (
Object*) 0) {
1838 if (obj->ctemplate->unref) {
1865 if (--obj->ctemplate->count <= 0) {
1866 obj->ctemplate->
index = 0;
1868 obj->ctemplate =
nullptr;
1900 if (strcmp(
"this", s->
name) != 0) {
1902 for (
i = 0;
i < total;
i++) {
1912 for (
i = 0;
i < total; ++
i) {
1967 for (s =
sl->first; s; s = s->
next) {
1968 if (s->
type == TEMPLATE) {
1972 for (
i = 0;
i < nspace; ++
i) {
1987 if (s && s->
type == TEMPLATE) {
1991 for (
i = 0;
i < nspace; ++
i) {
2015 for (s =
sl->first; s; s = s->
next) {
2018 for (
i = 0;
i < total;
i++) {
2020 for (
id = 0;
id < depth;
id++) {
2024 Printf(
"obp %s[%d] -> %s with %d refs.\n",
2033 (*obp)->u.dataspace !=
data
2036 (*obp)->recurse = 1;
2038 (*obp)->u.dataspace,
2040 (*obp)->recurse = 0;
2049 if (!obj || strcmp(obj->ctemplate->sym->name, type_name) != 0) {
2051 sprintf(
buf,
"object type is %s instead of", obj->ctemplate->sym->name);
2053 sprintf(
buf,
"object type is nil instead of");
2060 if (obj && strcmp(obj->ctemplate->sym->name, type_name) == 0) {
void nrn_rangeconst(Section *sec, Symbol *s, double *pd, int op)
void nrn_pushsec(Section *sec)
double cable_prop_eval(Symbol *sym)
void cable_prop_assign(Symbol *sym, double *pd, int op)
Section * nrn_sec_pop(void)
double * nrn_rangepointer(Section *sec, Symbol *s, double d)
void new_sections(Object *ob, Symbol *sym, Item **pitm, int size)
double * cable_prop_eval_pointer(Symbol *sym)
void ob_sec_access_push(Item *qsec)
Symbol * hoc_table_lookup(const char *, Symlist *)
void push_frame(Symbol *sp, int narg)
int araypt(Symbol *sp, int type)
void hoc_iterator_object(Symbol *sym, int argcount, Inst *beginpc, Inst *endpc, Object *ob)
void connect_obsec_syntax(void)
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)
void hoc_execerror(const char *, const char *)
static void destruct(void *v)
static void * cons(Object *o)
char * hoc_object_pathname(Object *ob)
Object * hoc_name2obj(const char *name, int index)
void hoc_obj_set(int i, Object *obj)
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)
double hoc_call_func(Symbol *s, int narg)
void hoc_free_val_array(double *, size_t)
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(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)
Object * hoc_obj_get(int i)
void hoc_freearay(Symbol *sp)
int hoc_obj_look_inside_stack_index(int i)
Symbol * hoc_install(const char *, int, double, Symlist **)
void hoc_free_object(Object *)
int hoc_is_str_arg(int narg)
int hoc_errno_check(void)
void hoc_free_pstring(char **)
Objectdata * hoc_objectdata
void hoc_assign_str(char **cpp, const char *buf)
size_t hoc_total_array(Symbol *s)
double hoc_opasgn(int op, double dest, double src)
double hoc_call_objfunc(Symbol *s, int narg, Object *ob)
int is_obj_type(Object *obj, const char *type_name)
int hoc_oc(const char *buf)
void hoc_warning(const char *, const char *)
void check_obj_type(Object *obj, const char *type_name)
void hoc_obj_disconnect(Object *)
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_install_object_data_index(Symbol *sp)
void hoc_stkobj_unref(Object *o, int stkindex)
void hoc_oop_initaftererror(void)
Symbol * hoc_lookup(const char *)
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)
HocStr * hocstr_create(size_t size)
void hocstr_delete(HocStr *hs)
void free_arrayinfo(Arrayinfo *a)
#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 newobj1_err_t * newobj1_err_
static int newobj1_err_size_
static Templatedatum * poptemplate(void)
void hoc_allobjectvars(void)
void hoc_newobj1_err()
unref partially constructed objects controlled by current longjump handle
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)
void hoc_object_asgn(void)
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)
int hoc_print_first_instance
void(* oc_jump_target_)()
static void hoc_list_allobjref(Symlist *, Objectdata *, int)
void hoc_object_component(void)
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...
#define pushtemplateo(arg)
void hoc_ob_check(int type)
void pop_newobj1_err()
pop the now fully constructed object
void hoc_endtemplate(Symbol *t)
Object * hoc_newobj1(Symbol *sym, int narg)
static Templatedatum * templatestackp
void call_ob_proc(Object *ob, Symbol *sym, int narg)
void class2oc(const char *name, void *(*cons)(Object *), void(*destruct)(void *), Member_func *m, int(*checkpoint)(void **), Member_ret_obj_func *mobjret, Member_ret_str_func *strret)
Object * hoc_new_object(Symbol *symtemp, void *v)
void hoc_object_push(void)
void hoc_newobj_ret(void)
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 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)
void hoc_add_publiclist(Symbol *s)
void * nrn_get_oji()
Return handle for the current longjump buffer info.
static void hoc_allobjects1(Symlist *sl, int nspace)
Objectdata * hoc_top_level_data
void hoc_newobj_arg(void)
static void push_newobj1_err(Object *ob)
save partially constructed object and controlling longjump handle
#define pushtemplateodata(arg)
static int newobj1_err_index_
void hoc_push_current_object(void)
void hoc_known_type(void)
int hoc_resize_toplevel(int more)
static Object * gui_redirect_obj_
#define NEWOBJ1_ERR_SIZE
If hoc_newob1 fails after creating a new object, that object needs to be unreffed.
void * erealloc(void *ptr, size_t n)
void * ecalloc(size_t n, size_t size)
union Objectdata Objectdata
#define NOT_PARALLEL_SUB(c1)
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)
Datum * hoc_look_inside_stack(int, int)
Object ** hoc_objgetarg(int)
Symlist * hoc_top_level_symlist
Symlist * hoc_built_in_symlist
Object ** hoc_temp_objptr(Object *)
#define ITERATE(itm, lst)
char * emalloc(unsigned n)
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)
Symbol * nrnpy_pyobj_sym_
void(* nrnpy_hpoasgn)(Object *, int)
void(* nrnpy_py2n_component)(Object *, Symbol *, int, int)
void *(* nrnpy_opaque_obj2pyobj_p_)(Object *)
Section * nrn_sectionref_steer(Section *sec, Symbol *sym, int *pnindex)
void hoc_free_symspace(Symbol *)
struct Object **(* member)(void *)
const char **(* member)(void *)
HocStruct hoc_Item * secelm_
HocStruct hoc_Item * itm_me
short cpublic
Note: public is a reserved keyword.
HocStruct Object * object_
HocStruct cTemplate * ctemplate
HocStruct hoc_Item ** psecitm