Edinburgh Speech Tools  2.1-release
siod.cc
Go to the documentation of this file.
1 /* Scheme In One Defun, but in C this time.
2 
3  * COPYRIGHT (c) 1988-1994 BY *
4  * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. *
5  * See the source file SLIB.C for more information. *
6 
7 */
8 
9 /*
10 
11 gjc@paradigm.com or gjc@mitech.com or gjc@world.std.com
12 
13 Paradigm Associates Inc Phone: 617-492-6079
14 29 Putnam Ave, Suite 6
15 Cambridge, MA 02138
16 
17  */
18 
19 /***************************************************************/
20 /* This has been modified to act as an interface to siod as an */
21 /* embedded Lisp module. */
22 /* Also a (large) number of other functions have been added */
23 /* */
24 /* Alan W Black (awb@cstr.ed.ac.uk) 8th April 1996 */
25 /***************************************************************/
26 #include <cstdio>
27 #include "EST_unix.h"
28 #include <cstdlib>
29 #include <cstring>
30 #include "EST_String.h"
31 #include "EST_THash.h"
32 #include "EST_StringTrie.h"
33 #include "EST_cutils.h"
34 #include "EST_strcasecmp.h"
35 #include "siod.h"
36 #include "siodp.h"
37 #include "siodeditline.h"
38 
39 #ifdef EST_SIOD_ENABLE_PYTHON
40 #include "slib_python.h"
41 #endif
42 
43 extern "C" const char * repl_prompt;
44 
47 
48 #if defined(INSTANTIATE_TEMPLATES)
49 #include "../base_class/EST_THash.cc"
50 
51  Instantiate_TStringHash_T(EST_Regex *, hash_string_regex)
52 #endif
53 
54 using namespace std;
55 
56 static EST_TStringHash<EST_Regex *> regexes(100);
57 
59 {
60  /* Initialize siod */
61  int actual_heap_size;
62 
63  if (heap_size == -1) // unspecified by user
64  {
65  char *char_heap_size=getenv("SIODHEAPSIZE");
66  if ((char_heap_size == 0) ||
67  (atoi(char_heap_size) < 1000))
68  actual_heap_size=ACTUAL_DEFAULT_HEAP_SIZE;
69  else
70  actual_heap_size=atoi(char_heap_size);
71  }
72  else
73  actual_heap_size = heap_size;
74 
75  init_storage(actual_heap_size);
76  init_subrs();
77 
78  #ifdef EST_SIOD_ENABLE_PYTHON
79  init_subrs_python();
80  #endif
81 
82  return 0;
83 }
84 
86 {
87  #ifdef EST_SIOD_ENABLE_PYTHON
88  python_tidy_up();
89  #endif
90 
92 }
93 
94 LISP siod_get_lval(const char *name,const char *message)
95 {
96  // returns value of variable name. If not set gives an error
97  LISP iii, rval=NIL;
98 
99  iii = rintern(name);
100 
101  // value or NIL if unset
102  if (symbol_boundp(iii,current_env) == NIL)
103  {
104  if (message != NULL)
105  err(message,iii);
106  }
107  else
108  rval = symbol_value(iii, current_env);
109 
110  return rval;
111 }
112 
113 LISP siod_set_lval(const char *name,LISP val)
114 {
115  // set variable name to val
116  LISP iii, rval;
117 
118  iii = rintern(name);
119 
120  rval = setvar(iii,val,current_env);
121 
122  return rval;
123 }
124 
125 LISP siod_assoc_str(const char *key,LISP alist)
126 {
127  // assoc without going through LISP atoms
128  // made get_c_string inline for optimization
129  LISP l,lc,lcc;
130 
131  for (l=alist; CONSP(l); l=CDR(l))
132  {
133  lc = CAR(l);
134  if (CONSP(lc))
135  {
136  lcc = CAR(lc);
137  if (NULLP(lcc)) continue;
138  else if TYPEP(lcc,tc_symbol)
139  {
140  if (strcmp(key,PNAME(lcc))==0)
141  return lc;
142  }
143  else if TYPEP(lcc,tc_flonum)
144  {
145  if (FLONMPNAME(lcc) == NULL)
146  {
147  char b[TKBUFFERN];
148  sprintf(b,"%g",FLONM(lcc));
149  FLONMPNAME(lcc) = (char *)must_malloc(strlen(b)+1);
150  sprintf(FLONMPNAME(lcc),"%s",b);
151  }
152  if (strcmp(key,FLONMPNAME(lcc))==0)
153  return lc;
154  }
155  else if TYPEP(lcc,tc_string)
156  {
157  if (strcmp(key,lcc->storage_as.string.data)==0)
158  return lc;
159  }
160  else
161  continue;
162  }
163  }
164  return NIL;
165 }
166 
167 LISP siod_member_str(const char *key,LISP list)
168 {
169  // member without going through LISP atoms
170  LISP l;
171 
172  for (l=list; CONSP(l); l=CDR(l))
173  if (strcmp(key,get_c_string(CAR(l))) == 0)
174  return l;
175 
176  return NIL;
177 }
178 
179 LISP siod_regex_member_str(const EST_String &key,LISP list)
180 {
181  // Check the regexs in LIST against key
182  LISP l;
183 
184  for (l=list; CONSP(l); l=CDR(l))
185  if (key.matches(make_regex(get_c_string(CAR(l)))))
186  return l;
187 
188  return NIL;
189 }
190 
191 LISP siod_member_int(const int key,LISP list)
192 {
193  // member without going through LISP atoms
194  LISP l;
195 
196  for (l=list; CONSP(l); l=CDR(l))
197  if (key == get_c_int(CAR(l)))
198  return l;
199  return NIL;
200 }
201 
202 int siod_llength(LISP list)
203 {
204  // length of string;
205  int len;
206  LISP l;
207 
208  for (len=0,l=list; CONSP(l); l=CDR(l),len++);
209 
210  return len;
211 
212 }
213 
214 LISP siod_nth(int n,LISP list)
215 {
216  // nth member -- first member is 0;
217  int i;
218  LISP l;
219 
220  for (i=0,l=list; CONSP(l); l=CDR(l),i++)
221  if (i == n)
222  return car(l);
223 
224  return NIL;
225 
226 }
227 
228 int siod_atomic_list(LISP list)
229 {
230  // TRUE is list only contains atoms
231  LISP p;
232 
233  for (p=list; p != NIL; p=cdr(p))
234  if (CONSP(car(p)))
235  return FALSE;
236 
237  return TRUE;
238 }
239 
240 int siod_eof(LISP item)
241 {
242  // TRUE if item is what siod denotes as eof
243  if (CONSP(item) &&
244  (cdr(item) == NIL) &&
245  (SYMBOLP(car(item))) &&
246  (strcmp("eof",get_c_string(car(item))) == 0))
247  return TRUE;
248  else
249  return FALSE;
250 }
251 
252 LISP quote(LISP l)
253 {
254  // Add quote round a Lisp expression
255  return cons(rintern("quote"),cons(l,NIL));
256 }
257 
258 LISP siod_last(LISP list)
259 {
260  LISP l;
261 
262  if ((list == NIL) || (NCONSP(list)))
263  return NIL;
264  else
265  {
266  for (l=list; cdr(l) != NIL; l=cdr(l));
267  return l;
268  }
269 }
270 
271 int get_param_int(const char *name, LISP params, int defval)
272 {
273  // Look up name in params and return value if present or
274  // defval if not present
275  LISP pair;
276 
277  pair = siod_assoc_str(name,params);
278 
279  if (pair == NIL)
280  return defval;
281  else if FLONUMP(car(cdr(pair)))
282  return (int)FLONM(car(cdr(pair)));
283  else
284  {
285  cerr << "param " << name << " not of type int" << endl;
286  err("",NIL);
287  return -1;
288  }
289 
290 }
291 
292 float get_param_float(const char *name, LISP params, float defval)
293 {
294  // Look up name in params and return value if present or
295  // defval if not present
296  LISP pair;
297 
298  pair = siod_assoc_str(name,params);
299 
300  if (pair == NIL)
301  return defval;
302  else if (FLONUMP(car(cdr(pair))))
303  return (float)FLONM(car(cdr(pair)));
304  else
305  {
306  cerr << "param " << name << " not of type float" << endl;
307  err("",NIL);
308  return -1;
309  }
310 
311 }
312 
313 const char *get_param_str(const char *name, LISP params, const char *defval)
314 {
315  // Look up name in params and return value if present or
316  // defval if not present
317  LISP pair;
318 
319  pair = siod_assoc_str(name,params);
320 
321  if (pair == NIL)
322  return defval;
323  else
324  return get_c_string(car(cdr(pair)));
325 }
326 
327 LISP get_param_lisp(const char *name, LISP params, LISP defval)
328 {
329  // Look up name in params and return value if present or
330  // defval if not present
331  LISP pair;
332 
333  pair = siod_assoc_str(name,params);
334 
335  if (pair == NIL)
336  return defval;
337  else
338  return car(cdr(pair));
339 }
340 
341 LISP make_param_str(const char *name,const char *val)
342 {
343  return cons(rintern(name),cons(rintern(val),NIL));
344 }
345 
346 LISP make_param_int(const char *name, int val)
347 {
348  return cons(rintern(name),cons(flocons(val),NIL));
349 }
350 
351 LISP make_param_float(const char *name, float val)
352 {
353  return cons(rintern(name),cons(flocons(val),NIL));
354 }
355 
356 LISP make_param_lisp(const char *name,LISP val)
357 {
358  return cons(rintern(name),cons(val,NIL));
359 }
360 
361 EST_Regex &make_regex(const char *r)
362 {
363  // Return pointer to existing regex if its already been created
364  // otherwise create a new one for this r.
365  EST_Regex *rx;
366  EST_String sr = r;
367  int found;
368 
369  rx = regexes.val(sr,found);
370  if (!found)
371  {
372  rx = new EST_Regex(r);
373  regexes.add_item(sr,rx);
374  }
375 
376  return *rx;
377 }
378 
379 LISP apply_hooks(LISP hooks,LISP arg)
380 {
381  // Apply each function in hooks to arg returning value from
382  // final application (or arg itself)
383  LISP h,r;
384 
385  r = arg;
386 
387  if (hooks && (!CONSP(hooks))) // singleton
388  r = leval(cons(hooks,cons(quote(arg),NIL)),NIL);
389  else
390  for (h=hooks; h != NIL; h=cdr(h))
391  r = leval(cons(car(h),cons(quote(arg),NIL)),NIL);
392  return r;
393 }
394 
395 LISP apply_hooks_right(LISP hooks,LISP args)
396 {
397  // The above version neither quotes its arguments properly of deals
398  // with lists of arguments so here's a better one
399  // Apply each function in hooks to arg returning value from
400  // final application (or arg itself)
401  LISP h,r;
402 
403  if (hooks == NIL)
404  r = args;
405  else if (!CONSP(hooks)) // singleton
406  r = apply(hooks,args);
407  else
408  for (r=args,h=hooks; h != NIL; h=cdr(h))
409  r = apply(car(h),r);
410  return r;
411 }
412 
413 LISP apply(LISP func,LISP args)
414 {
415  LISP qa,a;
416 
417  for (qa=NIL,a=args; a; a=cdr(a))
418  qa = cons(quote(car(a)),qa);
419  return leval(cons(func,reverse(qa)),NIL);
420 }
421 
422 LISP stringexplode(const char *str)
423 {
424  // Explode character string into list of symbols one for each char
425  LISP l=NIL;
426  unsigned int i;
427  char id[2];
428  id[1] = '\0';
429 
430  for (i=0; i < strlen(str); i++)
431  {
432  id[0] = str[i];
433  l = cons(rintern(id),l);
434  }
435 
436  return reverse(l);
437 }
438 
439 /* Editline completion functions */
440 
441 char **siod_variable_generator(char *text,int length)
442 {
443  LISP l,lmatches;
444  const char *name;
445  char **matches = NULL;
446  int i;
447 
448  /* Return the next name which partially matches from the command list. */
449  for(lmatches=NIL,l=oblistvar;CONSP(l);l=CDR(l))
450  {
451  if (VCELL(car(l)) == NIL) continue;
452  switch(TYPE(VCELL(CAR(l))))
453  {
454  case tc_subr_0:
455  case tc_subr_1:
456  case tc_subr_2:
457  case tc_subr_3:
458  case tc_subr_4:
459  case tc_lsubr:
460  case tc_fsubr:
461  case tc_msubr:
462  case tc_closure:
463  continue;
464  default:
465  /* only return names of nonfunctions (sometimes too restrictive) */
466  name = PNAME(CAR(l));
467  if (strncmp(name, text, length) == 0)
468  lmatches = cons(CAR(l),lmatches);
469  }
470  }
471 
472  /* Need to return the matches in a char** */
473  matches = walloc(char *,siod_llength(lmatches)+1);
474  for (l=lmatches,i=0; l; l=cdr(l),i++)
475  matches[i] = wstrdup(PNAME(car(l)));
476  matches[i] = NULL;
477 
478  return matches;
479 }
480 
481 char **siod_command_generator (char *text,int length)
482 {
483  LISP l,lmatches;
484  const char *name;
485  char **matches = NULL;
486  int i;
487 
488  /* Return the next name which partially matches from the command list. */
489  for(lmatches=NIL,l=oblistvar;CONSP(l);l=CDR(l))
490  {
491  if (VCELL(car(l)) == NIL) continue;
492  switch(TYPE(VCELL(CAR(l))))
493  {
494  case tc_subr_0:
495  case tc_subr_1:
496  case tc_subr_2:
497  case tc_subr_3:
498  case tc_subr_4:
499  case tc_lsubr:
500  case tc_fsubr:
501  case tc_msubr:
502  case tc_closure:
503  /* only return names of functions */
504  name = PNAME(CAR(l));
505  if (strncmp(name, text, length) == 0)
506  lmatches = cons(CAR(l),lmatches);
507  default: continue;
508  }
509  }
510 
511  /* Need to return the matches in a char** */
512  matches = walloc(char *,siod_llength(lmatches)+1);
513  for (l=lmatches,i=0; l; l=cdr(l),i++)
514  matches[i] = wstrdup(PNAME(car(l)));
515  matches[i] = NULL;
516 
517  return matches;
518 }
519 
521 {
522  // copy l into a
523  LISP b;
524 
525  a.clear();
526 
527  for (b=l; b != NIL; b=cdr(b))
528  a.append(get_c_string(car(b)));
529 
530 }
531 
533 {
534  // copy a into l
535  LISP b=NIL;;
536  EST_Litem *p;
537 
538  for (p=a.head(); p != 0; p=p->next())
539  b = cons(rintern(a(p)),b);
540 
541  return reverse(b);
542 }
543 
LISP siod_nth(int n, LISP list)
Definition: siod.cc:214
char * wstrdup(const char *s)
Definition: walloc.c:117
#define tc_fsubr
Definition: siod_defs.h:112
#define walloc(TYPE, SIZE)
Definition: EST_walloc.h:52
LISP siod_strlist_to_list(EST_StrList &a)
Definition: siod.cc:532
LISP stringexplode(const char *str)
Definition: siod.cc:422
const char * get_param_str(const char *name, LISP params, const char *defval)
Definition: siod.cc:313
int get_param_int(const char *name, LISP params, int defval)
Definition: siod.cc:271
#define tc_symbol
Definition: siod_defs.h:106
#define NULLP(x)
Definition: siod_defs.h:95
char ** siod_command_generator(char *text, int length)
Definition: siod.cc:481
int siod_llength(LISP list)
Definition: siod.cc:202
long heap_size
Definition: slib.cc:116
A Regular expression class to go with the CSTR EST_String class.
Definition: EST_Regex.h:56
long int get_c_int(LISP x)
Definition: slib.cc:1850
#define NIL
Definition: siod_defs.h:92
#define TKBUFFERN
Definition: siodp.h:97
LISP siod_get_lval(const char *name, const char *message)
Definition: siod.cc:94
#define SYMBOLP(x)
Definition: siod_defs.h:155
A specialised hash table for when the key is an EST_String.
Definition: EST_THash.h:304
#define ACTUAL_DEFAULT_HEAP_SIZE
Definition: siod_defs.h:30
char * getenv()
#define tc_flonum
Definition: siod_defs.h:105
LISP make_param_float(const char *name, float val)
Definition: siod.cc:351
#define TYPE(x)
Definition: siod_defs.h:98
EST_UItem * next()
Definition: EST_UList.h:55
#define VCELL(x)
Definition: siod_defs.h:79
float get_param_float(const char *name, LISP params, float defval)
Definition: siod.cc:292
#define PNAME(x)
Definition: siod_defs.h:78
void err(const char *message, LISP x) EST_NORETURN
Definition: slib.cc:608
LISP get_param_lisp(const char *name, LISP params, LISP defval)
Definition: siod.cc:327
LISP symbol_boundp(LISP x, LISP env)
Definition: slib_core.cc:222
const char * get_c_string(LISP x)
Definition: slib.cc:638
int siod_init(int heap_size)
Definition: siod.cc:58
#define tc_lsubr
Definition: siod_defs.h:111
LISP quote(LISP l)
Definition: siod.cc:252
LISP siod_regex_member_str(const EST_String &key, LISP list)
Definition: siod.cc:179
#define tc_msubr
Definition: siod_defs.h:113
LISP apply(LISP func, LISP args)
Definition: siod.cc:413
#define NCONSP(x)
Definition: siod_defs.h:158
LISP cons(LISP x, LISP y)
Definition: slib_list.cc:97
LISP setvar(LISP var, LISP val, LISP env)
Definition: slib_core.cc:18
LISP make_param_int(const char *name, int val)
Definition: siod.cc:346
LISP current_env
Definition: slib.cc:132
void init_storage(int init_heap_size)
Definition: slib.cc:880
LISP siod_last(LISP list)
Definition: siod.cc:258
#define Instantiate_TStringHash_T(VAL, TAG)
LISP siod_member_int(const int key, LISP list)
Definition: siod.cc:191
const char * repl_prompt
Definition: siod.cc:43
#define FLONUMP(x)
Definition: siod_defs.h:154
#define FALSE
Definition: EST_bool.h:119
#define tc_subr_0
Definition: siod_defs.h:107
NULL
Definition: EST_WFST.cc:55
LISP siod_member_str(const char *key, LISP list)
Definition: siod.cc:167
LISP siod_assoc_str(const char *key, LISP alist)
Definition: siod.cc:125
#define tc_subr_3
Definition: siod_defs.h:110
int matches(const char *e, ssize_t pos=0) const
Exactly match this string?
Definition: EST_String.cc:651
#define tc_closure
Definition: siod_defs.h:114
LISP symbol_value(LISP x, LISP env)
Definition: slib_core.cc:229
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:196
#define TYPEP(x, y)
Definition: siod_defs.h:100
LISP apply_hooks_right(LISP hooks, LISP args)
Definition: siod.cc:395
#define CAR(x)
Definition: siod_defs.h:76
#define tc_string
Definition: siod_defs.h:116
int siod_eof(LISP item)
Definition: siod.cc:240
LISP rintern(const char *name)
Definition: slib.cc:734
#define tc_subr_2
Definition: siod_defs.h:109
LISP oblistvar
Definition: slib.cc:131
LISP leval(LISP x, LISP env)
Definition: slib.cc:1378
EST_Regex & make_regex(const char *r)
Definition: siod.cc:361
#define tc_subr_4
Definition: siod_defs.h:122
char * must_malloc(unsigned long size)
Definition: slib.cc:693
void siod_tidy_up()
Definition: siod.cc:85
LISP make_param_lisp(const char *name, LISP val)
Definition: siod.cc:356
LISP apply_hooks(LISP hooks, LISP arg)
Definition: siod.cc:379
An open hash table. The number of buckets should be set to allow enough space that there are relative...
Definition: EST_THash.h:69
LISP flocons(double x)
Definition: slib.cc:673
#define tc_subr_1
Definition: siod_defs.h:108
EST_UItem * head() const
Definition: EST_UList.h:97
LISP car(LISP x)
Definition: slib_list.cc:115
LISP make_param_str(const char *name, const char *val)
Definition: siod.cc:341
#define FLONMPNAME(x)
Definition: siod_defs.h:88
#define TRUE
Definition: EST_bool.h:118
void reverse(EST_Wave &sig)
#define CONSP(x)
Definition: siod_defs.h:153
void siod_list_to_strlist(LISP l, EST_StrList &a)
Definition: siod.cc:520
char ** siod_variable_generator(char *text, int length)
Definition: siod.cc:441
void clear(void)
remove all items in list
Definition: EST_TList.h:244
void init_subrs(void)
Definition: slib.cc:1922
LISP cdr(LISP x)
Definition: slib_list.cc:124
void close_open_files(void)
Definition: slib_file.cc:610
#define CDR(x)
Definition: siod_defs.h:77
LISP siod_set_lval(const char *name, LISP val)
Definition: siod.cc:113
#define FLONM(x)
Definition: siod_defs.h:87
int siod_atomic_list(LISP list)
Definition: siod.cc:228