exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exipg.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 "createGrammars.h"
19 #include "grammarGenerator.h"
20 
21 #define MAX_XSD_FILES_COUNT 10 // up to 10 XSD files
22 #define OUT_EXIP 0
23 #define OUT_TEXT 1
24 #define OUT_SRC_DYN 2
25 #define OUT_SRC_STAT 3
26 
27 static void printfHelp();
28 static void parseSchema(char* xsdList, EXIPSchema* schema, unsigned char mask, EXIOptions maskOpt);
29 
30 int main(int argc, char *argv[])
31 {
32  FILE *outfile = stdout; // Default is the standard output
33  EXIPSchema schema;
34  unsigned char outputFormat = OUT_EXIP;
35  int argIndex = 1;
36  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
37  char prefix[20];
38  unsigned char mask = FALSE;
39  EXIOptions maskOpt;
40  Deviations dvis;
41 
42  dvis.grammar = 0;
43  dvis.ln = 0;
44  dvis.url = 0;
45  makeDefaultOpts(&maskOpt);
46 
47  if(argc == 1)
48  {
49  printfHelp();
50  return 0;
51  }
52 
53  if(strcmp(argv[argIndex], "-help") == 0)
54  {
55  printfHelp();
56  return 0;
57  }
58  else if(strcmp(argv[argIndex], "-exip") == 0)
59  {
60  outputFormat = OUT_EXIP;
61  argIndex++;
62  }
63  else if(strcmp(argv[argIndex], "-text") == 0)
64  {
65  outputFormat = OUT_TEXT;
66  argIndex++;
67  }
68  else if(strcmp(argv[argIndex], "-dynamic") == 0)
69  {
70  outputFormat = OUT_SRC_DYN;
71  argIndex++;
72  }
73  else if(strlen(argv[argIndex]) >= 7 &&
74  argv[argIndex][0] == '-' &&
75  argv[argIndex][1] == 's' &&
76  argv[argIndex][2] == 't' &&
77  argv[argIndex][3] == 'a' &&
78  argv[argIndex][4] == 't' &&
79  argv[argIndex][5] == 'i' &&
80  argv[argIndex][6] == 'c')
81  {
82  outputFormat = OUT_SRC_STAT;
83  if(strlen(argv[argIndex]) >= 15 && argv[argIndex][7] == '=' )
84  {
85  char * pEnd;
86 
87  dvis.url = (int) strtol (argv[argIndex] + 8, &pEnd, 10);
88  dvis.ln = (int) strtol (pEnd + 1, &pEnd, 10);
89  dvis.pfx = (int) strtol (pEnd + 1, &pEnd, 10);
90  dvis.grammar = (int) strtol (pEnd + 1, NULL, 10);
91  }
92  argIndex++;
93  }
94 
95  if(argc <= argIndex)
96  {
97  printfHelp();
98  return 0;
99  }
100 
101  if(strlen(argv[argIndex]) >= 5 &&
102  argv[argIndex][0] == '-' &&
103  argv[argIndex][1] == 'p' &&
104  argv[argIndex][2] == 'f' &&
105  argv[argIndex][3] == 'x' &&
106  argv[argIndex][4] == '=')
107  {
108  strcpy(prefix, argv[argIndex] + 5);
109  argIndex++;
110  }
111  else
112  {
113  strcpy(prefix, "prfx_"); // The default prefix
114  }
115 
116  if(argc <= argIndex)
117  {
118  printfHelp();
119  return 0;
120  }
121 
122  if(strlen(argv[argIndex]) >= 5 &&
123  argv[argIndex][0] == '-' &&
124  argv[argIndex][1] == 'o' &&
125  argv[argIndex][2] == 'p' &&
126  argv[argIndex][3] == 's' &&
127  argv[argIndex][4] == '=')
128  {
129  mask = TRUE;
130  if(argv[argIndex][5] == '1')
131  SET_STRICT(maskOpt.enumOpt);
132 
133  if(argv[argIndex][6] == '1')
134  SET_SELF_CONTAINED(maskOpt.enumOpt);
135 
136  if(argv[argIndex][7] == '1')
138 
139  if(argv[argIndex][8] == '1')
141 
142  if(argv[argIndex][9] == '1')
144 
145  if(argv[argIndex][10] == '1')
147 
148  if(argv[argIndex][11] == '1')
150 
151  argIndex++;
152  }
153 
154  if(argc <= argIndex)
155  {
156  printfHelp();
157  return 0;
158  }
159 
160  if(strstr(argv[argIndex], "-schema") != NULL)
161  {
162  char *xsdList = argv[argIndex] + 7;
163 
164  parseSchema(xsdList, &schema, mask, maskOpt);
165 
166  argIndex += 1;
167  }
168  else
169  {
170  printfHelp();
171  return 0;
172  }
173 
174  if(argc > argIndex)
175  {
176  outfile = fopen(argv[argIndex], "wb" );
177  if(!outfile)
178  {
179  fprintf(stderr, "Unable to open file %s", argv[argIndex]);
180  return 1;
181  }
182  argIndex += 1;
183  }
184 
185  switch(outputFormat)
186  {
187  case OUT_TEXT:
188  tmp_err_code = toText(&schema, outfile);
189  break;
190  case OUT_EXIP:
191  tmp_err_code = toEXIP(&schema, outfile);
192  break;
193  case OUT_SRC_STAT:
194  tmp_err_code = toStaticSrc(&schema, prefix, outfile, dvis);
195  break;
196  case OUT_SRC_DYN:
197  tmp_err_code = toDynSrc(&schema, outfile);
198  break;
199  default:
200  printf("\nUnsupported output format!");
201  exit(1);
202  break;
203  }
204 
205  destroySchema(&schema);
206 
207  fclose(outfile);
208 
209  if(tmp_err_code != EXIP_OK)
210  {
211  printf("\nError during grammar output!");
212  exit(1);
213  }
214 
215  return 0;
216 }
217 
218 static void printfHelp()
219 {
220  printf("\n" );
221  printf(" EXIP Copyright (c) 2010 - 2012, EISLAB - LuleĆ„ University of Technology Version 0.5.1 \n");
222  printf(" Author: Rumen Kyusakov\n");
223  printf(" Usage: exipg [options] -schema=<xsd_in> [grammar_out] \n\n");
224  printf(" Options: [-help | [[-exip | -text | -dynamic | -static[=<deviations>]] [-pfx=<prefix>] [-ops=<ops_mask>]] ] \n");
225  printf(" -help : Prints this help message\n");
226  printf(" -exip : Format the output schema definitions in EXIP-specific format (Default)\n");
227  printf(" -text : Format the output schema definitions in human readable text format\n");
228  printf(" -dynamic : Create C code for the grammars defined. The output is a C function that dynamically generates the grammars\n");
229  printf(" -static : Create C code for the grammars defined. The output is C structures describing the grammars\n");
230  printf(" deviations : When static C code is chosen for the output, this defines a static size of the possible extensions\n");
231  printf(" for URI, Local names, prefixes, and build-in grammars. The format is: <uri>:<ln>:<pfx>:<grammars>\n");
232  printf(" For example deviations -static=2:5:1:10 will allow for two non-schema namespaces, 5 new local names\n");
233  printf(" per each schema namespace, 1 additional prefix per namespace, and 10 new built-in grammars.\n");
234  printf(" The larger deviations the more memory is required.\n");
235  printf(" -pfx : When in -dynamic or -static mode, this option allows you to specify a unique prefix for the\n");
236  printf(" generated global types. The default is \"prfx_\"\n");
237  printf(" ops_mask : The format is: <STRICT><SELF_CONTAINED><dtd><prefixes><lexicalValues><comments><pis> := <0|1><0|1><0|1><0|1><0|1><0|1><0|1>\n");
238  printf(" Use this argument only for specifying out-of-band options. That is if no options are specified in the header of the <xsd_in>\n");
239  printf(" EXI encoded schema files but some options are used during encoding.\n");
240  printf(" This argument is useful for generating the \"EXI Options\" grammar where STRICT is set and the rest are default options. \n");
241  printf(" In this way the bootstrapping of the code is easier. The mask to use for EXIOptions-xsd.exi is -ops=0001000 \n");
242  printf(" -schema : The source schema definitions - all referenced schema files should be included in <xsd_in>\n");
243  printf(" xsd_in : Comma-separated list of schema documents encoded in EXI with Preserve.prefixes. The first schema is the main one and\n");
244  printf(" the rest are schemas that are referenced from the main one through the <xs:import> statement.\n");
245  printf(" grammar_out : Destination file for the grammar output (Default is the standard output) \n\n");
246  printf(" Purpose: Manipulation of EXIP schemas\n");
247  printf("\n" );
248 }
249 
250 static void parseSchema(char* xsdList, EXIPSchema* schema, unsigned char mask, EXIOptions maskOpt)
251 {
252  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
253  FILE *schemaFile;
254  BinaryBuffer buffer[MAX_XSD_FILES_COUNT]; // up to 10 XSD files
255  char schemaFileName[50];
256  unsigned int schemaFilesCount = 0;
257  unsigned int i;
258  char *token;
259  EXIOptions* opt = NULL;
260 
261  if(mask)
262  opt = &maskOpt;
263 
264  for (token = strtok(xsdList, "=,"), i = 0; token != NULL; token = strtok(NULL, "=,"), i++)
265  {
266  schemaFilesCount++;
267  if(schemaFilesCount > MAX_XSD_FILES_COUNT)
268  {
269  fprintf(stderr, "Too many xsd files given as an input: %d", schemaFilesCount);
270  exit(1);
271  }
272 
273  strcpy(schemaFileName, token);
274  schemaFile = fopen(schemaFileName, "rb" );
275  if(!schemaFile)
276  {
277  fprintf(stderr, "Unable to open file %s", schemaFileName);
278  exit(1);
279  }
280  else
281  {
282  //Get file length
283  fseek(schemaFile, 0, SEEK_END);
284  buffer[i].bufLen = ftell(schemaFile) + 1;
285  fseek(schemaFile, 0, SEEK_SET);
286 
287  //Allocate memory
288  buffer[i].buf = (char *) malloc(buffer[i].bufLen);
289  if (!buffer[i].buf)
290  {
291  fprintf(stderr, "Memory allocation error!");
292  fclose(schemaFile);
293  exit(1);
294  }
295 
296  //Read file contents into buffer
297  fread(buffer[i].buf, buffer[i].bufLen, 1, schemaFile);
298  fclose(schemaFile);
299 
300  buffer[i].bufContent = buffer[i].bufLen;
301  buffer[i].ioStrm.readWriteToStream = NULL;
302  buffer[i].ioStrm.stream = NULL;
303  }
304  }
305 
306  // Generate the EXI grammars based on the schema information
307  tmp_err_code = generateSchemaInformedGrammars(buffer, schemaFilesCount, SCHEMA_FORMAT_XSD_EXI, opt, schema, NULL);
308 
309  for(i = 0; i < schemaFilesCount; i++)
310  {
311  free(buffer[i].buf);
312  }
313 
314  if(tmp_err_code != EXIP_OK)
315  {
316  printf("\nGrammar generation error occurred: %d", tmp_err_code);
317  exit(1);
318  }
319 }