NEURON
list.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /* The following routines support the concept of a list.
4 That is, one can insert at the head of a list or append to the tail of a
5 list with linsert<type>() and lappend<type>().
6 
7 In addition, one can insert an item before a known item and it will be
8 placed in the proper list.
9 
10 Items point to strings, symbols, etc. Note that more than one item in the
11 same or several lists can point to the same string, symbol.
12 
13 Finally, knowing an item, one can determine the preceding and following
14 items with next() and prev().
15 
16 Deletion, replacement and moving blocks of items is also supported.
17 */
18 
19 /* Implementation
20  The list is a doubly linked list. A special item with element 0 is
21  always at the tail of the list and is denoted as the List pointer itself.
22  list->next point to the first item in the list and
23  list->prev points to the last item in the list.
24  i.e. the list is circular
25  Note that in an empty list next and prev points to itself.
26 
27 It is intended that this implementation be hidden from the user via the
28 following function calls.
29 */
30 
31 #define HOC_L_LIST 1
32 
33 #include <stdlib.h>
34 #include "hoclist.h"
35 #include "hocdec.h"
36 #include "parse.hpp"
37 
38 #define Free free
39 
40 static Item* newitem(void) {
41  Item* q;
42  q = (Item*) emalloc(sizeof(Item));
43  return q;
44 }
45 
46 List* newlist(void) {
47  Item* i;
48  i = newitem();
49  i->prev = i;
50  i->next = i;
51  i->element.lst = (List*) 0;
52  i->itemtype = 0;
53  return (List*) i;
54 }
55 
56 void freelist(List** plist) { /*free the list but not the elements*/
57  Item *i1, *i2;
58  if (!(*plist)) {
59  return;
60  }
61  for (i1 = (*plist)->next; i1 != *plist; i1 = i2) {
62  i2 = i1->next;
63  Free(i1);
64  }
65  Free(*plist);
66  *plist = (List*) 0;
67 }
68 
69 static Item* linkitem(Item* item) {
70  Item* i;
71 
72  i = newitem();
73  i->prev = item->prev;
74  i->next = item;
75  item->prev = i;
76  i->prev->next = i;
77  return i;
78 }
79 
80 Item* hoc_l_next(Item* item) {
81  assert(item->next->element.lst); /* never return the list item */
82  return item->next;
83 }
84 
85 Item* hoc_l_prev(Item* item) {
86  assert(item->prev->element.lst); /* never return the list item */
87  return item->prev;
88 }
89 
90 Item* insertstr(Item* item, const char* str) {
91  /* insert a copy of the string before item */
92  /* a copy is made because strings are often assembled into a reusable buffer*/
93  Item* i;
94 
95  i = linkitem(item);
96  i->element.str = stralloc(str, (char*) 0);
97  i->itemtype = STRING;
98  return i;
99 }
100 
101 Item* insertitem(Item* item, Item* itm) {
102  /* insert a item pointer before item */
103  Item* i;
104 
105  i = linkitem(item);
106  i->element.itm = itm;
107  i->itemtype = ITEM;
108  return i;
109 }
110 
111 Item* insertlist(Item* item, List* lst) {
112  /* insert a item pointer before item */
113  Item* i;
114 
115  i = linkitem(item);
116  i->element.lst = lst;
117  i->itemtype = LIST;
118  return i;
119 }
120 
121 Item* insertsym(Item* item, Symbol* sym) {
122  /* insert a symbol before item */
123  /* a copy is not made because we need the same symbol in different lists */
124  Item* i;
125 
126  i = linkitem(item);
127  i->element.sym = sym;
128  i->itemtype = SYMBOL;
129  return i;
130 }
131 
133  /* insert a section before item */
134  Item* i;
135 
136  i = linkitem(item);
137  i->element.sec = sec;
138  i->itemtype = SECTION;
139  return i;
140 }
141 
142 Item* insertobj(Item* item, Object* obj) {
143  /* insert a object before item */
144  Item* i;
145 
146  i = linkitem(item);
147  i->element.obj = obj;
148  i->itemtype = OBJECTVAR;
149  return i;
150 }
151 
152 Item* insertvoid(Item* item, void* obj) {
153  /* insert a void pointer before item */
154  Item* i;
155 
156  i = linkitem(item);
157  i->element.vd = obj;
158  i->itemtype = VOIDPOINTER;
159  return i;
160 }
161 
162 Item* linsertstr(List* list, const char* str) {
163  return insertstr(list->next, str);
164 }
165 
166 Item* lappendstr(List* list, const char* str) {
167  return insertstr(list, str);
168 }
169 
170 Item* linsertsym(List* list, Symbol* sym) {
171  return insertsym(list->next, sym);
172 }
173 
174 Item* lappendsym(List* list, Symbol* sym) {
175  return insertsym(list, sym);
176 }
177 
178 Item* lappenditem(List* list, Item* item) {
179  return insertitem(list, item);
180 }
181 
182 Item* lappendlst(List* list, List* lst) {
183  return insertlist(list, lst);
184 }
185 
187  return insertsec(list, sec);
188 }
189 
190 Item* lappendobj(List* list, Object* obj) {
191  return insertobj(list, obj);
192 }
193 
194 Item* lappendvoid(List* list, void* obj) {
195  return insertvoid(list, obj);
196 }
197 
198 void hoc_l_delete(Item* item) {
199  assert(item->itemtype); /* can't delete list */
200  item->next->prev = item->prev;
201  item->prev->next = item->next;
202  Free(item);
203 }
204 
205 char* stralloc(const char* buf, char* rel) {
206  /* allocate space, copy buf, and free rel */
207  char* s;
208  s = static_cast<char*>(emalloc((unsigned) (strlen(buf) + 1)));
209  Strcpy(s, buf);
210  if (rel) {
211  Free(rel);
212  }
213  return s;
214 }
215 
216 void delitems(Item* q1, Item* q2) { /* delete tokens from q1 to q2 */
217  /* It is a serious error if q2 precedes q1 */
218  Item* q;
219  for (q = q1; q != q2;) {
220  q = q->next;
221  hoc_l_delete(q->prev);
222  }
223  hoc_l_delete(q2);
224 }
225 
226 void hoc_l_move(Item* q1, Item* q2, Item* q3) { /* move q1 to q2 and insert before q3*/
227  /* it is a serious error if q2 precedes q1 */
228  assert(q1 && q2);
229  assert(q1->itemtype && q2->itemtype);
230  q1->prev->next = q2->next; /* remove from first list */
231  q2->next->prev = q1->prev;
232 
233  q1->prev = q3->prev;
234  q3->prev->next = q1;
235  q3->prev = q2;
236  q2->next = q3;
237 }
238 
239 void movelist(Item* q1, Item* q2, List* s) {
240  /* move q1 to q2 from old list to end of list s*/
241  hoc_l_move(q1, q2, s);
242 }
243 
244 void replacstr(Item* q, const char* s) {
245  q->itemtype = STRING;
246  q->element.str = stralloc(s, (char*) 0);
247 }
#define STRING
Definition: bbslsrv.cpp:9
#define sec
Definition: md1redef.h:20
#define i
Definition: md1redef.h:19
char buf[512]
Definition: init.cpp:13
#define assert(ex)
Definition: hocassrt.h:24
#define VOIDPOINTER
Definition: hoclist.h:94
#define SYMBOL
Definition: model.h:91
#define ITEM
Definition: model.h:92
#define Strcpy
Definition: model.h:215
#define LIST
Definition: model.h:93
char * stralloc(const char *buf, char *rel)
Definition: list.cpp:178
void movelist(Item *q1, Item *q2, List *s)
Definition: list.cpp:214
void freelist(List **plist)
Definition: list.cpp:58
Item * linsertstr(List *list, const char *str)
Definition: list.cpp:131
char * emalloc(unsigned n)
Definition: list.cpp:161
void replacstr(Item *q, const char *s)
Definition: list.cpp:219
List * newlist()
Definition: list.cpp:48
Item * lappenditem(List *list, Item *item)
Definition: list.cpp:147
Item * insertsym(Item *item, Symbol *sym)
Definition: list.cpp:120
Item * insertitem(Item *item, Item *itm)
Definition: list.cpp:110
Item * linsertsym(List *list, Symbol *sym)
Definition: list.cpp:139
Item * insertstr(Item *item, const char *str)
Definition: list.cpp:99
Item * lappendsym(List *list, Symbol *sym)
Definition: list.cpp:143
Item * lappendstr(List *list, const char *str)
Definition: list.cpp:135
Item * lappendlst(List *list, List *lst)
Definition: list.cpp:150
Item * insertlist(Item *item, List *lst)
Definition: list.cpp:109
size_t q
s
Definition: multisend.cpp:521
void hoc_l_delete(Item *item)
Definition: list.cpp:198
Item * lappendsec(List *list, Section *sec)
Definition: list.cpp:186
void hoc_l_move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:226
static Item * newitem(void)
Definition: list.cpp:40
Item * insertvoid(Item *item, void *obj)
Definition: list.cpp:152
Item * hoc_l_next(Item *item)
Definition: list.cpp:80
void delitems(Item *q1, Item *q2)
Definition: list.cpp:216
static Item * linkitem(Item *item)
Definition: list.cpp:69
Item * lappendvoid(List *list, void *obj)
Definition: list.cpp:194
Item * insertsec(Item *item, Section *sec)
Definition: list.cpp:132
#define Free
Definition: list.cpp:38
Item * lappendobj(List *list, Object *obj)
Definition: list.cpp:190
Item * insertobj(Item *item, Object *obj)
Definition: list.cpp:142
Item * hoc_l_prev(Item *item)
Definition: list.cpp:85
Definition: model.h:8
struct Item * prev
Definition: model.h:13
void * element
Definition: model.h:11
short itemtype
Definition: model.h:9
struct Item * next
Definition: model.h:12
Definition: hocdec.h:173
Definition: model.h:47