NEURON
list.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.h>
2 /* /local/src/master/nrn/src/nmodl/list.c,v 4.2 1998/01/22 18:50:32 hines Exp */
3 /*
4 list.c,v
5  * Revision 4.2 1998/01/22 18:50:32 hines
6  * allow stralloc with null string (creates empty string)
7  *
8  * Revision 4.1 1997/08/30 20:45:25 hines
9  * cvs problem with branches. Latest nmodl stuff should now be a top level
10  *
11  * Revision 4.0.1.1 1997/08/08 17:23:50 hines
12  * nocmodl version 4.0.1
13  *
14  * Revision 4.0 1997/08/08 17:06:16 hines
15  * proper nocmodl version number
16  *
17  * Revision 1.1.1.1 1994/10/12 17:21:35 hines
18  * NEURON 3.0 distribution
19  *
20  * Revision 9.159 93/02/11 16:55:37 hines
21  * minor mods for NeXT
22  *
23  * Revision 9.78 90/12/10 16:56:39 hines
24  * TABLE allowed in FUNCTION and PROCEDURE
25  *
26  * Revision 9.76 90/12/07 09:27:14 hines
27  * new list structure that uses unions instead of void *element
28  *
29  * Revision 8.1 89/09/29 16:26:03 mlh
30  * ifdef for VMS and SYSV and some fixing of assert
31  *
32  * Revision 8.0 89/09/22 17:26:18 nfh
33  * Freezing
34  *
35  * Revision 7.1 89/09/05 08:07:12 mlh
36  * lappenditem() for use with lists of items which point to items
37  * ITM(q) analogous to SYM(q)
38  *
39  * Revision 7.0 89/08/30 13:31:47 nfh
40  * Rev 7 is now Experimental; Rev 6 is Testing
41  *
42  * Revision 6.0 89/08/14 16:26:30 nfh
43  * Rev 6.0 is latest of 4.x; now the Experimental version
44  *
45  * Revision 4.1 89/08/07 15:34:30 mlh
46  * freelist now takes pointer to list pointer and 0's the list pointer.
47  * Not doing this is a bug for multiple sens blocks, etc.
48  *
49  * Revision 4.0 89/07/24 17:02:57 nfh
50  * Freezing rev 3. Rev 4 is now Experimental
51  *
52  * Revision 3.1 89/07/07 16:54:16 mlh
53  * FIRST LAST START in independent SWEEP higher order derivatives
54  *
55  * Revision 1.1 89/07/06 14:49:26 mlh
56  * Initial revision
57  *
58 */
59 
60 /* The following routines support the concept of a list.
61 That is, one can insert at the head of a list or append to the tail of a
62 list with linsert<type>() and lappend<type>().
63 
64 In addition, one can insert an item before a known item and it will be
65 placed in the proper list.
66 
67 Items point to strings, symbols, etc. Note that more than one item in the
68 same or several lists can point to the same string, symbol.
69 
70 Finally, knowing an item, one can determine the preceding and following
71 items with next() and prev().
72 
73 Deletion, replacement and moving blocks of items is also supported.
74 */
75 
76 /* Implementation
77  The list is a doubly linked list. A special item with element 0 is
78  always at the tail of the list and is denoted as the List pointer itself.
79  list->next point to the first item in the list and
80  list->prev points to the last item in the list.
81  i.e. the list is circular
82  Note that in an empty list next and prev points to itself.
83 
84 It is intended that this implementation be hidden from the user via the
85 following function calls.
86 */
87 
88 #include <stdlib.h>
89 #include "modl.h"
90 #include "parse1.hpp"
91 
92 static Item* newitem() {
93  return (Item*) emalloc(sizeof(Item));
94 }
95 
97  Item* i;
98  i = newitem();
99  i->prev = i;
100  i->next = i;
101  i->element.lst = (List*) 0;
102  i->itemtype = 0;
103  return (List*) i;
104 }
105 
106 void freelist(List** plist) /*free the list but not the elements*/
107 {
108  Item *i1, *i2;
109  if (!(*plist)) {
110  return;
111  }
112  for (i1 = (*plist)->next; i1 != *plist; i1 = i2) {
113  i2 = i1->next;
114  Free(i1);
115  }
116  Free(*plist);
117  *plist = (List*) 0;
118 }
119 
120 static Item* linkitem(Item* item) {
121  Item* i;
122 
123  i = newitem();
124  i->prev = item->prev;
125  i->next = item;
126  item->prev = i;
127  i->prev->next = i;
128  return i;
129 }
130 
131 #if 0 /*currently unused*/
132 Item *next( Item *item)
133 {
134  assert(item->next->element.lst); /* never return the list item */
135  return item->next;
136 }
137 
138 Item *prev(Item *item)
139 {
140  assert(item->prev->element.lst); /* never return the list item */
141  return item->prev;
142 }
143 #endif
144 
145 Item* insertstr(Item* item, char* str) /* insert a copy of the string before item */
146 /* a copy is made because strings are often assembled into a reusable buffer*/
147 {
148  Item* i;
149 
150  i = linkitem(item);
151  i->element.str = stralloc(str, (char*) 0);
152  i->itemtype = STRING;
153  return i;
154 }
155 
156 Item* insertitem(Item* item, Item* itm) /* insert a item pointer before item */
157 {
158  Item* i;
159 
160  i = linkitem(item);
161  i->element.itm = itm;
162  i->itemtype = ITEM;
163  return i;
164 }
165 
166 Item* insertlist(Item* item, List* lst) /* insert a item pointer before item */
167 {
168  Item* i;
169 
170  i = linkitem(item);
171  i->element.lst = lst;
172  i->itemtype = LIST;
173  return i;
174 }
175 
176 Item* insertsym(Item* item, Symbol* sym) /* insert a symbol before item */
177 /* a copy is not made because we need the same symbol in different lists */
178 {
179  Item* i;
180 
181  i = linkitem(item);
182  i->element.sym = sym;
183  i->itemtype = SYMBOL;
184  return i;
185 }
186 
187 Item* linsertstr(List* list, char* str) {
188  return insertstr(list->next, str);
189 }
190 
191 Item* lappendstr(List* list, char* str) {
192  return insertstr(list, str);
193 }
194 
195 Item* linsertsym(List* list, Symbol* sym) {
196  return insertsym(list->next, sym);
197 }
198 
199 Item* lappendsym(List* list, Symbol* sym) {
200  return insertsym(list, sym);
201 }
202 
203 Item* lappenditem(List* list, Item* item) {
204  return insertitem(list, item);
205 }
206 
207 Item* lappendlst(List* list, List* lst) {
208  return insertlist(list, lst);
209 }
210 
211 void remove(Item* item) {
212  assert(item->itemtype); /* can't delete list */
213  item->next->prev = item->prev;
214  item->prev->next = item->next;
215  Free(item);
216 }
217 
218 char* emalloc(unsigned n) { /* check return from malloc */
219  char* p;
220  p = static_cast<char*>(malloc(n));
221  if (p == (char*) 0) {
222  diag("out of memory", (char*) 0);
223  }
224  return p;
225 }
226 
227 char* stralloc(char* buf, char* rel) {
228  /* allocate space, copy buf, and free rel */
229  char* s;
230  if (buf) {
231  s = static_cast<char*>(emalloc((unsigned) (strlen(buf) + 1)));
232  Strcpy(s, buf);
233  } else {
234  s = static_cast<char*>(emalloc(1));
235  s[0] = '\0';
236  }
237  if (rel) {
238  Free(rel);
239  }
240  return s;
241 }
242 
243 void deltokens(Item* q1, Item* q2) /* delete tokens from q1 to q2 */
244 {
245  /* It is a serious error if q2 precedes q1 */
246  Item* q;
247  for (q = q1; q != q2;) {
248  q = q->next;
249  remove(q->prev);
250  }
251  remove(q2);
252 }
253 
254 void move(Item* q1, Item* q2, Item* q3) /* move q1 to q2 and insert before q3*/
255 {
256  /* it is a serious error if q2 precedes q1 */
257  assert(q1 && q2);
258  assert(q1->itemtype && q2->itemtype);
259  q1->prev->next = q2->next; /* remove from first list */
260  q2->next->prev = q1->prev;
261 
262  q1->prev = q3->prev;
263  q3->prev->next = q1;
264  q3->prev = q2;
265  q2->next = q3;
266 }
267 
268 void movelist(Item* q1, Item* q2, List* s) /* move q1 to q2 from old list to end of list s*/
269 {
270  move(q1, q2, s);
271 }
272 
273 void replacstr(Item* q, char* s) {
274  q->itemtype = STRING;
275  q->element.str = stralloc(s, (char*) 0);
276 }
277 
278 Item* putintoken(char* s, short type) { /* make sure a symbol exists for s and
279  append to intoken list */
280  Symbol* sym;
281 
282  if (s == (char*) 0)
283  diag("internal error", " in putintoken");
284  switch (type) {
285  case STRING:
286  case REAL:
287  case INTEGER:
288  return insertstr(intoken, s);
289 
290  default:
291  if ((sym = lookup(s)) == SYM0) {
292  sym = install(s, type);
293  }
294  break;
295  }
296  return insertsym(intoken, sym);
297 }
short type
Definition: cabvars.h:9
#define diag(s)
Definition: fmenu.cpp:192
char buf[512]
Definition: init.cpp:13
List * intoken
Definition: init.cpp:12
#define assert(ex)
Definition: hocassrt.h:32
#define REAL
Definition: machine.h:191
#define i
Definition: md1redef.h:12
#define SYM0
Definition: model.h:74
#define SYMBOL
Definition: model.h:102
#define ITEM
Definition: model.h:103
#define Strcpy
Definition: model.h:238
#define LIST
Definition: model.h:104
NMODL parser global flags / functions.
Item * putintoken(char *s, short type, short toktype)
Definition: list.cpp:230
Item * lappendstr(List *list, char *str)
Definition: list.cpp:134
void remove(Item *item)
Definition: list.cpp:150
Item * linsertstr(List *list, char *str)
Definition: list.cpp:130
void movelist(Item *q1, Item *q2, List *s)
Definition: list.cpp:220
Item * prev(Item *item)
Definition: list.cpp:93
void freelist(List **plist)
Definition: list.cpp:57
Item * insertstr(Item *item, char *str)
Definition: list.cpp:98
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:206
void replacstr(Item *q, char *s)
Definition: list.cpp:225
char * emalloc(unsigned n)
Definition: list.cpp:166
char * stralloc(char *buf, char *rel)
Definition: list.cpp:184
Item * next(Item *item)
Definition: list.cpp:88
void deltokens(Item *q1, Item *q2)
Definition: list.cpp:195
List * newlist()
Definition: list.cpp:47
Item * lappenditem(List *list, Item *item)
Definition: list.cpp:146
Item * insertsym(Item *item, Symbol *sym)
Definition: list.cpp:119
Item * insertitem(Item *item, Item *itm)
Definition: list.cpp:109
Item * linsertsym(List *list, Symbol *sym)
Definition: list.cpp:138
Item * lappendsym(List *list, Symbol *sym)
Definition: list.cpp:142
Item * lappendlst(List *list, List *lst)
Definition: list.cpp:207
static Item * linkitem(Item *item)
Definition: list.cpp:120
Item * insertlist(Item *item, List *lst)
Definition: list.cpp:166
static Item * newitem()
Definition: list.cpp:92
int const size_t const size_t n
Definition: nrngsl.h:11
size_t q
size_t p
#define Free
Definition: list.cpp:38
#define STRING
Definition: bbslsrv.cpp:9
#define lookup
Definition: redef.h:90
#define install
Definition: redef.h:82
Definition: model.h:15
struct Item * prev
Definition: model.h:20
void * element
Definition: model.h:18
short itemtype
Definition: model.h:16
struct Item * next
Definition: model.h:19
Definition: model.h:57