NEURON
symbol.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/oc/symbol.cpp,v 1.9 1999/02/25 18:01:58 hines Exp */
3 /* version 7.2.1 2-jan-89 */
4 
5 #include "hocdec.h"
6 #include "hoclist.h"
8 #include "oc_ansi.h"
9 #include "ocnotify.h"
10 #include "parse.hpp"
11 
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring>
15 
16 #if HAVE_MALLOC_H
17 #include <malloc.h>
18 #endif
19 
20 #include "nrnmpiuse.h"
21 
22 #if defined(__APPLE__) && defined(__MACH__)
23 #include <mach/mach.h>
24 #endif
25 
26 #include "utils/logger.hpp"
27 
28 Symlist* hoc_built_in_symlist = nullptr; /* keywords, built-in functions,
29  all name linked into hoc. Look in this list last */
30 Symlist* hoc_top_level_symlist = nullptr; /* all user names seen at top-level
31  (non-public names inside templates do not appear here) */
33 
34 Symlist* hoc_symlist = nullptr; /* the current user symbol table: linked list */
35 Symlist* hoc_p_symlist = nullptr; /* current proc, func, or temp table */
36  /* containing constants, strings, and auto */
37  /* variables. Discarding these lists at */
38  /* appropriate times prevents storage leakage. */
39 
40 void print_symlist(const char* s, Symlist* tab) {
41  Printf("%s\n", s);
42  if (tab)
43  for (Symbol* sp = tab->first; sp != nullptr; sp = sp->next) {
44  Printf("%s %p\n", sp->name, fmt::ptr(sp));
45  }
46 }
47 
48 Symbol* hoc_table_lookup(const char* s, Symlist* tab) /* find s in specific table */
49 {
50  if (tab)
51  for (Symbol* sp = tab->first; sp != nullptr; sp = sp->next) {
52  if (strcmp(sp->name, s) == 0) {
53  return sp;
54  }
55  }
56  return nullptr;
57 }
58 
59 Symbol* hoc_lookup(const char* s) /* find s in symbol table */
60  /* look in p_symlist then built_in_symlist then symlist */
61 {
62  Symbol* sp;
63 
64  if ((sp = hoc_table_lookup(s, hoc_p_symlist)) != nullptr) {
65  return sp;
66  }
67  if ((sp = hoc_table_lookup(s, hoc_symlist)) != nullptr) {
68  return sp;
69  }
70  if ((sp = hoc_table_lookup(s, hoc_built_in_symlist)) != nullptr) {
71  return sp;
72  }
73 
74  return nullptr; /* nullptr ==> not found */
75 }
76 
77 Symbol* hoc_install(/* install s in the list symbol table */
78  const char* s,
79  int t,
80  double d,
81  Symlist** list) {
82  Symbol* sp = (Symbol*) emalloc(sizeof(Symbol));
83  sp->name = (char*) emalloc((unsigned) (strlen(s) + 1)); /* +1 for '\0' */
84  Strcpy(sp->name, s);
85  sp->type = t;
86  sp->subtype = NOTUSER;
87  sp->defined_on_the_fly = 0;
88  sp->cpublic = 0;
89  sp->s_varn = 0;
90  sp->arayinfo = nullptr;
91  sp->extra = nullptr;
92  if (!(*list)) {
93  *list = (Symlist*) emalloc(sizeof(Symlist));
94  (*list)->first = (*list)->last = nullptr;
95  }
96  hoc_link_symbol(sp, *list);
97  switch (t) {
98  case NUMBER:
99  sp->u.pnum = (double*) emalloc(sizeof(double));
100  *sp->u.pnum = d;
101  break;
102  case VAR:
104  OPVAL(sp) = (double*) emalloc(sizeof(double));
105  *(OPVAL(sp)) = d;
106  break;
107  case PROCEDURE:
108  case FUNCTION:
109  case FUN_BLTIN:
110  case OBFUNCTION:
111  case STRFUNCTION:
112  sp->u.u_proc = (Proc*) ecalloc(1, sizeof(Proc));
113  sp->u.u_proc->list = nullptr;
114  sp->u.u_proc->size = 0;
115  break;
116  default:
117  sp->u.pnum = nullptr;
118  break;
119  }
120  return sp;
121 }
122 
123 Symbol* hoc_install_var(const char* name, double* pval) {
124  Symbol* s = hoc_install(name, UNDEF, 0., &hoc_symlist);
125  s->type = VAR;
126  s->u.pval = pval;
127  s->subtype = USERDOUBLE;
128  return s;
129 }
130 
132  assert(list);
133 
134  if (list->first == s) {
135  list->first = s->next;
136  if (list->last == s) {
137  list->last = nullptr;
138  }
139  } else {
140  Symbol* sp;
141  for (sp = list->first; sp != nullptr; sp = sp->next) {
142  if (sp->next == s) {
143  break;
144  }
145  }
146  assert(sp);
147  sp->next = s->next;
148  if (list->last == s) {
149  list->last = sp;
150  }
151  }
152  s->next = nullptr;
153 }
154 
155 void hoc_link_symbol(Symbol* sp, Symlist* list) {
156  /* put at end of list */
157  if (list->last) {
158  list->last->next = sp;
159  } else {
160  list->first = sp;
161  }
162  list->last = sp;
163  sp->next = nullptr;
164 }
165 
166 void hoc_free_symspace(Symbol* s1) { /* frees symbol space. Marks it UNDEF */
167  if (s1 && s1->cpublic != 2) {
168  switch (s1->type) {
169  case UNDEF:
170  case STRING:
171  case VAR:
172  break;
173  case NUMBER:
174  free((char*) (s1->u.pnum));
175  break;
176  case CSTRING:
177  free(s1->u.cstr);
178  break;
179  case PROCEDURE:
180  case FUNCTION:
181  if (s1->u.u_proc != nullptr) {
182  if (s1->u.u_proc->defn.in != STOP)
183  free((char*) s1->u.u_proc->defn.in);
184  hoc_free_list(&(s1->u.u_proc->list));
185  free((char*) s1->u.u_proc);
186  }
187  break;
188  case AUTO:
189  case AUTOOBJ:
190  break;
191  case TEMPLATE:
194  {
195  hoc_List* l = s1->u.ctemplate->olist;
196  if (l->next == l) {
198  free(s1->u.ctemplate);
199  } else {
200  hoc_warning("didn't free all objects created with the old template:", s1->name);
201  }
202  }
203  break;
204  case OBJECTVAR:
205 #if 0 /* should have been freed above, otherwise I don't know the exact objects*/
206  if (s1->arayinfo) {int i, j, k=0;
207  for (i = 0; i < s1->arayinfo->nsub; i++) {
208  for (j=0; j < s1->arayinfo->sub[i]; j++) {
209  hoc_dec_refcount(OPOBJ(s1) + k);
210  ++k;
211  }
212  }
213  }else{
214  hoc_dec_refcount(OPOBJ(s1));
215  }
216  free((char *)OPOBJ(s1));
217 #endif
218  break;
219  case OBJECTALIAS:
220  hoc_obj_unref(s1->u.object_);
221  break;
222  case VARALIAS:
223  break;
224  default:
225  Fprintf(stderr,
226  "In free_symspace may not free all of %s of type=%d\n",
227  s1->name,
228  s1->type);
229  }
230  if (s1->arayinfo != nullptr) {
232  s1->arayinfo = nullptr;
233  }
234  }
235  if (s1->extra) {
236  if (s1->extra->parmlimits) {
237  free(s1->extra->parmlimits);
238  }
239  if (s1->extra->units) {
240  free(s1->extra->units);
241  }
242  free(s1->extra);
243  s1->extra = nullptr;
244  }
245  s1->type = UNDEF;
246 }
247 
249  if (!sym->extra) {
250  sym->extra = (HocSymExtension*) ecalloc(1, sizeof(HocSymExtension));
251  }
252 }
253 
254 void hoc_free_list(Symlist** list) { /* free the space in a symbol table */
255  if (!*list) {
256  return;
257  }
258 
259  Symbol* s1 = (*list)->first;
260  while (s1) {
261  Symbol* s2 = s1->next;
262  hoc_free_symspace(s1);
263  if (s1->name) {
264  free(s1->name);
265  }
266  free((char*) s1);
267  s1 = s2;
268  }
269  free((char*) (*list));
270  *list = nullptr;
271 }
272 
273 void hoc_free_val(double* p) {
274  notify_freed(p);
275  free(p);
276 }
277 
278 void hoc_free_val_array(double* p, size_t size) {
279  notify_freed_val_array(p, size);
280  free(p);
281 }
282 
284  if (p) {
286  free(p);
287  }
288 }
289 
290 void hoc_free_string(char* p) {
291  free(p);
292 }
293 
294 void hoc_free_pstring(char** p) {
295  notify_freed((void*) p);
296  if (*p) {
297  free(*p);
298  free(p);
299  }
300 }
301 
302 size_t nrn_mallinfo(int item) {
303 #if defined(__APPLE__) && defined(__MACH__)
304  /* OSX ------------------------------------------------------
305  * Returns the current resident set size (physical memory use) measured
306  * in bytes, or zero if the value cannot be determined on this OS.
307  */
308  struct mach_task_basic_info info;
309  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
310  if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t) &info, &infoCount) !=
311  KERN_SUCCESS)
312  return (size_t) 0L; /* Can't access? */
313  return (size_t) info.resident_size;
314 #elif HAVE_MALLINFO || HAVE_MALLINFO2
315  // *nix platforms with mallinfo[2]()
316  size_t r;
317  // prefer mallinfo2, fall back to mallinfo
318 #if HAVE_MALLINFO2
319  auto const m = mallinfo2();
320 #else
321  auto const m = mallinfo();
322 #endif
323  if (item == 1) {
324  r = m.uordblks;
325  } else if (item == 2) {
326  r = m.hblkhd;
327  } else if (item == 3) {
328  r = m.arena;
329  } else if (item == 4) {
330  r = m.fordblks;
331  } else if (item == 5) {
332  r = m.hblks;
333  } else if (item == 6) {
334  r = m.hblkhd + m.arena;
335  } else {
336  r = m.hblkhd + m.uordblks;
337  }
338  return r;
339 #else
340  /* UNSUPPORTED PLATFORM ------------------------------------ */
341  return 0;
342 #endif
343 }
344 
345 void hoc_mallinfo() {
346  int const i = chkarg(1, 0, 6);
347  auto const x = nrn_mallinfo(i);
348  hoc_ret();
349  hoc_pushx(x);
350 }
351 
352 // TODO: would it be useful to return the handle itself to Python, for use with
353 // ctypes CDLL and so on?
355  bool success{false};
356  try {
357  success = get_coreneuron_handle();
358  } catch (std::runtime_error const& e) {
359  }
360  hoc_retpushx(success);
361 }
#define STRING
Definition: bbslsrv.cpp:9
#define pval
Definition: md1redef.h:40
#define i
Definition: md1redef.h:19
double chkarg(int, double low, double high)
Definition: code2.cpp:626
static RNG::key_type k
Definition: nrnran123.cpp:9
void hoc_unlink_symbol(Symbol *s, Symlist *list)
Definition: symbol.cpp:131
void sym_extra_alloc(Symbol *sym)
Definition: symbol.cpp:248
void hoc_ret()
void hoc_free_string(char *p)
Definition: symbol.cpp:290
Symbol * hoc_install(const char *s, int t, double d, Symlist **list)
Definition: symbol.cpp:77
void hoc_free_object(Object *p)
Definition: symbol.cpp:283
void hoc_free_pstring(char **p)
Definition: symbol.cpp:294
void notify_pointer_freed(void *pt)
Definition: ivoc.cpp:132
Symbol * hoc_table_lookup(const char *s, Symlist *tab)
Definition: symbol.cpp:48
void hoc_free_list(Symlist **list)
Definition: symbol.cpp:254
size_t nrn_mallinfo(int item)
Definition: symbol.cpp:302
void hoc_retpushx(double x)
Definition: hocusr.cpp:154
Symbol * hoc_install_var(const char *name, double *pval)
Definition: symbol.cpp:123
void hoc_dec_refcount(Object **pobj)
Definition: hoc_oop.cpp:1850
void hoc_install_object_data_index(Symbol *sp)
Definition: hoc_oop.cpp:297
Symbol * hoc_lookup(const char *s)
Definition: symbol.cpp:59
void hoc_free_arrayinfo(Arrayinfo *a)
Definition: hoc.cpp:579
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1881
void hoc_free_allobjects(cTemplate *ctemplate, Symlist *sl, Objectdata *data)
Definition: hoc_oop.cpp:1732
void notify_freed(void *p)
Definition: ivoc.cpp:144
void hoc_link_symbol(Symbol *sp, Symlist *list)
Definition: symbol.cpp:155
#define assert(ex)
Definition: hocassrt.h:24
#define OBJECTALIAS
Definition: hocdec.h:94
#define USERDOUBLE
Definition: hocdec.h:84
#define NOTUSER
Definition: hocdec.h:82
#define OPOBJ(sym)
Definition: hocdec.h:236
#define OPVAL(sym)
Definition: hocdec.h:234
#define STOP
Definition: hocdec.h:57
#define VARALIAS
Definition: hocdec.h:95
void hoc_l_freelist(hoc_List **)
void notify_freed_val_array(double *p, size_t size)
Definition: ivoc.cpp:152
void hoc_pushx(double)
Definition: code.cpp:779
#define Strcpy
Definition: model.h:215
const char * name
Definition: init.cpp:16
void * ecalloc(size_t n, size_t size)
Definition: nrnoc_aux.cpp:85
static void * emalloc(size_t size)
Definition: mpispike.cpp:30
void hoc_warning(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:44
static List * info
#define FUNCTION(a, b)
Definition: nrngsl.h:5
size_t p
size_t j
s
Definition: multisend.cpp:521
void hoc_free_val(double *p)
Definition: symbol.cpp:273
void hoc_mallinfo()
Definition: symbol.cpp:345
Symlist * hoc_top_level_symlist
Definition: symbol.cpp:30
void print_symlist(const char *s, Symlist *tab)
Definition: symbol.cpp:40
void hoc_free_symspace(Symbol *s1)
Definition: symbol.cpp:166
void hoc_free_val_array(double *p, size_t size)
Definition: symbol.cpp:278
void hoc_coreneuron_handle()
Definition: symbol.cpp:354
Symlist * hoc_symlist
Definition: symbol.cpp:34
Symlist * hoc_p_symlist
Definition: symbol.cpp:35
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:123
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:28
HOC interpreter function declarations (included by hocdec.h)
int nsub
Definition: hocdec.h:61
int sub[1]
Definition: hocdec.h:63
float * parmlimits
Definition: hocdec.h:98
char * units
Definition: hocdec.h:99
Definition: hocdec.h:173
Definition: hocdec.h:66
Inst defn
Definition: hocdec.h:67
unsigned long size
Definition: hocdec.h:68
Symlist * list
Definition: hocdec.h:69
Definition: model.h:47
Proc * u_proc
Definition: hocdec.h:120
Symbol * next
Definition: hocdec.h:133
union Symbol::@28 u
short cpublic
Definition: hocdec.h:107
Object * object_
Definition: hocdec.h:113
short type
Definition: model.h:48
double * pnum
Definition: hocdec.h:115
long subtype
Definition: model.h:49
cTemplate * ctemplate
Definition: hocdec.h:126
char * cstr
Definition: hocdec.h:114
unsigned s_varn
Definition: hocdec.h:129
char * name
Definition: model.h:61
HocSymExtension * extra
Definition: hocdec.h:131
Arrayinfo * arayinfo
Definition: hocdec.h:130
short defined_on_the_fly
Definition: hocdec.h:108
Definition: hocdec.h:75
Symbol * last
Definition: hocdec.h:77
Symbol * first
Definition: hocdec.h:76
Symlist * symtable
Definition: hocdec.h:148
hoc_List * olist
Definition: hocdec.h:155
hoc_Item * next
Definition: hoclist.h:44
Inst * in
Definition: hocdec.h:51
int Fprintf(FILE *stream, const char *fmt, Args... args)
Definition: logger.hpp:8
int Printf(const char *fmt, Args... args)
Definition: logger.hpp:18