exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
treeTableBuild.c
Go to the documentation of this file.
1 /*==================================================================*\
2 | EXIP - Embeddable EXI Processor in C |
3 |--------------------------------------------------------------------|
4 | This work is licensed under BSD 3-Clause License |
5 | The full license terms and conditions are located in LICENSE.txt |
6 \===================================================================*/
7 
18 #include "treeTableSchema.h"
19 #include "dynamicArray.h"
20 #include "EXIParser.h"
21 #include "genUtils.h"
22 #include "stringManipulate.h"
23 #include "memManagement.h"
24 #include "grammars.h"
25 #include "initSchemaInstance.h"
26 #include "grammarGenerator.h"
27 
28 #define INITIAL_STATE 0
29 #define SCHEMA_ELEMENT_STATE 1
30 #define SCHEMA_CONTENT_STATE 2
31 
32 extern const String XML_SCHEMA_NAMESPACE;
33 
34 #ifdef GRAMMAR_GEN_SCHEMA
35  // INCLUDE_SCHEMA_EXI_GRAMMAR_GENERATION in build-params is true
36  // Enables parsing of EXI encoded XMLSchema files in EXI schema-mode
37 
39 #endif
40 
45 {
52  unsigned char propsStat;
53  boolean expectingAttr;
61  unsigned int ignoredElement;
72 };
73 
74 
75 // Content Handler API
76 static errorCode xsd_fatalError(const errorCode code, const char* msg, void* app_data);
77 static errorCode xsd_startDocument(void* app_data);
78 static errorCode xsd_endDocument(void* app_data);
79 static errorCode xsd_startElement(QName qname, void* app_data);
80 static errorCode xsd_endElement(void* app_data);
81 static errorCode xsd_attribute(QName qname, void* app_data);
82 static errorCode xsd_stringData(const String value, void* app_data);
83 static errorCode xsd_namespaceDeclaration(const String ns, const String prefix, boolean isLocalElementNS, void* app_data);
84 static errorCode xsd_boolData(boolean bool_val, void* app_data);
85 static errorCode xsd_intData(Integer int_val, void* app_data);
86 
88 
89 static void initEntryContext(TreeTableEntry* entry);
90 
92 
93 static const char* elemStrings[] =
94 {
95  "element",
96  "attribute",
97  "choice",
98  "complexType",
99  "complexContent",
100  "group",
101  "import",
102  "sequence",
103  "all",
104  "extension",
105  "restriction",
106  "simpleContent",
107  "any",
108  "simpleType",
109  "minInclusive",
110  "annotation",
111  "documentation",
112  "maxLength",
113  "maxInclusive",
114  "list",
115  "union",
116  "attributeGroup",
117  "anyAttribute",
118  "enumeration",
119  "key",
120  "selector",
121  "field",
122  "notation",
123  "include",
124  "redefine",
125  "minExclusive",
126  "maxExclusive",
127  "totalDigits",
128  "fractionDigits",
129  "length",
130  "minLength",
131  "whiteSpace",
132  "pattern",
133  "appinfo"
134 };
135 
136 static const char* attrStrings[] =
137 {
138  "name",
139  "type",
140  "ref",
141  "minOccurs",
142  "maxOccurs",
143  "form",
144  "base",
145  "use",
146  "namespace",
147  "processContents",
148  "value",
149  "nillable",
150  "itemType",
151  "memberTypes",
152  "mixed",
153  "schemaLocation",
154  "substitutionGroup",
155  "abstract"
156 };
157 
158 static const char TRUE_CHAR_STR[] = "true";
159 static const char FALSE_CHAR_STR[] = "false";
160 
162 {
163  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
164  Parser xsdParser;
165  struct TreeTableParsingData ttpd;
166 
167  if(schemaFormat != SCHEMA_FORMAT_XSD_EXI)
169 
170  TRY(initParser(&xsdParser, buffer, &ttpd));
171 
172  xsdParser.handler.fatalError = xsd_fatalError;
173  xsdParser.handler.error = xsd_fatalError;
174  xsdParser.handler.startDocument = xsd_startDocument;
175  xsdParser.handler.endDocument = xsd_endDocument;
176  xsdParser.handler.startElement = xsd_startElement;
177  xsdParser.handler.attribute = xsd_attribute;
178  xsdParser.handler.stringData = xsd_stringData;
179  xsdParser.handler.endElement = xsd_endElement;
180  xsdParser.handler.namespaceDeclaration = xsd_namespaceDeclaration;
181  xsdParser.handler.booleanData = xsd_boolData;
182  xsdParser.handler.intData = xsd_intData;
183 
184  ttpd.propsStat = INITIAL_STATE;
185  ttpd.expectingAttr = FALSE;
186  ttpd.charDataPtr = NULL;
187  ttpd.ignoredElement = FALSE;
191  ttpd.contextStack = NULL;
192 
193  ttpd.treeT = treeT;
194  ttpd.schema = schema;
195 
196  // Parse the EXI stream
197 
198  if(opt != NULL)
199  {
200  xsdParser.strm.header.opts = *opt;
201  TRY(parseHeader(&xsdParser, TRUE));
202  }
203  else
204  {
205  TRY(parseHeader(&xsdParser, FALSE));
206  }
207 
209  {
210  /* When qualified namesNS are used in the values of AT or CH events in an EXI Stream,
211  * the Preserve.prefixes fidelity option SHOULD be turned on to enable the preservation of
212  * the NS prefix declarations used by these values. Note, in particular among other cases,
213  * that this practice applies to the use of xsi:type attributes in EXI streams when Preserve.lexicalValues
214  * fidelity option is set to true.*/
215  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, (">XML Schema must be EXI encoded with the prefixes preserved\n"));
216  destroyParser(&xsdParser);
218  }
219 
220  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">XML Schema header parsed\n"));
221 
222 #ifdef GRAMMAR_GEN_SCHEMA
223  if(stringEqual(xsdParser.strm.header.opts.schemaID, XML_SCHEMA_NAMESPACE))
224  {
225  // EXI encoded XML schema in schema mode
226  TRY(setSchema(&xsdParser, &xmlscm_schema));
227  }
228  else
229  {
230 #else
231  {
232 #endif
233  // EXI encoded XML schema in schema-less mode
234  TRY(setSchema(&xsdParser, NULL));
235  }
236 
237  while(tmp_err_code == EXIP_OK)
238  {
239  tmp_err_code = parseNext(&xsdParser);
240  }
241 
242  destroyParser(&xsdParser);
243 
244  if(tmp_err_code == EXIP_PARSING_COMPLETE)
245  return EXIP_OK;
246 
247  return tmp_err_code;
248 }
249 
250 static errorCode xsd_fatalError(const errorCode code, const char* msg, void* app_data)
251 {
252  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, (">Fatal error occurred during schema processing\n"));
253  return EXIP_HANDLER_STOP;
254 }
255 
256 static errorCode xsd_startDocument(void* app_data)
257 {
258  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Start XML Schema parsing\n"));
259  return EXIP_OK;
260 }
261 
262 static errorCode xsd_endDocument(void* app_data)
263 {
264  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">End XML Schema parsing\n"));
265  return EXIP_OK;
266 }
267 
268 static errorCode xsd_startElement(QName qname, void* app_data)
269 {
270  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
271  if(ttpd->propsStat == INITIAL_STATE) // This should be the first <schema> element
272  {
273  if(stringEqual(*qname.uri, XML_SCHEMA_NAMESPACE) &&
274  stringEqualToAscii(*qname.localName, "schema"))
275  {
277  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Starting <schema> element\n"));
278  }
279  else
280  {
281  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, (">Invalid XML Schema! Missing <schema> root element\n"));
282  return EXIP_HANDLER_STOP;
283  }
284  }
285  else
286  {
287  TreeTableEntry* treeTableEntry;
288  TreeTableEntry* prevEntry = NULL;
289  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
290  Index treeTableId;
291  int i;
292 
293  if(ttpd->propsStat == SCHEMA_ELEMENT_STATE)
294  {
298  if(!lookupUri(&ttpd->schema->uriTable, ttpd->treeT->globalDefs.targetNs, &ttpd->targetNsId))
299  {
300  String clonedTargetNS;
301 
302  TRY(cloneStringManaged(&ttpd->treeT->globalDefs.targetNs, &clonedTargetNS, &ttpd->schema->memList));
303 
304  // Add the target namespace to the schema string tables
305  TRY(addUriEntry(&ttpd->schema->uriTable, clonedTargetNS, &ttpd->targetNsId));
306  }
307 
308  // Setting up the tree table globalDefs
309 
310  if(stringEqualToAscii(ttpd->elementFormDefault, "qualified"))
312  if(stringEqualToAscii(ttpd->attributeFormDefault, "qualified"))
314 
316  }
317 
318  /**** Normal element processing starts here ****/
319 
320  if(!stringEqual(*qname.uri, XML_SCHEMA_NAMESPACE))
321  {
322  if(ttpd->ignoredElement == 0)
323  {
324  // If it is not within an ignored element
325  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, (">Invalid namespace of XML Schema element\n"));
326  return EXIP_HANDLER_STOP;
327  }
328  else
329  {
330  // If it is within an ignored element - ignore this one as well
331  ttpd->ignoredElement += 1;
332  return EXIP_OK;
333  }
334  }
335 
336  /**** Ignore certain elements. These elements will not be part of the resulting tree table. ****/
337 
338  if(stringEqualToAscii(*qname.localName, elemStrings[ELEMENT_ANNOTATION]))
339  {
340  ttpd->ignoredElement += 1;
341  return EXIP_OK;
342  }
343  else if(stringEqualToAscii(*qname.localName, elemStrings[ELEMENT_DOCUMENTATION]))
344  {
345  ttpd->ignoredElement += 1;
346  return EXIP_OK;
347  }
348  else if(stringEqualToAscii(*qname.localName, elemStrings[ELEMENT_APPINFO]))
349  {
350  ttpd->ignoredElement += 1;
351  return EXIP_OK;
352  }
353  else
354  ttpd->ignoredElement = FALSE;
355 
356  if(ttpd->contextStack != NULL)
357  prevEntry = (TreeTableEntry*) ttpd->contextStack->item;
358 
359  if(prevEntry == NULL)
360  {
361  /* At the root level, so create an entry */
362  TRY(addEmptyDynEntry(&ttpd->treeT->dynArray, (void**)&treeTableEntry, &treeTableId));
363  }
364  else
365  {
366  /* Nested entry */
367  treeTableEntry = (TreeTableEntry*) memManagedAllocate(&ttpd->treeT->memList, sizeof(TreeTableEntry));
368  if(treeTableEntry == NULL)
369  {
370  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, (">Memory allocation error\n"));
371  return EXIP_HANDLER_STOP;
372  }
373 
374  if(prevEntry->child.entry == NULL)
375  {
376  /* Nesting one level deeper */
377  prevEntry->child.entry = treeTableEntry;
378  prevEntry->child.treeT = ttpd->treeT;
379  }
380  else /* Append across */
381  {
382  TreeTableEntry* lastEntry;
383 
384  lastEntry = prevEntry->child.entry->next;
385  if(lastEntry == NULL)
386  {
387  prevEntry->child.entry->next = treeTableEntry;
388  }
389  else
390  {
391  while(lastEntry->next != NULL)
392  {
393  lastEntry = lastEntry->next;
394  }
395  lastEntry->next = treeTableEntry;
396  }
397  }
398  }
399 
400  initEntryContext(treeTableEntry);
401 
402  for(i = (int) ELEMENT_ELEMENT; i < (int) ELEMENT_VOID; i++)
403  {
404  /*
405  * See what sort of stream element this actually is.
406  * Tag the stream element to direct processing at the end of the stream element
407  */
408  if(stringEqualToAscii(*qname.localName, elemStrings[i]))
409  {
410  treeTableEntry->element = (ElemEnum) i;
411  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Starting <%s> element\n", elemStrings[i]));
412  break;
413  }
414  }
415  if (i == (int) ELEMENT_VOID)
416  {
417  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored schema element\n"));
418 #if EXIP_DEBUG == ON && DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL <= WARNING
419  printString(qname.localName);
421 #endif
422  return EXIP_HANDLER_STOP;
423  }
424 
425  /* Push the stream element onto the context stack associated with the stream */
426  TRY(pushOnStack(&(ttpd->contextStack), treeTableEntry));
427  }
428 
429  return EXIP_OK;
430 }
431 
432 static errorCode xsd_endElement(void* app_data)
433 {
434  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
435  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
436 
437  if(ttpd->ignoredElement != FALSE)
438  {
439  ttpd->ignoredElement -= 1;
440  return EXIP_OK;
441  }
442 
443  if(ttpd->contextStack == NULL) // No elements stored in the stack. That is </schema>
444  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">End </schema> element\n"));
445  else
446  {
448  String* elName;
449  String clonedName;
450 
451  /* Pop the stream element from the stack*/
452  popFromStack(&ttpd->contextStack, (void**) &entry);
453 
454  elName = &entry->attributePointers[ATTRIBUTE_NAME];
455 
456  if(entry->element != ELEMENT_NOTATION &&
457  entry->element != ELEMENT_KEY && !isStringEmpty(elName))
458  {
459  Index lnId;
460  SmallIndex uriId = 0; // URI 0 "" [empty string]
461 
462  if(ttpd->contextStack == NULL) // If the schema definition is global
463  {
464  // it is always in the target namespace
465  uriId = ttpd->targetNsId;
466  }
467  else
468  {
469  // local scope so look for form attribute value
470  if(entry->element == ELEMENT_ELEMENT)
471  {
473  uriId = ttpd->targetNsId;
474 
475  }
476  else if(entry->element == ELEMENT_ATTRIBUTE)
477  {
479  uriId = ttpd->targetNsId;
480  }
481  }
482 
483  if(!lookupLn(&ttpd->schema->uriTable.uri[uriId].lnTable, *elName, &lnId))
484  {
485  TRY(cloneStringManaged(elName, &clonedName, &ttpd->schema->memList));
486 
487  /* Add the element name to the schema string tables. Note this table persists beyond the tree table */
488  TRY(addLnEntry(&ttpd->schema->uriTable.uri[uriId].lnTable, clonedName, &lnId));
489  }
490 
491  if(entry->element == ELEMENT_ANY || entry->element == ELEMENT_ANY_ATTRIBUTE)
492  {
493  NsTable nsTable;
494  size_t i;
495 
496  TRY(createDynArray(&nsTable.dynArray, sizeof(String), 5));
497 
498  if(EXIP_OK != getNsList(ttpd->treeT, entry->attributePointers[ATTRIBUTE_NAMESPACE], &nsTable))
499  return EXIP_HANDLER_STOP;
500 
501  for(i = 0; i < nsTable.count; i++)
502  {
503  if(!lookupUri(&ttpd->schema->uriTable, nsTable.base[i], &uriId))
504  {
505  TRY(cloneStringManaged(&nsTable.base[i], &clonedName, &ttpd->schema->memList));
506 
507  /* Add the namespace to the schema URI string table. Note this table persists beyond the tree table */
508  TRY(addUriEntry(&ttpd->schema->uriTable, clonedName, &uriId));
509  }
510  }
511  }
512 
513 #if HASH_TABLE_USE
514  /*
515  * The hash tables are used to look up global definitions easily when it comes to resolving the tree table
516  * For example, an element local to another element may be declared with a type definition which is global.
517  * When it comes to linking that type in as a child or supertype, then the hash table can easily look up the
518  * appropriate tree table entry
519  */
520 
521  if(ttpd->contextStack == NULL) // If the schema definition is global
522  {
523  String lnNameStr = GET_LN_URI_IDS(ttpd->schema->uriTable, uriId, lnId).lnStr;
524 
525  if(entry->element == ELEMENT_ELEMENT)
526  {
527  if(ttpd->treeT->elemTbl != NULL)
528  {
529  if(hashtable_search(ttpd->treeT->elemTbl, lnNameStr) != INDEX_MAX)
530  {
531  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("ERROR: Duplicate global element name definition\n"));
532  return EXIP_HANDLER_STOP;
533  }
534 
535  if(hashtable_insert(ttpd->treeT->elemTbl, lnNameStr, ttpd->treeT->count - 1) != EXIP_OK)
536  return EXIP_HANDLER_STOP;
537  }
538  }
539  else if(entry->element == ELEMENT_SIMPLE_TYPE || entry->element == ELEMENT_COMPLEX_TYPE)
540  {
541  if(ttpd->treeT->typeTbl != NULL)
542  {
543  if(hashtable_search(ttpd->treeT->typeTbl, lnNameStr) != INDEX_MAX)
544  {
545  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("ERROR: Duplicate global type name definition\n"));
546  return EXIP_HANDLER_STOP;
547  }
548 
549  if(hashtable_insert(ttpd->treeT->typeTbl, lnNameStr, ttpd->treeT->count - 1) != EXIP_OK)
550  return EXIP_HANDLER_STOP;
551  }
552  }
553  else if(entry->element == ELEMENT_ATTRIBUTE)
554  {
555  if(ttpd->treeT->attrTbl != NULL)
556  {
557  if(hashtable_search(ttpd->treeT->attrTbl, lnNameStr) != INDEX_MAX)
558  {
559  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("ERROR: Duplicate global attribute name definition\n"));
560  return EXIP_HANDLER_STOP;
561  }
562 
563  if(hashtable_insert(ttpd->treeT->attrTbl, lnNameStr, ttpd->treeT->count - 1) != EXIP_OK)
564  return EXIP_HANDLER_STOP;
565  }
566  }
567  else if(entry->element == ELEMENT_GROUP)
568  {
569  if(ttpd->treeT->groupTbl != NULL)
570  {
571  if(hashtable_search(ttpd->treeT->groupTbl, lnNameStr) != INDEX_MAX)
572  {
573  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("ERROR: Duplicate global group name definition\n"));
574  return EXIP_HANDLER_STOP;
575  }
576 
577  if(hashtable_insert(ttpd->treeT->groupTbl, lnNameStr, ttpd->treeT->count - 1) != EXIP_OK)
578  return EXIP_HANDLER_STOP;
579  }
580  }
581  else if(entry->element == ELEMENT_ATTRIBUTE_GROUP)
582  {
583  if(ttpd->treeT->attrGroupTbl != NULL)
584  {
585  if(hashtable_search(ttpd->treeT->attrGroupTbl, lnNameStr) != INDEX_MAX)
586  {
587  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("ERROR: Duplicate global attribute group name definition\n"));
588  return EXIP_HANDLER_STOP;
589  }
590 
591  if(hashtable_insert(ttpd->treeT->attrGroupTbl, lnNameStr, ttpd->treeT->count - 1) != EXIP_OK)
592  return EXIP_HANDLER_STOP;
593  }
594  }
595  }
596 #endif
597  }
598  }
599 
600  return EXIP_OK;
601 }
602 
603 static errorCode xsd_attribute(QName qname, void* app_data)
604 {
605  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
606 
607  if(ttpd->ignoredElement != FALSE)
608  return EXIP_OK;
609 
610  if(ttpd->propsStat == SCHEMA_ELEMENT_STATE) // <schema> element attribute
611  {
612  if(stringEqualToAscii(*qname.localName, "targetNamespace"))
613  {
614  ttpd->charDataPtr = &(ttpd->treeT->globalDefs.targetNs);
615  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Attribute |targetNamespace| \n"));
616  }
617  else if(stringEqualToAscii(*qname.localName, "elementFormDefault"))
618  {
619  ttpd->charDataPtr = &(ttpd->elementFormDefault);
620  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Attribute |elementFormDefault| \n"));
621  }
622  else if(stringEqualToAscii(*qname.localName, "attributeFormDefault"))
623  {
624  ttpd->charDataPtr = &(ttpd->attributeFormDefault);
625  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Attribute |attributeFormDefault| \n"));
626  }
627  else
628  {
629  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored <schema> attribute\n"));
630 #if EXIP_DEBUG == ON && DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL <= WARNING
631  printString(qname.localName);
633 #endif
634  }
635  }
636  else
637  {
638  TreeTableEntry* currEntry = (TreeTableEntry*) ttpd->contextStack->item;
639  int i;
640 
641  for(i = (int)ATTRIBUTE_NAME; i < (int)ATTRIBUTE_CONTEXT_ARRAY_SIZE; i++)
642  {
643  /*
644  * See what sort of attribute this actually is.
645  * Tag the data ptr to the right attribute placeholder
646  */
647  if(stringEqualToAscii(*qname.localName, attrStrings[i]))
648  {
649  ttpd->charDataPtr = &currEntry->attributePointers[i];
650  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Attribute |%s|\n", attrStrings[i]));
651  break;
652  }
653  }
655  {
656  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored element attribute\n"));
657 #if EXIP_DEBUG == ON && DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL <= WARNING
658  printString(qname.localName);
660 #endif
661  }
662  }
663  ttpd->expectingAttr = TRUE;
664  return EXIP_OK;
665 }
666 
667 static errorCode xsd_stringData(const String value, void* app_data)
668 {
669  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
670  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
671 
672  if(ttpd->ignoredElement != FALSE)
673  return EXIP_OK;
674 
675  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">String data:\n"));
676 
677 #if DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL == INFO
678  printString(&value);
679  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n"));
680 #endif
681 
682  if(ttpd->expectingAttr)
683  {
684  if(ttpd->charDataPtr != NULL)
685  {
686  TRY(cloneStringManaged(&value, ttpd->charDataPtr, &ttpd->treeT->memList));
687  ttpd->charDataPtr = NULL;
688  }
689  else
690  {
691  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored element attribute value\n"));
692  }
693  ttpd->expectingAttr = FALSE;
694  }
695  else
696  {
697  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n>Ignored element character data"));
698  }
699 
700  return EXIP_OK;
701 }
702 
703 static errorCode xsd_boolData(boolean bool_val, void* app_data)
704 {
705  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
706  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
707  if(ttpd->ignoredElement != FALSE)
708  return EXIP_OK;
709 
710  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Bool data: %s\n", bool_val == TRUE?TRUE_CHAR_STR:FALSE_CHAR_STR));
711 
712  if(ttpd->expectingAttr)
713  {
714  if(ttpd->charDataPtr != NULL)
715  {
716  if(bool_val == TRUE)
717  TRY(asciiToString(TRUE_CHAR_STR, ttpd->charDataPtr, &ttpd->treeT->memList, TRUE));
718  else
719  TRY(asciiToString(FALSE_CHAR_STR, ttpd->charDataPtr, &ttpd->treeT->memList, TRUE));
720  ttpd->charDataPtr = NULL;
721  }
722  else
723  {
724  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored element attribute value\n"));
725  }
726  ttpd->expectingAttr = FALSE;
727  }
728  else
729  {
730  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, ("\n>Ignored element bool data"));
731  }
732 
733  return EXIP_OK;
734 }
735 
736 static errorCode xsd_intData(Integer int_val, void* app_data)
737 {
738  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
739  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
740  char tmp_str[15];
741  if(ttpd->ignoredElement != FALSE)
742  return EXIP_OK;
743 
744  sprintf(tmp_str, "%ld", (long) int_val);
745 
746  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Integer data: %s\n", tmp_str));
747 
748  if(ttpd->expectingAttr)
749  {
750  if(ttpd->charDataPtr != NULL)
751  {
752  TRY(asciiToString(tmp_str, ttpd->charDataPtr, &ttpd->treeT->memList, TRUE));
753  ttpd->charDataPtr = NULL;
754  }
755  else
756  {
757  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, (">Ignored element attribute value\n"));
758  }
759  ttpd->expectingAttr = FALSE;
760  }
761  else
762  {
763  DEBUG_MSG(WARNING, DEBUG_GRAMMAR_GEN, ("\n>Ignored element int data"));
764  }
765 
766  return EXIP_OK;
767 }
768 
769 static errorCode xsd_namespaceDeclaration(const String ns, const String pfx, boolean isLocalElementNS, void* app_data)
770 {
771  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
772  struct TreeTableParsingData* ttpd = (struct TreeTableParsingData*) app_data;
773  PfxNsEntry pfxNsEntry;
774  Index entryID;
775 
776  if(ttpd->ignoredElement != FALSE)
777  return EXIP_OK;
778 
779  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (">Namespace declaration\n"));
780 #if DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL == INFO
781  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (" pfx: "));
782  printString(&pfx);
783  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, (" ns: "));
784  printString(&ns);
785  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n"));
786 #endif
787 
788  TRY(cloneStringManaged(&ns, &pfxNsEntry.ns, &ttpd->treeT->memList));
789  TRY(cloneStringManaged(&pfx, &pfxNsEntry.pfx, &ttpd->treeT->memList));
790  TRY(addDynEntry(&ttpd->treeT->globalDefs.pfxNsTable.dynArray, &pfxNsEntry, &entryID));
791 
792  return EXIP_OK;
793 }
794 
795 static void initEntryContext(TreeTableEntry* entry)
796 {
797  unsigned int i = 0;
798  entry->next = NULL;
799  entry->supertype.entry = NULL;
800  entry->supertype.treeT = NULL;
801  entry->child.entry = NULL;
802  entry->child.treeT = NULL;
803  entry->element = ELEMENT_VOID;
804  entry->loopDetection = 0;
805 
806  for(i = 0; i < ATTRIBUTE_CONTEXT_ARRAY_SIZE; i++)
807  {
808  entry->attributePointers[i].length = 0;
809  entry->attributePointers[i].str = NULL;
810  }
811 }
812 
813 #if DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL == INFO
814 
815 static void printNameTypeBase(String *attrPtrs, char* indent)
816 {
817  if(attrPtrs[ATTRIBUTE_NAME].str != NULL)
818  {
819  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("%sName: ", indent));
820  printString(&attrPtrs[ATTRIBUTE_NAME]);
821  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n"));
822  }
823  if(attrPtrs[ATTRIBUTE_TYPE].str != NULL)
824  {
825  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("%sType: ", indent));
826  printString(&attrPtrs[ATTRIBUTE_TYPE]);
827  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n"));
828  }
829  if(attrPtrs[ATTRIBUTE_BASE].str != NULL)
830  {
831  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("%sBase: ", indent));
832  printString(&attrPtrs[ATTRIBUTE_BASE]);
833  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n"));
834  }
835 }
836 
837 #define FULL_EXPANSION
838 
839 void printTreeTableEntry(TreeTableEntry* treeTableEntryIn, int indentIdx, char *prefix)
840 {
841  char indent[101] = " ";
842 
843  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("%s%s[%s]\n", indent + (100 - indentIdx), prefix, elemStrings[treeTableEntryIn->element]));
844  printNameTypeBase(treeTableEntryIn->attributePointers, indent + (100 - indentIdx));
845 
846 #ifdef FULL_EXPANSION
847  if(treeTableEntryIn->supertype.entry != NULL)
848  printTreeTableEntry(treeTableEntryIn->supertype.entry, indentIdx + 4, "");
849 
850  if(treeTableEntryIn->child.entry != NULL)
851  printTreeTableEntry(treeTableEntryIn->child.entry, indentIdx, "");
852 #else
853  if(treeTableEntryIn->child.entry != NULL)
854  printTreeTableEntry(treeTableEntryIn->child.entry, indentIdx+2, "");
855 #endif
856 
857  if(treeTableEntryIn->next != NULL)
858  printTreeTableEntry(treeTableEntryIn->next, indentIdx, "...");
859 
860 }
861 #endif