NEURON
seclist.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #define HOC_L_LIST 1
3 #include <nrnpython_config.h>
4 #include "section.h"
5 #include "neuron.h"
6 #include "parse.hpp"
7 #include "hocparse.h"
8 #include "code.h"
9 #include "hoc_membf.h"
10 
11 /* needs trailing '}' */
12 #define ITERATE_REMOVE(q1, q2, lst) \
13  for (q1 = (lst)->next; q1 != (lst); q1 = q2) { \
14  q2 = q1->next; \
15  if (q1->element.sec->prop == NULL) { \
16  hoc_l_delete(q1); \
17  continue; \
18  }
19 
20 extern int hoc_return_type_code;
21 Section* (*nrnpy_o2sec_p_)(Object* o);
22 
24 
26  lappendsec((List*) sl, sec);
28 }
29 
30 /*ARGSUSED*/
31 static void* constructor(Object* ho) {
32  List* sl;
33  sl = newlist();
34  if (nrnpy_sectionlist_helper_ && ifarg(1)) {
36  }
37  return (void*) sl;
38 }
39 
40 static void destructor(void* v) {
41  Item* q;
42  List* sl = (List*) v;
43  ITERATE(q, sl) {
44  section_unref(q->element.sec);
45  }
46  freelist(&sl);
47 }
48 
50 #if USE_PYTHON
51  if (ifarg(i) && nrnpy_o2sec_p_) {
52  Object* o = *hoc_objgetarg(i);
53  return (*nrnpy_o2sec_p_)(o);
54  }
55 #endif
56  return chk_access();
57 }
58 
59 static double append(void* v) {
60  Section* sec = nrn_secarg(1);
61  if (ifarg(2)) {
62  hoc_execerror("Too many parameters. SectionList.append takes 0 or 1 arguments", (char*) 0);
63  }
65  return 1.;
66 }
67 
68 
70  Item* i;
71  Section* ch;
72  i = sl->prev;
73  for (ch = sec->child; ch; ch = ch->sibling) {
74  i = lappendsec(sl, ch);
75  section_ref(ch);
76  }
77  return i;
78 }
79 
80 static double children(void* v) {
81  Section* sec;
82  List* sl;
83  sec = nrn_secarg(1);
84  sl = (List*) v;
85  children1(sl, sec);
86  return 1.;
87 }
88 
89 static Item* subtree1(List* sl, Section* sec) {
90  Item *i, *j, *last, *first;
91  Section* s;
92  /* it is confusing to span the tree from the root without using
93  recursion.
94  */
95  s = sec;
96  i = lappendsec(sl, s);
97  section_ref(s);
98  last = i->prev;
99  while (i != last) {
100  for (first = last->next, last = i, j = first; j->prev != last; j = j->next) {
101  s = hocSEC(j);
102  i = children1(sl, s);
103  }
104  }
105  return i;
106 }
107 
108 static double subtree(void* v) {
109  Section* sec;
110  List* sl;
111  sec = nrn_secarg(1);
112  sl = (List*) v;
113  subtree1(sl, sec);
114  return 1.;
115 }
116 
117 static double wholetree(void* v) {
118  List* sl;
119  Section *s, *sec, *ch;
120  Item *i, *j, *first, *last;
121  sec = nrn_secarg(1);
122  sl = (List*) v;
123  /*find root*/
124  for (s = sec; s->parentsec; s = s->parentsec) {
125  }
126 
127  subtree1(sl, s);
128  return 1.;
129 }
130 
131 static double allroots(void* v) {
132  List* sl;
133  Item* qsec;
134  sl = (List*) v;
135  // ForAllSections(sec)
136  ITERATE(qsec, section_list) {
137  Section* sec = hocSEC(qsec);
138  if (!sec->parentsec) {
139  lappendsec(sl, sec);
140  section_ref(sec);
141  }
142  }
143 
144  return 1.;
145 }
146 
147 static double seclist_remove(void* v) {
148 #if USE_PYTHON
149  extern Symbol* nrnpy_pyobj_sym_;
150 #endif
151  Section *sec, *s;
152  Item *q, *q1;
153  List* sl;
154  int i;
155 
156  sl = (List*) v;
157  i = 0;
158 #if USE_PYTHON
159  if (!ifarg(1) || (*hoc_objgetarg(1))->ctemplate->sym == nrnpy_pyobj_sym_) {
160 #else
161  if (!ifarg(1)) {
162 #endif
163  sec = nrn_secarg(1);
164  ITERATE_REMOVE(q, q1, sl) /*{*/
165  if (sec == q->element.sec) {
166  delete (q);
168  return 1.;
169  }
170  }
171  hoc_warning(secname(sec), "not in this section list");
172 }
173 else {
174  Object* o;
176  check_obj_type(o, "SectionList");
177  ITERATE_REMOVE(q, q1, sl) /*{*/
178  s = hocSEC(q);
180 }
181 sl = (List*) o->u.this_pointer;
182 ITERATE_REMOVE(q, q1, sl) /*{*/
183 s = hocSEC(q);
184 s->volatile_mark = 1;
185 }
186 sl = (List*) v;
187 i = 0;
188 for (q = sl->next; q != sl; q = q1) {
189  q1 = q->next;
190  s = hocSEC(q);
191  if (s->volatile_mark) {
192  delete (q);
193  section_unref(s);
194  ++i;
195  }
196 }
197 }
198 return (double) i;
199 }
200 
201 static double unique(void* v) {
202  int i; /* number deleted */
203  Section* s;
204  Item *q, *q1;
205  List* sl = (List*) v;
206  hoc_return_type_code = 1; /* integer */
207  ITERATE_REMOVE(q, q1, sl) /*{*/
208  s = hocSEC(q);
209  s->volatile_mark = 0;
210 }
211 i = 0;
212 for (q = sl->next; q != sl; q = q1) {
213  q1 = q->next;
214  s = hocSEC(q);
215  if (s->volatile_mark++) {
216  delete (q);
217  section_unref(s);
218  ++i;
219  }
220 }
221 return (double) i;
222 }
223 
224 static double contains(void* v) {
225  Section* s;
226  Item *q, *q1;
227  List* sl = (List*) v;
228  hoc_return_type_code = 2; /* boolean */
229  s = nrn_secarg(1);
230  ITERATE_REMOVE(q, q1, sl) /*{*/
231  if (hocSEC(q) == s) {
232  return 1.;
233  }
234 }
235 return (0.);
236 }
237 
238 static double printnames(void* v) {
239  Item *q, *q1;
240  List* sl = (List*) v;
241  ITERATE_REMOVE(q, q1, sl) /*{*/
242  if (q->element.sec->prop) {
243  Printf("%s\n", secname(q->element.sec));
244  }
245 }
246 return 1.;
247 }
248 
249 static Member_func members[] = {"append", append, "remove", seclist_remove,
250  "wholetree", wholetree, "subtree", subtree,
251  "children", children, "unique", unique,
252  "printnames", printnames, "contains", contains,
253  "allroots", allroots, 0, 0};
254 
255 
256 extern void class2oc(const char*,
257  void* (*cons)(Object*),
258  void (*destruct)(void*),
259  Member_func*,
260  int (*checkpoint)(void**),
263 
264 
265 void SectionList_reg(void) {
266  /* printf("SectionList_reg\n");*/
267  class2oc("SectionList", constructor, destructor, members, nullptr, nullptr, nullptr);
268 }
269 
270 #define relative(pc) (pc + (pc)->i)
271 extern int hoc_returning;
272 
273 static void check(Object* ob) {
274  if (!ob) {
275  hoc_execerror("nil object is not a SectionList", (char*) 0);
276  }
277  if (ob->ctemplate->constructor != constructor) {
278  hoc_execerror(ob->ctemplate->sym->name, " is not a SectionList");
279  }
280 }
281 
282 void forall_sectionlist(void) {
283  Inst* savepc = pc;
284  Item *q, *q1;
285  Section* sec;
286  List* sl;
287  Object* ob;
288  Object** obp;
289  int istk;
290 
291  /* if arg is a string use forall_section */
292  if (hoc_stacktype() == STRING) {
293  forall_section();
294  return;
295  }
296  obp = hoc_objpop();
297  ob = *obp;
298  check(ob);
299  sl = (List*) (ob->u.this_pointer);
300  istk = nrn_isecstack();
301  for (q = sl->next; q != sl; q = q1) {
302  q1 = q->next;
303  sec = q->element.sec;
304  if (!sec->prop) {
305  delete (q);
307  continue;
308  }
309  nrn_pushsec(sec);
310  hoc_execute(relative(savepc));
311  nrn_popsec();
312  if (hoc_returning) {
313  nrn_secstack(istk);
314  }
315  if (hoc_returning == 1 || hoc_returning == 4) {
316  break;
317  } else if (hoc_returning == 2) {
318  hoc_returning = 0;
319  break;
320  } else {
321  hoc_returning = 0;
322  }
323  }
324  hoc_tobj_unref(obp);
325  if (!hoc_returning) {
326  pc = relative(savepc + 1);
327  }
328 }
329 
330 void hoc_ifseclist(void) {
331  Inst* savepc = pc;
332  Item *q, *q1;
333  Section* sec = chk_access();
334  List* sl;
335  Object* ob;
336  Object** obp;
337 
338  /* if arg is a string use forall_section */
339  if (hoc_stacktype() == STRING) {
340  hoc_ifsec();
341  return;
342  }
343  obp = hoc_objpop();
344  ob = *obp;
345  check(ob);
346  sl = (List*) (ob->u.this_pointer);
347  ITERATE_REMOVE(q, q1, sl) /*{*/
348  if (sec == q->element.sec) {
349  hoc_execute(relative(savepc));
350  if (!hoc_returning) {
351  pc = relative(savepc + 1);
352  }
353  hoc_tobj_unref(obp);
354  return;
355  }
356 }
359  pc = relative(savepc + 1);
360 }
361 }
const char * secname(Section *sec)
Definition: cabcode.cpp:1776
void nrn_secstack(int i)
Definition: cabcode.cpp:58
void nrn_pushsec(Section *sec)
Definition: cabcode.cpp:99
void forall_section(void)
Definition: cabcode.cpp:2137
int nrn_isecstack(void)
Definition: cabcode.cpp:54
void hoc_ifsec(void)
Definition: cabcode.cpp:2211
Section * chk_access(void)
Definition: cabcode.cpp:444
void nrn_popsec(void)
Definition: cabcode.cpp:123
Inst * pc
Definition: code.cpp:145
static int first
Definition: fmenu.cpp:190
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
static void destruct(void *v)
Definition: grglyph.cpp:205
static void * cons(Object *o)
Definition: grglyph.cpp:198
void hoc_warning(const char *, const char *)
#define hocSEC(q)
Definition: hoclist.h:66
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
void
void hoc_execute(Inst *)
int ifarg(int)
Definition: code.cpp:1581
#define v
Definition: md1redef.h:4
#define sec
Definition: md1redef.h:13
#define ITERATE(itm, lst)
Definition: model.h:25
#define Printf
Definition: model.h:237
void freelist(List **plist)
Definition: list.cpp:57
List * newlist()
Definition: list.cpp:47
int hoc_stacktype()
Definition: code.cpp:731
void section_ref(Section *)
Definition: solve.cpp:575
void section_unref(Section *)
Definition: solve.cpp:565
size_t q
size_t j
hoc_List * section_list
Definition: init.cpp:102
Symbol * nrnpy_pyobj_sym_
Object ** hoc_objpop()
Definition: code.cpp:860
Item * lappendsec(List *list, Section *sec)
Definition: list.cpp:186
#define STRING
Definition: bbslsrv.cpp:9
void forall_sectionlist(void)
Definition: seclist.cpp:282
static double subtree(void *v)
Definition: seclist.cpp:108
static double seclist_remove(void *v)
Definition: seclist.cpp:147
static double printnames(void *v)
Definition: seclist.cpp:238
static double allroots(void *v)
Definition: seclist.cpp:131
int hoc_returning
Definition: code.cpp:148
#define ITERATE_REMOVE(q1, q2, lst)
Definition: seclist.cpp:12
static Member_func members[]
Definition: seclist.cpp:249
void hoc_ifseclist(void)
Definition: seclist.cpp:330
check_obj_type(o, "SectionList")
Section *(* nrnpy_o2sec_p_)(Object *o)
Definition: seclist.cpp:21
static double unique(void *v)
Definition: seclist.cpp:201
static double children(void *v)
Definition: seclist.cpp:80
static void * constructor(Object *ho)
Definition: seclist.cpp:31
static void destructor(void *v)
Definition: seclist.cpp:40
void(* nrnpy_sectionlist_helper_)(List *, Object *)=0
Definition: seclist.cpp:23
sl
Definition: seclist.cpp:181
i
Definition: seclist.cpp:187
void lvappendsec_and_ref(void *sl, Section *sec)
Definition: seclist.cpp:25
static Item * subtree1(List *sl, Section *sec)
Definition: seclist.cpp:89
static double contains(void *v)
Definition: seclist.cpp:224
hoc_tobj_unref(obp)
int hoc_return_type_code
Definition: code.cpp:42
#define relative(pc)
Definition: seclist.cpp:270
static Item * children1(List *sl, Section *sec)
Definition: seclist.cpp:69
static void check(Object *ob)
Definition: seclist.cpp:273
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
void SectionList_reg(void)
Definition: seclist.cpp:265
o
Definition: seclist.cpp:175
static double wholetree(void *v)
Definition: seclist.cpp:117
static double append(void *v)
Definition: seclist.cpp:59
Section * nrn_secarg(int i)
Definition: seclist.cpp:49
Definition: model.h:15
struct Item * next
Definition: model.h:19
Definition: hocdec.h:227
void * this_pointer
Definition: hocdec.h:232
union Object::@39 u
short volatile_mark
Definition: section.h:54
struct Section * parentsec
Definition: section.h:42
struct Section * sibling
Definition: section.h:46
Definition: model.h:57
Definition: hocdec.h:51