exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
grammarGenerator.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 
17 #include "grammarGenerator.h"
18 #include "treeTableSchema.h"
19 #include "stringManipulate.h"
20 #include "memManagement.h"
21 #include "initSchemaInstance.h"
22 #include "sTables.h"
23 
24 
25 static int compareLn(const void* lnRow1, const void* lnRow2);
26 static int compareUri(const void* uriRow1, const void* uriRow2);
27 
31 static void sortUriTable(UriTable* uriTable);
32 
33 errorCode generateSchemaInformedGrammars(BinaryBuffer* buffers, unsigned int bufCount, SchemaFormat schemaFormat, EXIOptions* opt, EXIPSchema* schema,
34  errorCode (*loadSchemaHandler) (String* namespace, String* schemaLocation, BinaryBuffer** buffers, unsigned int* bufCount, SchemaFormat* schemaFormat, EXIOptions** opt))
35 {
36  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
37  TreeTable* treeT;
38  SubstituteTable substituteTbl;
39  unsigned int treeTCount = bufCount;
40  unsigned int i = 0;
41 
42  // TODO: again in error cases all the memory must be released
43 
44  treeT = (TreeTable*) EXIP_MALLOC(sizeof(TreeTable)*bufCount);
45  if(treeT == NULL)
47 
48  /* Initialize the SubstituteTable in case there are substitution groups defined in the schema */
49  TRY(createDynArray(&substituteTbl.dynArray, sizeof(SubtGroupHead), 5));
50 
51  for(i = 0; i < bufCount; i++)
52  {
53  TRY(initTreeTable(&treeT[i]));
54  }
55 
57 
58  for(i = 0; i < bufCount; i++)
59  {
60  TRY(generateTreeTable(buffers[i], schemaFormat, opt, &treeT[i], schema));
61  }
62 
63  TRY(resolveIncludeImportReferences(schema, &treeT, &treeTCount, loadSchemaHandler));
64 
65 #if DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL == INFO
66  {
67  unsigned int j;
68  for(i = 0; i < treeTCount; i++)
69  {
70  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\nElement tree %d before resolving:\n", i));
71  for(j = 0; j < treeT[i].count; j++)
72  {
73  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n>(Before) Tree Table Entry %d:\n", j));
74  printTreeTableEntry(&treeT[i].tree[j], 0, "");
75  }
76 
77  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("\nPrefix Namespace Table\n"));
78  for(j = 0; j < treeT[i].globalDefs.pfxNsTable.count; j++)
79  {
80  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("index: %u\n", j));
81  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("prf: "));
82  printString(&treeT[i].globalDefs.pfxNsTable.pfxNs[j].pfx);
84  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("uri: "));
85  printString(&treeT[i].globalDefs.pfxNsTable.pfxNs[j].ns);
87  }
88  }
89 
90  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("\nURI Table\n"));
91  for(i = 0; i < schema->uriTable.count; i++)
92  {
93  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("index: %u\n", i));
94  DEBUG_MSG(ERROR, DEBUG_GRAMMAR_GEN, ("uri: "));
95  printString(&schema->uriTable.uri[i].uriStr);
97  }
98  }
99 #endif
100 
101  // Sort the string tables
102  sortUriTable(&schema->uriTable);
103 
104  // Find the correct targetNsId in the string tables for each TreeTable
105  for(i = 0; i < treeTCount; i++)
106  {
107  if(!lookupUri(&schema->uriTable, treeT[i].globalDefs.targetNs, &treeT[i].globalDefs.targetNsId))
108  return EXIP_UNEXPECTED_ERROR;
109  }
110 
111  TRY(resolveTypeHierarchy(schema, treeT, treeTCount, &substituteTbl));
112 
113 #if DEBUG_GRAMMAR_GEN == ON && EXIP_DEBUG_LEVEL == INFO
114  {
115  unsigned int j;
116 
117  for(i = 0; i < treeTCount; i++)
118  {
119  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\nElement tree %d after resolving:\n", i));
120  for(j = 0; j < treeT[i].count; j++)
121  {
122  DEBUG_MSG(INFO, DEBUG_GRAMMAR_GEN, ("\n>(After) Tree Table Entry %d:\n", j));
123  printTreeTableEntry(&treeT[i].tree[j], 0, "");
124  }
125  }
126  }
127 #endif
128 
129  TRY(convertTreeTablesToExipSchema(treeT, treeTCount, schema, &substituteTbl));
130 
131  /* Destroy all tree tables */
132  for(i = 0; i < treeTCount; i++)
133  {
134  destroyTreeTable(&treeT[i]);
135  }
136 
137  /* Destroy all substitution group heads if any */
138  for(i = 0; i < substituteTbl.count; i++)
139  {
140  destroyDynArray(&substituteTbl.head[i].dynArray);
141  }
142 
143  /* Destroy the substitution group table */
144  destroyDynArray(&substituteTbl.dynArray);
145 
146  EXIP_MFREE(treeT);
147 
148  return tmp_err_code;
149 }
150 
152 {
153  Index i;
154 
155  // Freeing the string tables
156 
157  for(i = 0; i < schema->uriTable.count; i++)
158  {
161  }
162 
167  freeAllocList(&schema->memList);
168 }
169 
170 
171 static int compareLn(const void* lnRow1, const void* lnRow2)
172 {
173  LnEntry* lnEntry1 = (LnEntry*)lnRow1;
174  LnEntry* lnEntry2 = (LnEntry*)lnRow2;
175 
176  return stringCompare(lnEntry1->lnStr, lnEntry2->lnStr);
177 }
178 
179 static int compareUri(const void* uriRow1, const void* uriRow2)
180 {
181  UriEntry* uriEntry1 = (UriEntry*) uriRow1;
182  UriEntry* uriEntry2 = (UriEntry*) uriRow2;
183 
184  return stringCompare(uriEntry1->uriStr, uriEntry2->uriStr);
185 }
186 
187 static void sortUriTable(UriTable* uriTable)
188 {
189  uint16_t i = 0;
190 
191  // First sort the local name tables
192 
193  for (i = 0; i < uriTable->count; i++)
194  {
195  unsigned int initialEntries = 0;
196 
197  // The initialEntries entries in "http://www.w3.org/XML/1998/namespace",
198  // "http://www.w3.org/2001/XMLSchema-instance" and "http://www.w3.org/2001/XMLSchema"
199  // are not sorted
200  if(i == XML_NAMESPACE_ID) // "http://www.w3.org/XML/1998/namespace"
201  {
202  initialEntries = 4;
203  }
204  else if(i == XML_SCHEMA_INSTANCE_ID) // "http://www.w3.org/2001/XMLSchema-instance"
205  {
206  initialEntries = 2;
207  }
208  else if(i == XML_SCHEMA_NAMESPACE_ID) // "http://www.w3.org/2001/XMLSchema"
209  {
210  initialEntries = 46;
211  }
212 
213  if(uriTable->uri[i].lnTable.ln != NULL)
214  qsort(&uriTable->uri[i].lnTable.ln[initialEntries], uriTable->uri[i].lnTable.count - initialEntries, sizeof(LnEntry), compareLn);
215  }
216 
217  // Then sort the uri tables
218 
219  // The first four initial entries are not sorted
220  // URI 0 "" [empty string]
221  // URI 1 "http://www.w3.org/XML/1998/namespace"
222  // URI 2 "http://www.w3.org/2001/XMLSchema-instance"
223  // URI 3 "http://www.w3.org/2001/XMLSchema"
224  qsort(&uriTable->uri[4], uriTable->count - 4, sizeof(UriEntry), compareUri);
225 }