NEURON
strfun.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <OS/string.h>
3 #include <InterViews/regexp.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "classreg.h"
7 #include "oc2iv.h"
8 #include <string.h>
9 // for alias
10 #include <symdir.h>
11 #include <oclist.h>
12 #include <parse.hpp>
13 // for references
14 #include <hoclist.h>
15 #if HAVE_IV
16 #include <ocbox.h>
17 #endif
20 extern int nrn_is_artificial(int);
21 
22 extern int hoc_return_type_code;
23 
24 inline unsigned long key_to_hash(String& s) {
25  return s.hash();
26 }
27 
28 static double l_substr(void*) {
29  char* s1 = gargstr(1);
30  char* s2 = gargstr(2);
31  char* p = strstr(s1, s2);
32  hoc_return_type_code = 1; // integer
33  if (p) {
34  return double(p - s1);
35  } else {
36  return -1.;
37  }
38 }
39 
40 static double l_len(void*) {
41  hoc_return_type_code = 1; // integer
42  return double(strlen(gargstr(1)));
43 }
44 
45 static double l_head(void*) {
46  String text(gargstr(1));
47  Regexp r(gargstr(2));
48  r.Search(text.string(), text.length(), 0, text.length());
49  int i = r.BeginningOfMatch();
50  // text.set_to_left(i); doesnt work
51  char** head = hoc_pgargstr(3);
52  if (i > 0) {
53  char* buf = new char[i + 1];
54  strncpy(buf, text.string(), i);
55  buf[i] = '\0';
56  hoc_assign_str(head, buf);
57  delete[] buf;
58  } else {
59  hoc_assign_str(head, "");
60  }
61  hoc_return_type_code = 1; // integer
62  return double(i);
63 }
64 
65 static double l_tail(void*) {
67  Regexp r(gargstr(2));
68  r.Search(text.string(), text.length(), 0, text.length());
69  int i = r.EndOfMatch();
70  char** tail = hoc_pgargstr(3);
71  if (i >= 0) {
72  hoc_assign_str(tail, text.string() + i);
73  } else {
74  hoc_assign_str(tail, "");
75  }
76  hoc_return_type_code = 1; // integer
77  return double(i);
78 }
79 
80 static double l_left(void*) {
82  CopyString newtext = text.left(int(chkarg(2, 0, strlen(gargstr(1)))));
83  hoc_assign_str(hoc_pgargstr(1), newtext.string());
84  return 1.;
85 }
86 
87 static double l_right(void*) {
89  CopyString newtext = text.right(int(chkarg(2, 0, strlen(gargstr(1)))));
90  hoc_assign_str(hoc_pgargstr(1), newtext.string());
91  return 1.;
92 }
93 
94 static double l_is_name(void*) {
95  hoc_return_type_code = 2; // boolean
96  return hoc_lookup(gargstr(1)) ? 1. : 0.;
97 }
98 
99 
100 extern void hoc_free_symspace(Symbol*);
101 extern Object* hoc_newobj1(Symbol*, int);
103 
104 extern Symbol* ivoc_alias_lookup(const char* name, Object* ob) {
105  IvocAliases* a = (IvocAliases*) ob->aliases;
106  if (a) {
107  return a->lookup(name);
108  }
109  return NULL;
110 }
111 
112 extern void ivoc_free_alias(Object* ob) {
113  IvocAliases* a = (IvocAliases*) ob->aliases;
114  if (a)
115  delete a;
116 }
117 
118 
119 static double l_alias(void*) {
120  char* name;
121  Object* ob = *hoc_objgetarg(1);
122  IvocAliases* a = (IvocAliases*) ob->aliases;
123  Symbol* sym;
124 
125  if (!ifarg(2)) { // remove them all
126  if (a) {
127  delete a;
128  }
129  return 0.;
130  }
131  name = gargstr(2);
132  if (!a) {
133  a = new IvocAliases(ob);
134  }
135  sym = a->lookup(name);
136  if (sym) {
137  a->remove(sym);
138  }
139  if (ifarg(3)) {
140  sym = a->install(name);
141  if (hoc_is_object_arg(3)) {
142  sym->u.object_ = *hoc_objgetarg(3);
143  hoc_obj_ref(sym->u.object_);
144  sym->type = OBJECTALIAS;
145  } else {
146  sym->u.pval = hoc_pgetarg(3);
147  sym->type = VARALIAS;
148  }
149  }
150  return 0.;
151 }
152 
153 static Object** l_alias_list(void*) {
154  // Assumes that a hoc String exists with constructor that takes a strdef
155  Object* ob = *hoc_objgetarg(1);
156  IvocAliases* a = (IvocAliases*) ob->aliases;
157  OcList* list = new OcList();
158  list->ref();
159  Symbol* sl = hoc_lookup("List");
161  if (!st || st->type != TEMPLATE) {
162  printf("st=%p %s %d\n", st, st ? st->name : "NULL", st ? st->type : 0);
163  hoc_execerror("String is not a template", 0);
164  }
165  Object** po = hoc_temp_objvar(sl, list);
166  (*po)->refcount++;
167  int id = (*po)->index;
168  if (a) {
169  char buf[256];
170  for (auto& kv: a->symtab_) {
171  Symbol* sym = kv.second;
172  hoc_pushstr(&sym->name);
173  Object* sob = hoc_newobj1(st, 1);
174  list->append(sob);
175  --sob->refcount;
176  }
177  }
178  (*po)->refcount--;
179  return po;
180 }
181 
182 // does o refer to ob
183 static int l_ref2(Object* o, Object* ob, int nr) {
184  int i, total;
185  if (!o) {
186  return nr;
187  }
188  if (o->ctemplate->constructor) {
189  return nr;
190  }
191  Symlist* sl = o->ctemplate->symtable;
192  Symbol* s;
193  if (sl)
194  for (s = sl->first; s; s = s->next) {
195  if (s->type == OBJECTVAR && s->cpublic < 2) {
196  total = hoc_total_array_data(s, o->u.dataspace);
197  for (i = 0; i < total; ++i) {
198  Object** obp = o->u.dataspace[s->u.oboff].pobj + i;
199  if (*obp == ob) {
200  if (total == 1) {
201  Printf(" %s.%s\n", hoc_object_name(o), s->name);
202  } else {
203  Printf(" %s.%s[%d]\n", hoc_object_name(o), s->name, i);
204  }
205  ++nr;
206  }
207  }
208  }
209  }
210  return nr;
211 }
212 
213 // does data refer to ob
214 static int l_ref1(Symlist* sl, Objectdata* data, Object* ob, int nr) {
215  int i, total;
216  Symbol* s;
217  if (sl)
218  for (s = sl->first; s; s = s->next) {
219  if (s->type == OBJECTVAR && s->cpublic < 2) {
220  total = hoc_total_array_data(s, data);
221  for (i = 0; i < total; ++i) {
222  Object** obp = data[s->u.oboff].pobj + i;
223  if (*obp == ob) {
224  if (total == 1) {
225  Printf(" %s\n", s->name);
226  } else {
227  Printf(" %s[%d]\n", s->name, i);
228  }
229  ++nr;
230  }
231  }
232  }
233  }
234  return nr;
235 }
236 static int l_ref0(Symlist* sl, Object* ob, int nr) {
237  Symbol* s;
238  cTemplate* t;
239  if (sl)
240  for (s = sl->first; s; s = s->next) {
241  if (s->type == TEMPLATE) {
242  t = s->u.ctemplate;
243  hoc_Item* q;
244  ITERATE(q, t->olist) {
245  nr = l_ref2(OBJ(q), ob, nr);
246  }
247  }
248  }
249  return nr;
250 }
251 
252 static int l_ref3(Symbol* s, Object* ob, int nr) {
253 #if HAVE_IV
254  hoc_Item* q;
255  ITERATE(q, s->u.ctemplate->olist) {
256  OcBox* b = (OcBox*) (OBJ(q)->u.this_pointer);
257  if (b->keep_ref() == ob) {
258  Printf(" %s.ref\n", hoc_object_name(OBJ(q)));
259  ++nr;
260  }
261  }
262  return nr;
263 #else
264  return 0;
265 #endif
266 }
267 
268 static int l_ref4(Symbol* s, Object* ob, int nr) {
269  hoc_Item* q;
270  long i;
271  ITERATE(q, s->u.ctemplate->olist) {
272  OcList* list = (OcList*) (OBJ(q)->u.this_pointer);
273  if (list->refs_items())
274  for (i = 0; i < list->count(); ++i) {
275  if (list->object(i) == ob) {
276  Printf(" %s.object(%ld)\n", hoc_object_name(OBJ(q)), i);
277  ++nr;
278  }
279  }
280  }
281  return nr;
282 }
283 
284 static double l_ref(void*) {
285  Object* ob = *hoc_objgetarg(1);
286  int nr = ob ? ob->refcount : 0;
287  Printf("%s has %d references\n", hoc_object_name(ob), nr);
288  hoc_return_type_code = 1; // integer
289  if (nr == 0) {
290  return 0.;
291  }
292  nr = 0;
294  nr = l_ref0(hoc_top_level_symlist, ob, nr);
295  // any due to boxes
296  nr = l_ref3(hoc_table_lookup("HBox", hoc_built_in_symlist), ob, nr);
297  nr = l_ref3(hoc_table_lookup("VBox", hoc_built_in_symlist), ob, nr);
298  nr = l_ref4(hoc_table_lookup("List", hoc_built_in_symlist), ob, nr);
299 
300  Printf(" found %d of them\n", nr);
301  return (double) nr;
302 }
303 
304 static double l_is_point(void*) {
305  Object* ob = *hoc_objgetarg(1);
306  hoc_return_type_code = 1; // integer
307  return double(ob ? ob->ctemplate->is_point_ : 0);
308 }
309 
310 static double l_is_artificial(void*) {
311  Object* ob = *hoc_objgetarg(1);
312  int type = ob ? ob->ctemplate->is_point_ : 0;
313  hoc_return_type_code = 1; // integer
314  if (type == 0) {
315  return 0.;
316  }
317  return nrn_is_artificial(type) ? type : 0;
318 }
319 
320 static Member_func l_members[] = {"substr",
321  l_substr,
322  "len",
323  l_len,
324  "head",
325  l_head,
326  "tail",
327  l_tail,
328  "right",
329  l_right,
330  "left",
331  l_left,
332  "is_name",
333  l_is_name,
334  "alias",
335  l_alias,
336  "references",
337  l_ref,
338  "is_point_process",
339  l_is_point,
340  "is_artificial",
342  0,
343  0};
344 
345 static Member_ret_obj_func l_obj_members[] = {"alias_list", l_alias_list, 0, 0};
346 
347 static void* l_cons(Object*) {
348  return NULL;
349 }
350 
351 static void l_destruct(void*) {}
352 
354  class2oc("StringFunctions", l_cons, l_destruct, l_members, NULL, l_obj_members, NULL);
355 }
356 
357 
359  ob_ = ob;
360  ob_->aliases = (void*) this;
361 }
362 
364  ob_->aliases = NULL;
365  for (auto& kv: symtab_) {
366  Symbol* sym = kv.second;
367  hoc_free_symspace(sym);
368  free(sym->name);
369  free(sym);
370  }
371 }
373  String s(name);
374  const auto& it = symtab_.find(s);
375  if (it != symtab_.end()) {
376  return it->second;
377  }
378  return nullptr;
379 }
381  Symbol* sp;
382  sp = (Symbol*) emalloc(sizeof(Symbol));
383  sp->name = static_cast<char*>(emalloc(strlen(name) + 1));
384  strcpy(sp->name, name);
385  sp->type = VARALIAS;
386  sp->cpublic = 0; // cannot be 2 or cannot be freed
387  sp->extra = 0;
388  sp->arayinfo = 0;
389  String s(sp->name);
390  symtab_.emplace(s, sp);
391  return sp;
392 }
394  hoc_free_symspace(sym);
395  String s(sym->name);
396  auto it = symtab_.find(s);
397  symtab_.erase(it);
398  free(sym->name);
399  free(sym);
400 }
short type
Definition: cabvars.h:9
Object * ob_
Definition: symdir.h:22
virtual ~IvocAliases()
Definition: strfun.cpp:363
Symbol * install(const char *)
Definition: strfun.cpp:380
void remove(Symbol *)
Definition: strfun.cpp:393
Symbol * lookup(const char *)
Definition: strfun.cpp:372
IvocAliases(Object *)
Definition: strfun.cpp:358
std::map< String, Symbol * > symtab_
Definition: symdir.h:23
Definition: ocbox.h:11
void keep_ref(Object *)
Definition: oclist.h:12
long count()
Definition: oclist.cpp:187
bool refs_items()
Definition: oclist.h:25
Object * object(long)
Definition: oclist.cpp:231
Definition: regexp.h:64
int EndOfMatch(int subexp=0)
Definition: regexp.cpp:234
int BeginningOfMatch(int subexp=0)
Definition: regexp.cpp:227
int Search(const char *text, int length, int index, int range)
Definition: regexp.cpp:111
virtual void ref() const
Definition: resource.cpp:47
Definition: string.h:34
virtual unsigned long hash() const
Definition: string.cpp:74
const char * string() const
Definition: string.h:139
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:61
double t
Definition: cvodeobj.cpp:59
double chkarg(int, double low, double high)
Definition: code2.cpp:638
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
char buf[512]
Definition: init.cpp:13
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
void hoc_pushstr(char **d)
Definition: code.cpp:680
size_t hoc_total_array_data(Symbol *s, Objectdata *obd)
Definition: hoc_oop.cpp:94
Object ** hoc_temp_objvar(Symbol *symtemp, void *v)
Definition: hoc_oop.cpp:491
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2350
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1810
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:72
void ivoc_free_alias(Object *ob)
Definition: strfun.cpp:112
Symbol * hoc_lookup(const char *)
double * hoc_pgetarg(int narg)
Definition: code.cpp:1623
Symbol * ivoc_alias_lookup(const char *name, Object *ob)
Definition: strfun.cpp:104
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1599
#define OBJECTALIAS
Definition: hocdec.h:107
#define gargstr
Definition: hocdec.h:14
#define VARALIAS
Definition: hocdec.h:108
#define OBJ(q)
Definition: hoclist.h:67
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
int ifarg(int)
Definition: code.cpp:1581
#define i
Definition: md1redef.h:12
#define ITERATE(itm, lst)
Definition: model.h:25
#define Printf
Definition: model.h:237
char * name
Definition: init.cpp:16
char * emalloc(unsigned n)
Definition: list.cpp:166
#define printf
Definition: mwprefix.h:26
size_t q
if(status)
size_t p
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1560
#define text
Definition: plot.cpp:85
#define data
Definition: rbtqueue.cpp:49
sl
Definition: seclist.cpp:181
o
Definition: seclist.cpp:175
#define NULL
Definition: sptree.h:16
static int l_ref2(Object *o, Object *ob, int nr)
Definition: strfun.cpp:183
static double l_is_artificial(void *)
Definition: strfun.cpp:310
static double l_tail(void *)
Definition: strfun.cpp:65
static double l_left(void *)
Definition: strfun.cpp:80
static int l_ref3(Symbol *s, Object *ob, int nr)
Definition: strfun.cpp:252
Symlist * hoc_top_level_symlist
Definition: symdir.cpp:23
static int l_ref4(Symbol *s, Object *ob, int nr)
Definition: strfun.cpp:268
static double l_len(void *)
Definition: strfun.cpp:40
void StringFunctions_reg()
Definition: strfun.cpp:353
static void * l_cons(Object *)
Definition: strfun.cpp:347
static Object ** l_alias_list(void *)
Definition: strfun.cpp:153
static double l_substr(void *)
Definition: strfun.cpp:28
Object * hoc_newobj1(Symbol *, int)
Definition: hoc_oop.cpp:565
static Member_ret_obj_func l_obj_members[]
Definition: strfun.cpp:345
int hoc_return_type_code
Definition: code.cpp:42
static double l_ref(void *)
Definition: strfun.cpp:284
void hoc_free_symspace(Symbol *)
Definition: symbol.cpp:271
unsigned long key_to_hash(String &s)
Definition: strfun.cpp:24
static void l_destruct(void *)
Definition: strfun.cpp:351
static double l_head(void *)
Definition: strfun.cpp:45
static int l_ref1(Symlist *sl, Objectdata *data, Object *ob, int nr)
Definition: strfun.cpp:214
static double l_right(void *)
Definition: strfun.cpp:87
int nrn_is_artificial(int)
Definition: init.cpp:201
static double l_is_name(void *)
Definition: strfun.cpp:94
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:124
static int l_ref0(Symlist *sl, Object *ob, int nr)
Definition: strfun.cpp:236
Symlist * hoc_built_in_symlist
Definition: ivocmac.cpp:76
static Member_func l_members[]
Definition: strfun.cpp:320
static double l_is_point(void *)
Definition: strfun.cpp:304
static double l_alias(void *)
Definition: strfun.cpp:119
Definition: hocdec.h:227
void * aliases
Definition: hocdec.h:239
int refcount
Definition: hocdec.h:228
Definition: model.h:57
short cpublic
Note: public is a reserved keyword.
Definition: hocdec.h:125
short type
Definition: model.h:58
HocStruct Symbol * next
Definition: hocdec.h:162
HocStruct Object * object_
Definition: hocdec.h:138
union Symbol::@18 u
char * name
Definition: model.h:72
HocSymExtension * extra
Definition: hocdec.h:160
HocStruct cTemplate * ctemplate
Definition: hocdec.h:152
int oboff
Definition: hocdec.h:132
Arrayinfo * arayinfo
Definition: hocdec.h:159
Definition: hocdec.h:84
hoc_List * olist
Definition: hocdec.h:204
char * strstr(char *cs, char *ct)
Definition: xred.cpp:173