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