NEURON
secref.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /*
3 Section reference
4 Allows sections to be stored as variables and passed as arguments by
5 using an object as a label for a particular section.
6 
7 Usage is:
8 
9 objectvar s1, s2
10 soma s1 = new SectionRef()
11 print s1.sec.L // prints length of soma
12 s2 = s1
13 s2.sec {psection()} // makes soma the currently accessed section for a statement
14 
15 access s1.sec // soma becomes the default section
16 */
17 
18 #include <stdlib.h>
19 #include "section.h"
20 #include "parse.hpp"
21 #include "hoc_membf.h"
22 #include "oc_ansi.h"
23 #include <nrnpython_config.h>
24 
25 extern int hoc_return_type_code;
26 
29 
32  Symbol* sym;
33  Object* ob;
34  int i;
35  if (!sec || !sec->prop || !sec->prop->dparam[0].sym) {
36  hoc_execerror("section is unnamed", (char*) 0);
37  }
38  sym = sec->prop->dparam[0].sym;
39  ob = sec->prop->dparam[6].obj;
40  i = sec->prop->dparam[5].i;
41  if (ob) {
42  return ob->u.dataspace[sym->u.oboff].psecitm + i;
43  } else {
44  return hoc_top_level_data[sym->u.oboff].psecitm + i;
45  }
46 }
47 
48 /*ARGSUSED*/
49 static void* cons(Object* ho) {
50  Section* sec = nrn_secarg(1);
52  return (void*) (sec);
53 }
54 
55 static void destruct(void* v) {
56  Section* sec = (Section*) v;
58 }
59 
60 #if 0
61 static double dummy(void* v) {
62  Section* sec = (Section*)v;
63  printf("%s\n", secname(sec));
64  return 0.;
65 }
66 #endif
67 
68 static double s_unname(void* v) {
69  hoc_Item** pitm;
70  Section* sec;
71  sec = (Section*) v;
72 #if USE_PYTHON
73  /* Python Sections cannot be unnamed, return 0.0 */
74  if (sec->prop && sec->prop->dparam[PROP_PY_INDEX]._pvoid) {
75  return 0.0;
76  }
77 #endif
78  pitm = sec2pitm(sec);
79  *pitm = (hoc_Item*) 0;
80  sec->prop->dparam[0].sym = (Symbol*) 0;
81  return 1.;
82 }
83 
84 static double s_rename(void* v) {
87 
88  char* name;
89  Section* sec;
90  Symbol* sym;
91  hoc_Item* qsec;
92  hoc_Item** pitm;
93  Object *ob, *olist;
94  Objectdata* obdsav;
95  int i, index, size, n;
96 
97  sec = (Section*) v;
98  if (!sec->prop) {
99  Printf("SectionRef[???].sec is a deleted section\n");
100  return 0.;
101  }
102 #if USE_PYTHON
103  /* Python Sections cannot be renamed, return 0.0 */
104  if (sec->prop->dparam[PROP_PY_INDEX]._pvoid) {
105  return 0.;
106  }
107 #endif
108  qsec = sec->prop->dparam[8].itm;
109  if (sec->prop->dparam[0].sym) {
110  Printf("%s must first be unnamed\n", secname(sec));
111  return 0.;
112  }
113 
114  name = gargstr(1);
115  size = 0;
116  index = 0;
117  if (ifarg(2)) {
118  olist = *hoc_objgetarg(2);
119  size = ivoc_list_count(olist);
120  assert(size > 0);
121  }
123  obdsav = hoc_objectdata;
125  if (sym) {
126  if (sym->type != SECTION || (sym->arayinfo && sym->arayinfo->nsub > 1)) {
127  Printf("The new name already exists and is not a SECTION or has a dimension > 1\n");
128  hoc_objectdata = obdsav;
129  return 0;
130  }
131  /* check that it points to no sections */
133  pitm = hoc_top_level_data[sym->u.oboff].psecitm;
134  for (i = 0; i < n; ++i) {
135  if (pitm[i]) {
136  Printf("Previously existing %s[%d] points to a section which is being deleted\n",
137  sym->name,
138  i);
139  sec_free(pitm[i]);
140  }
141  }
142  if (sym->arayinfo) {
143  hoc_freearay(sym);
144  }
145  free(pitm);
146  } else {
147  sym = hoc_install(name, SECTION, 0., &hoc_top_level_symlist);
149  }
150  if (size) {
151  hoc_pushx((double) size);
152  hoc_arayinfo_install(sym, 1);
153  hoc_top_level_data[sym->u.oboff].psecitm = pitm = (hoc_Item**) ecalloc(size,
154  sizeof(hoc_Item*));
155  } else {
156  hoc_top_level_data[sym->u.oboff].psecitm = pitm = (hoc_Item**) ecalloc(1,
157  sizeof(hoc_Item*));
158  }
159 
160  if (size == 0) {
161  pitm[index] = qsec;
162  sec->prop->dparam[0].sym = sym;
163  sec->prop->dparam[5].i = index;
164  sec->prop->dparam[6].obj = nullptr;
165  OPSECITM(sym)[0] = qsec;
166  } else {
167  for (i = 0; i < size; ++i) {
168  ob = ivoc_list_item(olist, i);
169  /*assert(is_obj_type(ob, "SectionRef")*/
170  sec = (Section*) ob->u.this_pointer;
171  if (!sec->prop) {
172  Printf("%s references a deleted section\n", hoc_object_name(ob));
173  hoc_objectdata = obdsav;
174  return 0;
175  }
176  qsec = sec->prop->dparam[8].itm;
177  sec->prop->dparam[0].sym = sym;
178  sec->prop->dparam[5].i = i;
179  sec->prop->dparam[6].obj = nullptr;
180  OPSECITM(sym)[i] = qsec;
181  }
182  }
183 #if 0
184  printf("SectionRef[???}.rename");
185  i = sec->prop->dparam[5].i;
186  if (ob) {
187  pitm = ob->u.dataspace[sym->u.oboff].psecitm;
188  }else{
189  pitm = hoc_top_level_data[sym->u.oboff].psecitm;
190  }
191  printf("%s\n", secname(sec));
192  printf("sec->prop->dparam[0].sym->name = %s\n", sym->name);
193  printf("dparam[5].i = %d dparam[6].obj = %s\n", i, hoc_object_name(ob));
194  printf("sym->u.oboff = %d\n", sym->u.oboff);
195  if (ob) {
196  printf("ob->u.dataspace[sym->u.oboff].psecitm = %lx\n", pitm);
197  }else{
198  printf("hoc_top_level_data[sym->u.oboff].psecitm = %lx\n", pitm);
199  }
200  printf("hocSEC(pitm[i]) = %s\n", secname(hocSEC(pitm[i])));
201  if (sym->arayinfo) {
202  Arrayinfo* a;
203  int j;
204  a = sym->arayinfo;
205  printf("symbol array info ");
206  for (j=0; j < a->nsub; ++j) {
207  printf("[%d]", a->sub[j]);
208  }
209  printf("\n");
210  if (ob) {
211  a = ob->u.dataspace[sym->u.oboff + 1].arayinfo;
212  printf("dataspace array info ");
213  for (j=0; j < a->nsub; ++j) {
214  printf("[%d]", a->sub[j]);
215  }
216  printf("\n");
217  }
218  }else{
219  printf("scalar\n");
220  }
221 #endif
222  hoc_objectdata = obdsav;
223  return 1.0;
224 }
225 
227  int n;
228  if (!sec->prop) {
229  hoc_execerror("Section was deleted", (char*) 0);
230  }
231  for (n = 0, sec = sec->child; sec; sec = sec->sibling) {
232  ++n;
233  }
234  return n;
235 }
236 
237 static double s_nchild(void* v) {
238  int n;
239  hoc_return_type_code = 1; /* integer */
240  return (double) nrn_secref_nchild((Section*) v);
241 }
242 
243 static double s_has_parent(void* v) {
244  int n;
245  Section* sec = (Section*) v;
246  hoc_return_type_code = 2; /* boolean */
247  if (!sec->prop) {
248  hoc_execerror("Section was deleted", (char*) 0);
249  }
250  return (double) (sec->parentsec != (Section*) 0);
251 }
252 
253 static double s_has_trueparent(void* v) {
254  int n;
255  Section* sec = (Section*) v;
256  hoc_return_type_code = 2; /* boolean */
257  if (!sec->prop) {
258  hoc_execerror("Section was deleted", (char*) 0);
259  }
260  return (double) (nrn_trueparent(sec) != (Section*) 0);
261 }
262 
263 static double s_exists(void* v) {
264  int n;
265  hoc_return_type_code = 2; /* boolean */
266  Section* sec = (Section*) v;
267  return (double) (sec->prop != (Prop*) 0);
268 }
269 
270 static double s_cas(void* v) { /* return 1 if currently accessed section */
271  Section* sec = (Section*) v;
272  Section* cas = chk_access();
273  hoc_return_type_code = 2; /* boolean */
274  if (!sec->prop) {
275  hoc_execerror("Section was deleted", (char*) 0);
276  }
277  if (sec == cas) {
278  return 1.;
279  }
280  return 0.;
281 }
282 
283 static Member_func members[] = {"sec",
284  s_rename, /* will actually become a SECTIONREF below */
285  "parent",
286  s_rename,
287  "trueparent",
288  s_rename,
289  "root",
290  s_rename,
291  "child",
292  s_rename,
293  "nchild",
294  s_nchild,
295  "has_parent",
296  s_has_parent,
297  "has_trueparent",
299  "exists",
300  s_exists,
301  "rename",
302  s_rename,
303  "unname",
304  s_unname,
305  "is_cas",
306  s_cas,
307  0,
308  0};
309 
311  Section* s = 0;
312  if (sym == nrn_parent_sym) {
313  s = sec->parentsec;
314  if (!s) {
315  if (nrn_inpython_ == 1) {
316  hoc_warning("SectionRef has no parent for ", secname(sec));
317  nrn_inpython_ = 2;
318  return NULL;
319  } else {
320  hoc_execerror("SectionRef has no parent for ", secname(sec));
321  }
322  }
323  } else if (sym == nrn_trueparent_sym) {
324  s = nrn_trueparent(sec);
325  if (!s) {
326  if (nrn_inpython_) {
327  hoc_warning("SectionRef has no parent for ", secname(sec));
328  nrn_inpython_ = 2;
329  return NULL;
330  } else {
331  hoc_execerror("SectionRef has no parent for ", secname(sec));
332  }
333  }
334  } else if (sym == nrn_root_sym) {
335  for (s = sec; s->parentsec; s = s->parentsec) {
336  }
337  } else if (sym == nrn_child_sym) {
338  int index, i;
339  if (*pnindex == 0) {
340  if (nrn_inpython_) {
341  hoc_warning("SectionRef.child[index]", (char*) 0);
342  nrn_inpython_ = 2;
343  return NULL;
344  } else {
345  hoc_execerror("SectionRef.child[index]", (char*) 0);
346  }
347  }
348  index = (int) hoc_xpop();
349  --*pnindex;
350  for (i = 0, s = sec->child; i < index && s; s = s->sibling) {
351  ++i;
352  }
353  if (i != index || !s) {
354  if (nrn_inpython_) {
355  hoc_warning("SectionRef.child index too large for", secname(sec));
356  nrn_inpython_ = 2;
357  return NULL;
358  } else {
359  hoc_execerror("SectionRef.child index too large for", secname(sec));
360  }
361  }
362  }
363  return s;
364 }
365 
366 
367 extern void class2oc(const char*,
368  void* (*cons)(Object*),
369  void (*destruct)(void*),
370  Member_func*,
371  int (*checkpoint)(void**),
374 
375 
376 void SectionRef_reg(void) {
377  Symbol *s, *sr;
378 
379  class2oc("SectionRef", cons, destruct, members, nullptr, nullptr, nullptr);
380  /* now make the sec variable an actual SECTIONREF */
381  sr = hoc_lookup("SectionRef");
382  s = hoc_table_lookup("sec", sr->u.ctemplate->symtable);
383  s->type = SECTIONREF;
384  nrn_sec_sym = s;
385  s = hoc_table_lookup("parent", sr->u.ctemplate->symtable);
386  s->type = SECTIONREF;
387  nrn_parent_sym = s;
388  s = hoc_table_lookup("trueparent", sr->u.ctemplate->symtable);
389  s->type = SECTIONREF;
390  nrn_trueparent_sym = s;
391  s = hoc_table_lookup("root", sr->u.ctemplate->symtable);
392  s->type = SECTIONREF;
393  nrn_root_sym = s;
394  s = hoc_table_lookup("child", sr->u.ctemplate->symtable);
395  s->type = SECTIONREF;
396  nrn_child_sym = s;
397  s->arayinfo = (Arrayinfo*) emalloc(sizeof(Arrayinfo));
398  ;
399  s->arayinfo->refcount = 1;
400  s->arayinfo->a_varn = nullptr;
401  s->arayinfo->nsub = 1;
402  s->arayinfo->sub[0] = 0;
403 }
const char * secname(Section *sec)
Definition: cabcode.cpp:1776
Section * nrn_trueparent(Section *sec)
Definition: cabcode.cpp:1666
Section * chk_access(void)
Definition: cabcode.cpp:444
short index
Definition: cabvars.h:10
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:61
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
Object * ivoc_list_item(Object *olist, int i)
Definition: oclist.cpp:414
size_t hoc_total_array_data(Symbol *s, Objectdata *obd)
Definition: hoc_oop.cpp:94
int hoc_arayinfo_install(Symbol *sp, int nsub)
Definition: hoc.cpp:601
int ivoc_list_count(Object *)
Definition: oclist.cpp:408
void hoc_freearay(Symbol *sp)
Definition: hoc.cpp:640
Symbol * hoc_install(const char *, int, double, Symlist **)
Objectdata * hoc_objectdata
Definition: hoc_oop.cpp:123
void hoc_warning(const char *, const char *)
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:72
void hoc_install_object_data_index(Symbol *sp)
Definition: hoc_oop.cpp:304
Symbol * hoc_lookup(const char *)
double hoc_xpop(void)
#define assert(ex)
Definition: hocassrt.h:32
void * ecalloc(size_t n, size_t size)
Definition: symbol.cpp:215
#define gargstr
Definition: hocdec.h:14
#define OPSECITM(sym)
Definition: hocdec.h:309
#define hocSEC(q)
Definition: hoclist.h:66
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
Symlist * hoc_top_level_symlist
Definition: code2.cpp:690
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:124
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
#define v
Definition: md1redef.h:4
#define sec
Definition: md1redef.h:13
#define i
Definition: md1redef.h:12
#define Printf
Definition: model.h:237
char * name
Definition: init.cpp:16
char * emalloc(unsigned n)
Definition: list.cpp:166
#define printf
Definition: mwprefix.h:26
void section_ref(Section *)
Definition: solve.cpp:575
void section_unref(Section *)
Definition: solve.cpp:565
void sec_free(hoc_Item *)
Definition: solve.cpp:521
Section * nrn_secarg(int iarg)
Definition: seclist.cpp:49
int const size_t const size_t n
Definition: nrngsl.h:11
if(status)
size_t j
int nrn_inpython_
Definition: hoc.cpp:37
HOC interpreter function declarations (included by hocdec.h)
static double dummy
Definition: ocptrvector.cpp:27
void SectionRef_reg(void)
Definition: secref.cpp:376
static double s_has_parent(void *v)
Definition: secref.cpp:243
Section * nrn_sectionref_steer(Section *sec, Symbol *sym, int *pnindex)
Definition: secref.cpp:310
Symbol * nrn_parent_sym
Definition: secref.cpp:27
Symbol * nrn_child_sym
Definition: secref.cpp:27
static double s_has_trueparent(void *v)
Definition: secref.cpp:253
static Member_func members[]
Definition: secref.cpp:283
Symbol * nrn_sec_sym
Definition: secref.cpp:27
static hoc_Item ** sec2pitm(Section *sec)
Definition: secref.cpp:30
int nrn_secref_nchild(Section *sec)
Definition: secref.cpp:226
static void destruct(void *v)
Definition: secref.cpp:55
static double s_unname(void *v)
Definition: secref.cpp:68
static void * cons(Object *ho)
Definition: secref.cpp:49
Symbol * nrn_root_sym
Definition: secref.cpp:27
static double s_rename(void *v)
Definition: secref.cpp:84
static double s_nchild(void *v)
Definition: secref.cpp:237
int hoc_return_type_code
Definition: code.cpp:42
static double s_exists(void *v)
Definition: secref.cpp:263
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1560
static double s_cas(void *v)
Definition: secref.cpp:270
Symbol * nrn_trueparent_sym
Definition: secref.cpp:28
#define PROP_PY_INDEX
Definition: section.h:212
#define NULL
Definition: sptree.h:16
unsigned * a_varn
Definition: hocdec.h:69
int nsub
Definition: hocdec.h:70
int refcount
Definition: hocdec.h:71
int sub[1]
Definition: hocdec.h:72
Definition: hocdec.h:227
void * this_pointer
Definition: hocdec.h:232
Objectdata * dataspace
Definition: hocdec.h:231
union Object::@39 u
Definition: section.h:214
struct Section * parentsec
Definition: section.h:42
Definition: model.h:57
short type
Definition: model.h:58
union Symbol::@18 u
char * name
Definition: model.h:72
HocStruct cTemplate * ctemplate
Definition: hocdec.h:152
int oboff
Definition: hocdec.h:132
Arrayinfo * arayinfo
Definition: hocdec.h:159
Definition: hocdec.h:84
Symlist * symtable
Definition: hocdec.h:197
Arrayinfo * arayinfo
Definition: hocdec.h:223
HocStruct hoc_Item ** psecitm
Definition: hocdec.h:221