Edinburgh Speech Tools  2.1-release
genxml.cc
Go to the documentation of this file.
1  /************************************************************************/
2  /* */
3  /* Centre for Speech Technology Research */
4  /* University of Edinburgh, UK */
5  /* Copyright (c) 1996,1997 */
6  /* All Rights Reserved. */
7  /* */
8  /* Permission is hereby granted, free of charge, to use and distribute */
9  /* this software and its documentation without restriction, including */
10  /* without limitation the rights to use, copy, modify, merge, publish, */
11  /* distribute, sublicense, and/or sell copies of this work, and to */
12  /* permit persons to whom this work is furnished to do so, subject to */
13  /* the following conditions: */
14  /* 1. The code must retain the above copyright notice, this list of */
15  /* conditions and the following disclaimer. */
16  /* 2. Any modifications must be clearly marked as such. */
17  /* 3. Original authors' names are not deleted. */
18  /* 4. The authors' names are not used to endorse or promote products */
19  /* derived from this software without specific prior written */
20  /* permission. */
21  /* */
22  /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23  /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24  /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25  /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26  /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27  /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28  /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29  /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30  /* THIS SOFTWARE. */
31  /* */
32  /*************************************************************************/
33  /* */
34  /* Author: Richard Caley (rjc@cstr.ed.ac.uk) */
35  /* -------------------------------------------------------------------- */
36  /* Code to read utterances marked up in XML according to a DTD with */
37  /* certain conventions indicating the mapping from XML to Utterance. */
38  /* */
39  /*************************************************************************/
40 
41 #include <cstdlib>
42 #include <cstdio>
43 #include <cctype>
44 #include "EST_TDeque.h"
45 #include "EST_THash.h"
46 #include "EST_error.h"
47 #include "genxml.h"
48 #include "rxp/XML_Parser.h"
49 
50 #include "ling_class_init.h"
51 
52 using namespace std;
53 
54 #if defined(ESTLIBDIRC)
55 # define __STRINGIZE(X) #X
56 # define ESTLIBDIR __STRINGIZE(ESTLIBDIRC)
57 #endif
58 
59 
60 static EST_Regex simpleIDRegex("[^#]*#id(\\([-a-z0-9]+\\))");
61 static EST_Regex rangeIDRegex("[^#]*#id(\\([a-z]*\\)\\([0-9]*\\)\\(-\\([0-9]+\\)\\)*).*id(\\([a-z]*\\)\\([0-9]*\\)\\(-\\([0-9]+\\)\\)*)");
62 static EST_Regex featureDefRegex("\\([^:]*\\):\\(.*\\)");
63 
64 // Separator between feature names in attributes.
65 
66 static EST_String feat_sep(",");
67 
68 // I'd like to get rid of this. It is a maximum for the number of features
69 // which can be named in an attribute, say for copying to the utterance.
70 
71 #define MAX_FEATS (50)
72 
73 // Parse state.
74 
75 class GenXML_Parse_State
76  {
77 public:
78  int depth;
79  int open_depth;
80  int rel_start_depth;
81  EST_TDeque<int> depth_stack;
82  EST_String relName;
83  bool linear;
84  EST_Utterance *utt;
85  EST_Relation *rel;
87  EST_Item *current;
88  EST_String contentAttr;
89 
90  // used to force a given ID on a node.
91  EST_String id;
92 
94 
95 
96  GenXML_Parse_State() : contents(100) {
97  depth = 0;
98  open_depth = 0;
99  rel_start_depth = 0;
100  linear = false;
101  utt = 0;
102  rel = 0;
103  parent = 0;
104  current = 0;
105  }
106  };
107 
108 class GenXML_Parser_Class : public XML_Parser_Class
109 {
110 protected:
111  virtual void document_open(XML_Parser_Class &c,
112  XML_Parser &p,
113  void *data);
114  virtual void document_close(XML_Parser_Class &c,
115  XML_Parser &p,
116  void *data);
117 
118  virtual void element_open(XML_Parser_Class &c,
119  XML_Parser &p,
120  void *data,
121  const char *name,
122  XML_Attribute_List &attributes);
123  virtual void element(XML_Parser_Class &c,
124  XML_Parser &p,
125  void *data,
126  const char *name,
127  XML_Attribute_List &attributes);
128  virtual void element_close(XML_Parser_Class &c,
129  XML_Parser &p,
130  void *data,
131  const char *name);
132 
133  virtual void pcdata(XML_Parser_Class &c,
134  XML_Parser &p,
135  void *data,
136  const char *chars);
137  virtual void cdata(XML_Parser_Class &c,
138  XML_Parser &p,
139  void *data,
140  const char *chars);
141 
142  virtual void processing(XML_Parser_Class &c,
143  XML_Parser &p,
144  void *data,
145  const char *instruction);
146  virtual void error(XML_Parser_Class &c,
147  XML_Parser &p,
148  void *data);
149 };
150 
151 static void print_attributes(XML_Attribute_List &attributes);
152 
153 XML_Parser_Class *EST_GenXML::pclass;
154 
155 
157 {
159 
160  pclass = new GenXML_Parser_Class();
161 #ifdef DEBUGGING
162  printf("Register estlib in genxml %s\n", ESTLIBDIR "/\\1.dtd");
163 #endif
164 
165  pclass->register_id("//CSTR EST//DTD \\(.*\\)//[A-Z]*",
166  ESTLIBDIR "/\\1.dtd");
167  pclass->register_id("//CSTR EST//ENTITIES \\(.*\\)//[A-Z]*",
168  ESTLIBDIR "/\\1.ent");
169 }
170 
172  const EST_String result)
173 {
174  EST_GenXML::pclass->register_id(pattern, result);
175 }
176 
178 {
179  EST_GenXML::pclass->registered_ids(list);
180 }
181 
182 InputSource EST_GenXML::try_and_open(Entity ent)
183 {
184  return EST_GenXML::pclass->try_and_open(ent);
185 }
186 
187 
189  const EST_String &name,
190  EST_Utterance &u,
191  int &max_id)
192 {
193  (void)max_id;
194  (void)print_attributes; // just to shut -Wall up.
195  GenXML_Parse_State state;
196 
197  u.clear();
198 
199  state.utt=&u;
200 
201  XML_Parser *parser = EST_GenXML::pclass->make_parser(file, name, &state);
202  parser->track_context(TRUE);
203 
204  CATCH_ERRORS()
205  return read_format_error;
206 
207  parser->go();
208 
210 
211  return read_ok;
212 }
213 
214 static void ensure_relation(GenXML_Parse_State *state, EST_String name)
215 {
216  if (state->rel!=NULL && name == state->relName)
217  return;
218 
219  state->rel = state->utt->create_relation(state->relName=name);
220 }
221 
222 static EST_Item_Content *get_contents(GenXML_Parse_State *state, EST_String id)
223 {
224  EST_Item_Content *c = state->contents.val(id);
225 
226  if (c==NULL)
227  {
228  c = new EST_Item_Content();
229  state->contents.add_item(id, c);
230  c->f.set("id", id);
231  }
232  else
233  {
234  if (c->relations.present(state->relName))
235  return NULL;
236  }
237 
238  return c;
239 }
240 
241 static EST_String make_new_id(const char *root)
242 {
243  char buf[100];
244  static int count=0;
245 
246  sprintf(buf, "%s%d", root, ++count);
247  return buf;
248 }
249 
250 
251 static void extract_ids(XML_Attribute_List &attributes,
253 {
254  EST_String val;
255  if (attributes.present("id"))
256  {
257  val = attributes.val("id");
258 #if defined(EST_DEBUGGING)
259  fprintf(stderr, "ID %s\n", (const char *)val);
260 #endif
261  ids.append(val);
262  }
263  else if (attributes.present("href"))
264  {
265  val = attributes.val("href");
266  size_t starts[EST_Regex_max_subexpressions];
267  size_t ends[EST_Regex_max_subexpressions];
268 
269  if (val.matches(simpleIDRegex, 0, starts, ends))
270  {
271  EST_String n = val.at(starts[1], ends[1]-starts[1]);
272 #if defined(EST_DEBUGGING)
273  fprintf(stderr, "SIMPLE %s\n", (const char *)n);
274 #endif
275  ids.append(n);
276  }
277  else if (val.matches(rangeIDRegex, 0, starts, ends))
278  {
279  EST_String prefix1 = val.at(starts[1], ends[1]-starts[1]);
280  int n1 = atoi(val.at(starts[2], ends[2]-starts[2]));
281  EST_String postfix1 = val.at(starts[4], ends[4]-starts[4]);
282  EST_String prefix2 = val.at(starts[5], ends[5]-starts[5]);
283  int n2 = atoi(val.at(starts[6], ends[6]-starts[6]));
284  EST_String postfix2 = val.at(starts[8], ends[8]-starts[8]);
285 
286 #if defined(EST_DEBUGGING)
287  fprintf(stderr, "RANGE '%s' %d - '%s' // '%s' %d - '%s'\n",
288  (const char *)prefix1,
289  n1,
290  (const char *)postfix1,
291  (const char *)prefix2,
292  n2,
293  (const char *)postfix2
294  );
295 #endif
296 
297  if (prefix1==prefix2)
298  prefix2="";
299 
300  char buf[100];
301  if (n1==n2)
302  {
303  int c;
304  if (postfix1.length()==0)
305  {
306  sprintf(buf, "%s%s%d",
307  (const char *)prefix1,
308  (const char *)prefix2,
309  n1
310  );
311  ids.append(buf);
312  c=1;
313  }
314  else
315  c=atoi(postfix1);
316 
317  if (postfix2.length()>0)
318  for (; c<=atoi(postfix2); c++)
319  {
320  sprintf(buf, "%s%s%d-%d",
321  (const char *)prefix1,
322  (const char *)prefix2,
323  n1,
324  c
325  );
326  ids.append(buf);
327  }
328  }
329  else
330  {
331  for(int i=n1; i<=n2; i++)
332  {
333  if (i==n2
334  && postfix2.length()>0)
335  {
336  sprintf(buf, "%s%s%d",
337  (const char *)prefix1,
338  (const char *)prefix2,
339  i
340  );
341  ids.append(buf);
342  for (int c=1; c<=atoi(postfix2); c++)
343  {
344  sprintf(buf, "%s%s%d-%d",
345  (const char *)prefix1,
346  (const char *)prefix2,
347  i,
348  c
349  );
350  ids.append(buf);
351  }
352  }
353  else
354  {
355  if ( postfix1.length()>0)
356  sprintf(buf, "%s%s%d-%s",
357  (const char *)prefix1,
358  (const char *)prefix2,
359  i,
360  (const char *)postfix1
361  );
362  else
363  sprintf(buf, "%s%s%d",
364  (const char *)prefix1,
365  (const char *)prefix2,
366  i
367  );
368 
369  ids.append(buf);
370  }
371  postfix1="";
372  }
373 
374  }
375  }
376  else
377  EST_warning("element with bad ID or HREF '%s'", (const char *)val);
378  }
379  else
380  ids.append(make_new_id("n"));
381 
382  // cout << ids << "\n";
383 }
384 
385 /* For debugging.
386  */
387 static void print_attributes(XML_Attribute_List &attributes)
388 {
390 
391  for(them.begin(attributes); them ; them++)
392  printf(" %s='%s'",
393  (const char *)them->k,
394  (const char *)them->v);
395 }
396 
397 /** Now we define the callbacks.
398  */
399 
400 void GenXML_Parser_Class::document_open(XML_Parser_Class &c,
401  XML_Parser &p,
402  void *data)
403 {
404  (void)c; (void)p;
405  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
406 
407  state->depth=1;
408  state->open_depth=-1;
409  state->rel_start_depth=-1;
410  state->depth_stack.clear();
411  state->rel=NULL;
412  state->parent=NULL;
413  state->current=NULL;
414  state->id="";
415 }
416 
417 void GenXML_Parser_Class::document_close(XML_Parser_Class &c,
418  XML_Parser &p,
419  void *data)
420 {
421  (void)c; (void)p; (void)data;
422 }
423 
424 static void proccess_features(EST_String name,
425  EST_String defs,
426  XML_Attribute_List &attributes,
427  EST_Features &f)
428 {
429  EST_String names[MAX_FEATS];
430  size_t starts[EST_Regex_max_subexpressions];
431  size_t ends[EST_Regex_max_subexpressions];
432 
433  size_t n = split(defs, names, MAX_FEATS, feat_sep);
434  for(size_t i=0; i<n; i++)
435  {
436  EST_String def = names[i];
437  EST_String feat;
438  EST_String attr;
439 
440  if (def.matches(featureDefRegex, 0, starts, ends))
441  {
442  feat = def.at(starts[1], ends[1]-starts[1]);
443  attr = def.at(starts[2], ends[2]-starts[2]);
444  }
445  else
446  {
447  attr=def;
448  feat=EST_String::cat(name, "_", attr);
449  }
450 
451  EST_String fval = attributes.val(attr);
452 
453 #ifdef DEBUGGING
454  printf("on %s got %s(%s)=%s\n", name,
455  (const char *)feat,
456  (const char *)attr,
457  (const char *)fval);
458 #endif
459  if (fval != EST_String::Empty)
460  f.set(feat, fval);
461  }
462 }
463 
464 void GenXML_Parser_Class::element_open(XML_Parser_Class &c,
465  XML_Parser &p,
466  void *data,
467  const char *name,
468  XML_Attribute_List &attributes)
469 {
470  (void)c; (void)p; (void)attributes; (void)name;
471  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
472 
473  state->depth++;
474 
475  EST_String val, ig;
476 
477  // Features to copy to utterance
478  if (state->utt != NULL
479  && (val=attributes.val("estUttFeats")) != EST_String::Empty)
480  proccess_features(name, val, attributes, state->utt->f);
481 
482  // Features to copy to relation
483  if (state->rel != NULL
484  && (val=attributes.val("estRelFeats")) != EST_String::Empty)
485  proccess_features(name, val, attributes, state->rel->f);
486 
487 
488  if ((val=attributes.val("estRelationElementAttr")) != EST_String::Empty)
489  {
490  // All nodes inside this element are in the given relation
491  EST_String relName = attributes.val(val);
492 
493  if (relName == EST_String::Empty)
494  {
495  relName = "UNNAMED";
496  EST_warning("%s\nNo feature '%s' to name relation\n", get_error(p), (const char *)val);
497  }
498 
499  EST_String relationType = attributes.val("estRelationTypeAttr");
500 
501  ensure_relation(state, relName);
502  state->rel_start_depth=state->depth;
503  state->linear=(attributes.val(relationType) == "linear"||
504  attributes.val(relationType) == "list");
505 #ifdef DEBUGGING
506  printf("start of relation depth=%d name=%s type=%s\n", state->depth, (const char *)relName, state->linear?"linear":"tree");
507 #endif
508  }
509  else if ((state->rel_start_depth >= 0 &&
510  (ig=attributes.val("estRelationIgnore")) == EST_String::Empty)
511  || (val=attributes.val("estRelationNode")) != EST_String::Empty)
512  {
513  // This node defines an Item in a relation.
514 #ifdef DEBUGGING
515  printf("push depth=%d name=%s ig=%s\n", state->depth, name, (const char *)ig);
516 #endif
517  if (val != EST_String::Empty)
518  ensure_relation(state, val);
519 
520  state->depth_stack.push(state->open_depth);
521  state->open_depth=state->depth;
522 
524 
525  if (state->id == EST_String::Empty)
526  {
527  extract_ids(attributes, ids);
528  }
529  else
530  ids.append(state->id);
531 
532  switch (ids.length())
533  {
534  case 0:
535  XML_Parser_Class::error(c, p, data, EST_String("Element With No Id"));
536  break;
537  case 1:
538  {
539  EST_String id = ids.first();
540 
541  if (id==EST_String::Empty)
542  XML_Parser_Class::error(c, p, data, EST_String("Element With No Id"));
543 
544  EST_Item_Content *cont = get_contents(state, id);
545 
546  if (!cont)
547  XML_Parser_Class::error(c, p, data, EST_String("Repeated Id ") + id);
548 
550  for(them.begin(attributes); them ; them++)
551  {
552  EST_String k = them->k;
553  EST_String v = them->v;
554  cont->f.set(k,v);
555  }
556 
557  cont->f.set("id", id);
558 
559  EST_Item *item;
560 
561  if (state->linear)
562  if (state->current == NULL)
563  item = state->rel->append();
564  else
565  item = state->current->insert_after();
566  else if (state->current == NULL)
567  if (state->parent == NULL)
568  item = state->rel->append();
569  else
570  item = state->parent->append_daughter();
571  else
572  if (state->parent == NULL)
573  item = state->current->insert_after();
574  else
575  item = state->parent->append_daughter();
576 
577  item->set_contents(cont);
578 
579  state->current=NULL;
580  state->parent=item;
581  }
582  break;
583 
584  default:
585  {
586  bool embed = (attributes.val("estExpansion") == "embed");
587  if (embed)
588  {
589  state->id=make_new_id("e");
590  element_open(c, p, data, name, attributes);
591  state->id="";
592  }
593  EST_Litem *idp = ids.head();
594  bool first=TRUE;
595  for(; idp!= NULL; idp = idp->next())
596  {
597  EST_String id = ids(idp);
598  if (id==EST_String::Empty)
599  XML_Parser_Class::error(c, p, data, EST_String("Element With No Id"));
600 
601  if (!first)
602  element_close(c, p, data, name);
603  else
604  first=FALSE;
605 
606  state->id=id;
607  element_open(c, p, data, name, attributes);
608  state->id=EST_String::Empty;
609  }
610  if (embed)
611  {
612  element_close(c, p, data, name);
613  }
614  }
615  }
616 
617 
618  if (state->parent!=NULL)
619  state->contentAttr = attributes.val("estContentFeature");
620 
621 #ifdef DEBUGGING
622  printf("\t current=%s parent=%s contA=%s\n",
623  (const char *)state->current->name(),
624  (const char *)state->parent->name(),
625  (const char *)state->contentAttr);
626 #endif
627 
628  }
629  else {}
630  ; // Skip
631 
632 }
633 
634 
635 void GenXML_Parser_Class::element(XML_Parser_Class &c,
636  XML_Parser &p,
637  void *data,
638  const char *name,
639  XML_Attribute_List &attributes)
640 {
641  (void)c; (void)p; (void)attributes;
642  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
643  (void)state;
644 
645  element_open(c, p, data, name, attributes);
646  element_close(c, p, data, name);
647 }
648 
649 
650 void GenXML_Parser_Class::element_close(XML_Parser_Class &c,
651  XML_Parser &p,
652  void *data,
653  const char *name)
654 {
655  (void)c; (void)p; (void)name;
656  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
657 
658  EST_String val;
659 
660 
661  if (state->depth == state->rel_start_depth )
662  {
663 #ifdef DEBUGGING
664  printf("end of relation depth=%d name=%s\n", state->depth, name);
665 #endif
666  state->rel_start_depth=-1;
667  }
668 
669  if (
670  state->depth == state->open_depth)
671  {
672 #ifdef DEBUGGING
673  printf("pop depth=%d name=%s\n", state->depth, name);
674 #endif
675  state->current = state->parent;
676  state->parent=parent(state->parent);
677  state->open_depth = state->depth_stack.pop();
678 #ifdef DEBUGGING
679  printf("\t current=%s parent=%s\n",
680  (const char *)state->current->name(),
681  (const char *)state->parent->name());
682 #endif
683  }
684 
685 
686  state->depth--;
687 }
688 
689 
690 void GenXML_Parser_Class::pcdata(XML_Parser_Class &c,
691  XML_Parser &p,
692  void *data,
693  const char *chars)
694 {
695  (void)c;
696  (void)p;
697  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
698 
699 
700  if ( state->parent != NULL && state->contentAttr != EST_String::Empty)
701  state->parent->set(state->contentAttr, chars);
702 
703 #ifdef DEBUGGING
704  printf("GEN XML Parser [pcdata[%s]] %d\n", chars, state->depth);
705 #endif
706 }
707 
708 
709 void GenXML_Parser_Class::cdata(XML_Parser_Class &c,
710  XML_Parser &p,
711  void *data,
712  const char *chars)
713 {
714  (void)c; (void)p; (void)data; (void)chars;
715  // GenXML_Parse_State *state = (GenXML_Parse_State *)data;
716 
717 #ifdef DEBUGGING
718  printf("GEN XML Parser [cdata[%s]] %d\n", chars, state->depth);
719 #endif
720 }
721 
722 
723 void GenXML_Parser_Class::processing(XML_Parser_Class &c,
724  XML_Parser &p,
725  void *data,
726  const char *instruction)
727 {
728  (void)c; (void)p; (void)instruction;
729  GenXML_Parse_State *state = (GenXML_Parse_State *)data;
730  (void)state;
731 
732 #ifdef DEBUGGING
733  printf("GEN XML Parser [proc[%s]] %d\n", instruction, state->depth);
734 #endif
735 }
736 
737 
739  XML_Parser &p,
740  void *data)
741 {
742  (void)c; (void)p; (void)data;
743  // GenXML_Parse_State *state = (GenXML_Parse_State *)data;
744 
745  EST_error("GEN XML Parser %s", get_error(p));
746 
747  est_error_throw();
748 }
749 
752 
753 #if defined(INSTANTIATE_TEMPLATES)
754 
755 #include "../base_class/EST_THash.cc"
756 
757 Instantiate_TStringHash_T(EST_Item_Content *, THash_String_ItemC_P)
758 
759 #endif
static void use(void)
static void registered_ids(EST_StrList &list)
Definition: genxml.cc:177
void set_contents(EST_Item_Content *li)
Definition: EST_Item.cc:202
#define END_CATCH_ERRORS()
Definition: EST_error.h:144
static EST_read_status read_xml(FILE *file, const EST_String &name, EST_Utterance &u, int &max_id)
Definition: genxml.cc:188
void clear()
remove everything in utterance
The file was read in successfully.
A Regular expression class to go with the CSTR EST_String class.
Definition: EST_Regex.h:56
#define EST_Regex_max_subexpressions
Definition: EST_Regex.h:150
void registered_ids(EST_TList< EST_String > &list)
Definition: XML_Parser.cc:53
void set(const EST_String &name, int ival)
Definition: EST_Features.h:186
EST_Item * root(const EST_Item *n)
return root node of treeprevious sibling (sister) of n
EST_UItem * next()
Definition: EST_UList.h:55
EST_Track error(EST_Track &ref, EST_Track &test, int relax=0)
EST_Features f
General features for this item.
#define ESTLIBDIR
Definition: EST_cutils.c:59
void register_id(EST_Regex id_pattern, EST_String directory)
Definition: XML_Parser.cc:48
static EST_String cat(const EST_String s1, const EST_String s2=Empty, const EST_String s3=Empty, const EST_String s4=Empty, const EST_String s5=Empty, const EST_String s6=Empty, const EST_String s7=Empty, const EST_String s8=Empty, const EST_String s9=Empty)
Definition: EST_String.cc:1084
void go()
Run the parser.
Definition: XML_Parser.cc:282
InputSource try_and_open(Entity ent)
Definition: XML_Parser.cc:130
EST_TKVL< EST_String, EST_Val > relations
#define est_error_throw()
Definition: EST_error.h:112
V & val(const K &key, int &found) const
Definition: EST_THash.cc:114
int present(const K &key) const
Does the key have an entry?
Definition: EST_THash.cc:96
#define Instantiate_TStringHash_T(VAL, TAG)
void track_context(bool flag)
Definition: XML_Parser.cc:391
#define FALSE
Definition: EST_bool.h:119
#define CATCH_ERRORS()
Definition: EST_error.h:126
static InputSource try_and_open(Entity ent)
Definition: genxml.cc:182
The file exists but is not in the format specified.
NULL
Definition: EST_WFST.cc:55
#define EST_error
Definition: EST_error.h:104
const T & first() const
return const reference to first item in list
Definition: EST_TList.h:152
f
Definition: EST_item_aux.cc:48
#define MAX_FEATS
Definition: genxml.cc:71
static void register_id(const EST_String pattern, const EST_String result)
Definition: genxml.cc:171
int matches(const char *e, ssize_t pos=0) const
Exactly match this string?
Definition: EST_String.cc:651
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:196
XML_Parser * make_parser(InputSource source, void *data)
Create a parser for the RXP InputSource.
Definition: XML_Parser.cc:72
int length() const
Definition: EST_UList.cc:57
EST_read_status
void begin(const Container &over)
Set the iterator ready to run over this container.
#define EST_warning
Definition: EST_error.h:106
int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
An open hash table. The number of buckets should be set to allow enough space that there are relative...
Definition: EST_THash.h:69
EST_UItem * head() const
Definition: EST_UList.h:97
virtual void error(XML_Parser_Class &c, XML_Parser &p, void *data)
Definition: XML_Parser.cc:225
EST_String
EST_String at(int from, int len=0) const
Return part at position.
Definition: EST_String.h:292
#define TRUE
Definition: EST_bool.h:118
EST_Item * parent(const EST_Item *n)
return parent of n
static const EST_String Empty
Constant empty string.
Definition: EST_String.h:110
static void class_init(void)
Definition: genxml.cc:156