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 {
94  return (Item *)emalloc(sizeof(Item));
95 }
96 
98 {
99  Item *i;
100  i = newitem();
101  i->prev = i;
102  i->next = i;
103  i->element.lst = (List *)0;
104  i->itemtype = 0;
105  return (List *)i;
106 }
107 
108 void freelist(List** plist) /*free the list but not the elements*/
109 {
110  Item *i1, *i2;
111  if (!(*plist)) {
112  return;
113  }
114  for (i1 = (*plist)->next; i1 != *plist; i1 = i2) {
115  i2 = i1->next;
116  Free(i1);
117  }
118  Free(*plist);
119  *plist = (List *)0;
120 }
121 
122 static Item *linkitem(Item *item)
123 {
124  Item *i;
125 
126  i = newitem();
127  i->prev = item->prev;
128  i->next = item;
129  item->prev = i;
130  i->prev->next = i;
131  return i;
132 }
133 
134 #if 0 /*currently unused*/
135 Item *next( Item *item)
136 {
137  assert(item->next->element.lst); /* never return the list item */
138  return item->next;
139 }
140 
141 Item *prev(Item *item)
142 {
143  assert(item->prev->element.lst); /* never return the list item */
144  return item->prev;
145 }
146 #endif
147 
148 Item *insertstr(Item* item, char* str) /* insert a copy of the string before item */
149 /* a copy is made because strings are often assembled into a reusable buffer*/
150 {
151  Item *i;
152 
153  i = linkitem(item);
154  i->element.str = stralloc(str, (char *)0);
155  i->itemtype = STRING;
156  return i;
157 }
158 
159 Item *insertitem(Item* item, Item* itm) /* insert a item pointer before item */
160 {
161  Item *i;
162 
163  i = linkitem(item);
164  i->element.itm = itm;
165  i->itemtype = ITEM;
166  return i;
167 }
168 
169 Item *insertlist(Item* item, List* lst) /* insert a item pointer before item */
170 {
171  Item *i;
172 
173  i = linkitem(item);
174  i->element.lst = lst;
175  i->itemtype = LIST;
176  return i;
177 }
178 
179 Item *insertsym(Item* item, Symbol* sym) /* insert a symbol before item */
180 /* a copy is not made because we need the same symbol in different lists */
181 {
182  Item *i;
183 
184  i = linkitem(item);
185  i->element.sym = sym;
186  i->itemtype = SYMBOL;
187  return i;
188 }
189 
190 Item *linsertstr(List* list, char* str)
191 {
192  return insertstr(list->next, str);
193 }
194 
195 Item *lappendstr(List* list, char* str)
196 {
197  return insertstr(list, str);
198 }
199 
200 Item *linsertsym(List* list, Symbol* sym)
201 {
202  return insertsym(list->next, sym);
203 }
204 
205 Item *lappendsym(List* list, Symbol* sym)
206 {
207  return insertsym(list, sym);
208 }
209 
210 Item *lappenditem(List* list, Item* item)
211 {
212  return insertitem(list, item);
213 }
214 
215 Item *lappendlst(List* list, List* lst)
216 {
217  return insertlist(list, lst);
218 }
219 
220 void remove(Item *item)
221 {
222  assert(item->itemtype); /* can't delete list */
223  item->next->prev = item->prev;
224  item->prev->next = item->next;
225  Free(item);
226 }
227 
228 char *emalloc(unsigned n) { /* check return from malloc */
229  char *p;
230  p = static_cast<char*>(malloc(n));
231  if (p == (char *)0) {
232  diag("out of memory", (char *)0);
233  }
234  return p;
235 }
236 
237 char *stralloc(char* buf, char* rel) {
238  /* allocate space, copy buf, and free rel */
239  char *s;
240  if (buf) {
241  s = static_cast<char *>(emalloc((unsigned)(strlen(buf) + 1)));
242  Strcpy(s, buf);
243  }else{
244  s = static_cast<char *>(emalloc(1));
245  s[0] = '\0';
246  }
247  if (rel) {
248  Free(rel);
249  }
250  return s;
251 }
252 
253 void deltokens(Item* q1, Item* q2) /* delete tokens from q1 to q2 */
254 {
255  /* It is a serious error if q2 precedes q1 */
256  Item *q;
257  for (q = q1; q != q2;) {
258  q = q->next;
259  remove(q->prev);
260  }
261  remove(q2);
262 
263 }
264 
265 void move(Item* q1, Item* q2, Item* q3) /* move q1 to q2 and insert before q3*/
266 {
267  /* it is a serious error if q2 precedes q1 */
268  assert(q1 && q2);
269  assert(q1->itemtype && q2->itemtype);
270  q1->prev->next = q2->next; /* remove from first list */
271  q2->next->prev = q1->prev;
272 
273  q1->prev = q3->prev;
274  q3->prev->next = q1;
275  q3->prev = q2;
276  q2->next = q3;
277 }
278 
279 void movelist(Item* q1, Item* q2, List* s) /* move q1 to q2 from old list to end of list s*/
280 {
281  move(q1, q2, s);
282 }
283 
284 void replacstr(Item* q, char* s)
285 {
286  q->itemtype = STRING;
287  q->element.str = stralloc(s, (char *)0);
288 
289 }
290 
291 Item *putintoken(char *s, short type)
292 { /* make sure a symbol exists for s and
293  append to intoken list */
294  Symbol *sym;
295 
296  if (s == (char *)0)
297  diag("internal error", " in putintoken");
298  switch (type) {
299 
300  case STRING:
301  case REAL:
302  case INTEGER:
303  return insertstr(intoken, s);
304 
305  default:
306  if ((sym = lookup(s)) == SYM0) {
307  sym = install(s, type);
308  }
309  break;
310  }
311  return insertsym(intoken, sym);
312 }
313 
314 
void deltokens(Item *q1, Item *q2)
Definition: list.cpp:219
char * stralloc(char *buf, char *rel)
Definition: list.cpp:208
short itemtype
Definition: model.h:16
#define assert(ex)
Definition: hocassrt.h:26
short type
Definition: cabvars.h:10
#define diag(s)
Definition: fmenu.cpp:188
static Item * newitem()
Definition: list.cpp:92
size_t p
Item * lappendsym(List *list, Symbol *sym)
Definition: list.cpp:161
#define REAL
Definition: machine.h:191
struct Item * prev
Definition: model.h:20
Item * next(Item *item)
Definition: list.cpp:95
#define LIST
Definition: model.h:104
#define SYMBOL
Definition: model.h:102
struct Item * next
Definition: model.h:19
Definition: model.h:15
Item * insertsym(Item *item, Symbol *sym)
Definition: list.cpp:131
Item * prev(Item *item)
Definition: list.cpp:101
#define install
Definition: redef.h:82
int const size_t const size_t n
Definition: nrngsl.h:12
#define Free
Definition: list.cpp:38
void movelist(Item *q1, Item *q2, List *s)
Definition: list.cpp:245
_CONST char * s
Definition: system.cpp:74
static Item * linkitem(Item *item)
Definition: list.cpp:122
Item * lappendstr(List *list, char *str)
Definition: list.cpp:149
Item * insertitem(Item *item, Item *itm)
Definition: list.cpp:120
#define STRING
Definition: bbslsrv.cpp:9
#define ITEM
Definition: model.h:103
Item * linsertstr(List *list, char *str)
Definition: list.cpp:143
Item * lappendlst(List *list, List *lst)
Definition: list.cpp:215
Definition: model.h:57
char * emalloc(unsigned n)
Definition: list.cpp:189
void * element
Definition: model.h:18
List * newlist()
Definition: list.cpp:50
#define Strcpy
Definition: model.h:253
NMODL parser global flags / functions.
#define lookup
Definition: redef.h:90
Item * lappenditem(List *list, Item *item)
Definition: list.cpp:167
Item * linsertsym(List *list, Symbol *sym)
Definition: list.cpp:155
Item * insertlist(Item *item, List *lst)
Definition: list.cpp:169
Item * insertstr(Item *item, char *str)
Definition: list.cpp:108
List * intoken
Definition: init.cpp:12
void freelist(List **plist)
Definition: list.cpp:61
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:231
#define i
Definition: md1redef.h:12
char buf[512]
Definition: init.cpp:13
Item * putintoken(char *s, short type, short toktype)
Definition: list.cpp:258
void replacstr(Item *q, char *s)
Definition: list.cpp:250
#define SYM0
Definition: model.h:74
size_t q