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 #include <stdlib.h>
32 #include "modl.h"
33 #include "parse1.hpp"
34 
35 static Item* newitem() {
36  return (Item*) emalloc(sizeof(Item));
37 }
38 
40  Item* i;
41  i = newitem();
42  i->prev = i;
43  i->next = i;
44  i->element.lst = (List*) 0;
45  i->itemtype = 0;
46  return (List*) i;
47 }
48 
49 void freelist(List** plist) /*free the list but not the elements*/
50 {
51  Item *i1, *i2;
52  if (!(*plist)) {
53  return;
54  }
55  for (i1 = (*plist)->next; i1 != *plist; i1 = i2) {
56  i2 = i1->next;
57  Free(i1);
58  }
59  Free(*plist);
60  *plist = (List*) 0;
61 }
62 
63 static Item* linkitem(Item* item) {
64  Item* i;
65 
66  i = newitem();
67  i->prev = item->prev;
68  i->next = item;
69  item->prev = i;
70  i->prev->next = i;
71  return i;
72 }
73 
74 #if 0 /*currently unused*/
75 Item *next( Item *item)
76 {
77  assert(item->next->element.lst); /* never return the list item */
78  return item->next;
79 }
80 
81 Item *prev(Item *item)
82 {
83  assert(item->prev->element.lst); /* never return the list item */
84  return item->prev;
85 }
86 #endif
87 
88 Item* insertstr(Item* item, const char* str) /* insert a copy of the string before item */
89 /* a copy is made because strings are often assembled into a reusable buffer*/
90 {
91  Item* i;
92 
93  i = linkitem(item);
94  i->element.str = stralloc(str, (char*) 0);
95  i->itemtype = STRING;
96  return i;
97 }
98 
99 Item* insertitem(Item* item, Item* itm) /* insert a item pointer before item */
100 {
101  Item* i;
102 
103  i = linkitem(item);
104  i->element.itm = itm;
105  i->itemtype = ITEM;
106  return i;
107 }
108 
109 Item* insertlist(Item* item, List* lst) /* insert a item pointer before item */
110 {
111  Item* i;
112 
113  i = linkitem(item);
114  i->element.lst = lst;
115  i->itemtype = LIST;
116  return i;
117 }
118 
119 Item* insertsym(Item* item, Symbol* sym) /* insert a symbol before item */
120 /* a copy is not made because we need the same symbol in different lists */
121 {
122  Item* i;
123 
124  i = linkitem(item);
125  i->element.sym = sym;
126  i->itemtype = SYMBOL;
127  return i;
128 }
129 
130 Item* linsertstr(List* list, const char* str) {
131  return insertstr(list->next, str);
132 }
133 
134 Item* lappendstr(List* list, const char* str) {
135  return insertstr(list, str);
136 }
137 
138 Item* linsertsym(List* list, Symbol* sym) {
139  return insertsym(list->next, sym);
140 }
141 
142 Item* lappendsym(List* list, Symbol* sym) {
143  return insertsym(list, sym);
144 }
145 
146 Item* lappenditem(List* list, Item* item) {
147  return insertitem(list, item);
148 }
149 
150 Item* lappendlst(List* list, List* lst) {
151  return insertlist(list, lst);
152 }
153 
154 void remove(Item* item) {
155  assert(item->itemtype); /* can't delete list */
156  item->next->prev = item->prev;
157  item->prev->next = item->next;
158  Free(item);
159 }
160 
161 char* emalloc(unsigned n) { /* check return from malloc */
162  char* p;
163  p = static_cast<char*>(malloc(n));
164  if (p == (char*) 0) {
165  diag("out of memory", (char*) 0);
166  }
167  return p;
168 }
169 
170 char* stralloc(const char* buf, char* rel) {
171  /* allocate space, copy buf, and free rel */
172  char* s;
173  if (buf) {
174  s = static_cast<char*>(emalloc((unsigned) (strlen(buf) + 1)));
175  Strcpy(s, buf);
176  } else {
177  s = static_cast<char*>(emalloc(1));
178  s[0] = '\0';
179  }
180  if (rel) {
181  Free(rel);
182  }
183  return s;
184 }
185 
186 void deltokens(Item* q1, Item* q2) /* delete tokens from q1 to q2 */
187 {
188  /* It is a serious error if q2 precedes q1 */
189  Item* q;
190  for (q = q1; q != q2;) {
191  q = q->next;
192  remove(q->prev);
193  }
194  remove(q2);
195 }
196 
197 void move(Item* q1, Item* q2, Item* q3) /* move q1 to q2 and insert before q3*/
198 {
199  /* it is a serious error if q2 precedes q1 */
200  assert(q1 && q2);
201  assert(q1->itemtype && q2->itemtype);
202  q1->prev->next = q2->next; /* remove from first list */
203  q2->next->prev = q1->prev;
204 
205  q1->prev = q3->prev;
206  q3->prev->next = q1;
207  q3->prev = q2;
208  q2->next = q3;
209 }
210 
211 void movelist(Item* q1, Item* q2, List* s) /* move q1 to q2 from old list to end of list s*/
212 {
213  move(q1, q2, s);
214 }
215 
216 void replacstr(Item* q, const char* s) {
217  q->itemtype = STRING;
218  q->element.str = stralloc(s, (char*) 0);
219 }
220 
221 Item* putintoken(const char* s, short type) { /* make sure a symbol exists for s and
222  append to intoken list */
223  Symbol* sym;
224 
225  if (s == (char*) 0)
226  diag("internal error", " in putintoken");
227  switch (type) {
228  case STRING:
229  case REAL:
230  case INTEGER:
231  return insertstr(intoken, s);
232 
233  default:
234  if ((sym = lookup(s)) == SYM0) {
235  sym = install(s, type);
236  }
237  break;
238  }
239  return insertsym(intoken, sym);
240 }
#define STRING
Definition: bbslsrv.cpp:9
#define i
Definition: md1redef.h:19
char buf[512]
Definition: init.cpp:13
List * intoken
Definition: init.cpp:12
#define assert(ex)
Definition: hocassrt.h:24
#define SYM0
Definition: model.h:63
#define SYMBOL
Definition: model.h:91
#define ITEM
Definition: model.h:92
#define Strcpy
Definition: model.h:215
Symbol * lookup(const char *)
#define LIST
Definition: model.h:93
Symbol * install(const char *, int)
void remove(Item *item)
Definition: list.cpp:151
char * stralloc(const char *buf, char *rel)
Definition: list.cpp:178
void movelist(Item *q1, Item *q2, List *s)
Definition: list.cpp:214
Item * prev(Item *item)
Definition: list.cpp:94
void freelist(List **plist)
Definition: list.cpp:58
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:200
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
Item * next(Item *item)
Definition: list.cpp:89
void deltokens(Item *q1, Item *q2)
Definition: list.cpp:189
List * newlist()
Definition: list.cpp:48
Item * putintoken(const char *s, short type, short toktype)
Definition: list.cpp:224
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
static Item * linkitem(Item *item)
Definition: list.cpp:63
Item * insertlist(Item *item, List *lst)
Definition: list.cpp:109
static Item * newitem()
Definition: list.cpp:35
NMODL parser global flags / functions.
#define diag(s)
Definition: nonlin.cpp:19
int const size_t const size_t n
Definition: nrngsl.h:10
size_t q
size_t p
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
#define Free
Definition: list.cpp:38
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: model.h:47