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