Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/xml/xsd-to-xmlparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1784 - (show annotations) (download) (as text)
Sat Aug 15 13:08:37 2015 UTC (9 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 16574 byte(s)
Merge libroutino branch back into the trunk.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/xml/xsd-to-xmlparser.c,v 1.10 2010-04-23 18:41:20 amb Exp $
3
4 An XML parser for simplified XML Schema Definitions to create XML parser skeletons.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2010-2015 Andrew M. Bishop
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
23
24
25 #include <stdio.h>
26 #if !defined(_MSC_VER)
27 #include <unistd.h>
28 #endif
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "xmlparse.h"
34
35
36 /*+ A forward definition of the xmltagx +*/
37 typedef struct _xmltagx xmltagx;
38
39
40 /*+ A structure to hold the extended definition of a tag. +*/
41 struct _xmltagx
42 {
43 char *name; /*+ The name of the tag. +*/
44 char *type; /*+ The type of the tag. +*/
45
46 int nattributes; /*+ The number of valid attributes for the tag. +*/
47 char *attributes[XMLPARSE_MAX_ATTRS]; /*+ The valid attributes for the tag. +*/
48
49 int nsubtagsx; /*+ The number of valid attributes for the tag. +*/
50 xmltagx *subtagsx[XMLPARSE_MAX_SUBTAGS]; /*+ The list of types for the subtags contained within this one. +*/
51 };
52
53
54 /* The local variables and functions */
55
56 int ntagsx=0;
57 xmltagx **tagsx=NULL;
58 char *currenttype=NULL;
59
60 static char *safe(const char *name);
61
62
63 /* The XML tag processing function prototypes */
64
65 static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
66 static int schemaType_function(const char *_tag_,int _type_,const char *elementFormDefault,const char *xmlns_xsd);
67 static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs);
68 static int complexType_function(const char *_tag_,int _type_,const char *name);
69 static int sequenceType_function(const char *_tag_,int _type_);
70 static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type);
71
72
73 /* The XML tag definitions (forward declarations) */
74
75 static const xmltag xmlDeclaration_tag;
76 static const xmltag schemaType_tag;
77 static const xmltag elementType_tag;
78 static const xmltag complexType_tag;
79 static const xmltag sequenceType_tag;
80 static const xmltag attributeType_tag;
81
82
83 /* The XML tag definition values */
84
85 /*+ The complete set of tags at the top level. +*/
86 static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL};
87
88 /*+ The xmlDeclaration type tag. +*/
89 static const xmltag xmlDeclaration_tag=
90 {"xml",
91 2, {"version","encoding"},
92 xmlDeclaration_function,
93 {NULL}};
94
95 /*+ The schemaType type tag. +*/
96 static const xmltag schemaType_tag=
97 {"xsd:schema",
98 2, {"elementFormDefault","xmlns:xsd"},
99 schemaType_function,
100 {&elementType_tag,&complexType_tag,NULL}};
101
102 /*+ The elementType type tag. +*/
103 static const xmltag elementType_tag=
104 {"xsd:element",
105 4, {"name","type","minOccurs","maxOccurs"},
106 elementType_function,
107 {NULL}};
108
109 /*+ The complexType type tag. +*/
110 static const xmltag complexType_tag=
111 {"xsd:complexType",
112 1, {"name"},
113 complexType_function,
114 {&sequenceType_tag,&attributeType_tag,NULL}};
115
116 /*+ The sequenceType type tag. +*/
117 static const xmltag sequenceType_tag=
118 {"xsd:sequence",
119 0, {NULL},
120 sequenceType_function,
121 {&elementType_tag,NULL}};
122
123 /*+ The attributeType type tag. +*/
124 static const xmltag attributeType_tag=
125 {"xsd:attribute",
126 2, {"name","type"},
127 attributeType_function,
128 {NULL}};
129
130
131 /* The XML tag processing functions */
132
133
134 /*++++++++++++++++++++++++++++++++++++++
135 The function that is called when the XML declaration is seen
136
137 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
138
139 const char *_tag_ Set to the name of the element tag that triggered this function call.
140
141 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
142
143 const char *version The contents of the 'version' attribute (or NULL if not defined).
144
145 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
146 ++++++++++++++++++++++++++++++++++++++*/
147
148 static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
149 {
150 /* Add the XML declaration as a tag. */
151
152 currenttype=NULL;
153 elementType_function("xsd:element",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"xml","xmlDeclaration",NULL,NULL);
154 complexType_function("xsd:complexType",XMLPARSE_TAG_START,"xmlDeclaration");
155 attributeType_function("xsd:attribute",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"version",NULL);
156 attributeType_function("xsd:attribute",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"encoding",NULL);
157 complexType_function("xsd:complexType",XMLPARSE_TAG_END,NULL);
158 currenttype=NULL;
159
160 return(0);
161 }
162
163
164 /*++++++++++++++++++++++++++++++++++++++
165 The function that is called when the schemaType XSD type is seen
166
167 int schemaType_function Returns 0 if no error occured or something else otherwise.
168
169 const char *_tag_ Set to the name of the element tag that triggered this function call.
170
171 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
172
173 const char *elementFormDefault The contents of the 'elementFormDefault' attribute (or NULL if not defined).
174
175 const char *xmlns_xsd The contents of the 'xmlns:xsd' attribute (or NULL if not defined).
176 ++++++++++++++++++++++++++++++++++++++*/
177
178 static int schemaType_function(const char *_tag_,int _type_,const char *elementFormDefault,const char *xmlns_xsd)
179 {
180 return(0);
181 }
182
183
184 /*++++++++++++++++++++++++++++++++++++++
185 The function that is called when the elementType XSD type is seen
186
187 int elementType_function Returns 0 if no error occured or something else otherwise.
188
189 const char *_tag_ Set to the name of the element tag that triggered this function call.
190
191 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
192
193 const char *name The contents of the 'name' attribute (or NULL if not defined).
194
195 const char *type The contents of the 'type' attribute (or NULL if not defined).
196
197 const char *minOccurs The contents of the 'minOccurs' attribute (or NULL if not defined).
198
199 const char *maxOccurs The contents of the 'maxOccurs' attribute (or NULL if not defined).
200 ++++++++++++++++++++++++++++++++++++++*/
201
202 static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs)
203 {
204 xmltagx *tagx=NULL;
205 int i;
206
207 if(_type_==XMLPARSE_TAG_END)
208 return(0);
209
210 for(i=0;i<ntagsx;i++)
211 if(!strcmp(type,tagsx[i]->type) && !strcmp(name,tagsx[i]->name))
212 tagx=tagsx[i];
213
214 if(!tagx)
215 {
216 ntagsx++;
217 tagsx=(xmltagx**)realloc((void*)tagsx,ntagsx*sizeof(xmltagx*));
218
219 tagsx[ntagsx-1]=(xmltagx*)calloc(1,sizeof(xmltagx));
220 tagsx[ntagsx-1]->name=strcpy(malloc(strlen(name)+1),name);
221 tagsx[ntagsx-1]->type=strcpy(malloc(strlen(type)+1),type);
222
223 tagx=tagsx[ntagsx-1];
224 }
225
226 if(!currenttype)
227 return(0);
228
229 for(i=0;i<ntagsx;i++)
230 if(!strcmp(tagsx[i]->type,currenttype))
231 {
232 tagsx[i]->subtagsx[tagsx[i]->nsubtagsx]=tagx;
233 tagsx[i]->nsubtagsx++;
234
235 if(tagsx[i]->nsubtagsx==XMLPARSE_MAX_SUBTAGS)
236 {fprintf(stderr,"Too many subtags seen for type '%s'.\n",currenttype); exit(1);}
237 }
238
239 return(0);
240 }
241
242
243 /*++++++++++++++++++++++++++++++++++++++
244 The function that is called when the complexType XSD type is seen
245
246 int complexType_function Returns 0 if no error occured or something else otherwise.
247
248 const char *_tag_ Set to the name of the element tag that triggered this function call.
249
250 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
251
252 const char *name The contents of the 'name' attribute (or NULL if not defined).
253 ++++++++++++++++++++++++++++++++++++++*/
254
255 static int complexType_function(const char *_tag_,int _type_,const char *name)
256 {
257 if(_type_==XMLPARSE_TAG_END)
258 return(0);
259
260 currenttype=strcpy(realloc(currenttype,strlen(name)+1),name);
261
262 return(0);
263 }
264
265
266 /*++++++++++++++++++++++++++++++++++++++
267 The function that is called when the sequenceType XSD type is seen
268
269 int sequenceType_function Returns 0 if no error occured or something else otherwise.
270
271 const char *_tag_ Set to the name of the element tag that triggered this function call.
272
273 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
274 ++++++++++++++++++++++++++++++++++++++*/
275
276 static int sequenceType_function(const char *_tag_,int _type_)
277 {
278 return(0);
279 }
280
281
282 /*++++++++++++++++++++++++++++++++++++++
283 The function that is called when the attributeType XSD type is seen
284
285 int attributeType_function Returns 0 if no error occured or something else otherwise.
286
287 const char *_tag_ Set to the name of the element tag that triggered this function call.
288
289 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
290
291 const char *name The contents of the 'name' attribute (or NULL if not defined).
292
293 const char *type The contents of the 'type' attribute (or NULL if not defined).
294 ++++++++++++++++++++++++++++++++++++++*/
295
296 static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type)
297 {
298 int i;
299
300 if(_type_==XMLPARSE_TAG_END)
301 return(0);
302
303 for(i=0;i<ntagsx;i++)
304 if(!strcmp(tagsx[i]->type,currenttype))
305 {
306 tagsx[i]->attributes[tagsx[i]->nattributes]=strcpy(malloc(strlen(name)+1),name);
307 tagsx[i]->nattributes++;
308
309 if(tagsx[i]->nattributes==XMLPARSE_MAX_ATTRS)
310 {fprintf(stderr,"Too many attributes seen for type '%s'.\n",currenttype); exit(1);}
311 }
312
313 return(0);
314 }
315
316
317 /*++++++++++++++++++++++++++++++++++++++
318 The XML Schema Definition XML parser and C program generator.
319 ++++++++++++++++++++++++++++++++++++++*/
320
321 int main(int argc,char **argv)
322 {
323 int i,j;
324
325 /* Parse the XSD file */
326
327 if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE))
328 {
329 fprintf(stderr,"Cannot parse XML file - exiting.\n");
330 exit(1);
331 }
332
333 /* Print the header */
334
335 printf("/***************************************\n");
336 printf(" An automatically generated skeleton XML parser.\n");
337 printf("\n");
338 printf(" Automatically generated by xsd-to-xmlparser.\n");
339 printf(" ***************************************/\n");
340 printf("\n");
341 printf("\n");
342 printf("#include <stdio.h>\n");
343 printf("#if !defined(_MSC_VER)\n");
344 printf("#include <unistd.h>\n");
345 printf("#endif\n");
346 printf("\n");
347 printf("#include \"xmlparse.h\"\n");
348
349 /* Print the function prototypes */
350
351 printf("\n");
352 printf("\n");
353 printf("/* The XML tag processing function prototypes */\n");
354 printf("\n");
355
356 for(i=0;i<ntagsx;i++)
357 {
358 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
359
360 for(j=0;j<tagsx[i]->nattributes;j++)
361 printf(",const char *%s",safe(tagsx[i]->attributes[j]));
362
363 printf(");\n");
364 }
365
366 /* Print the xmltag variables */
367
368 printf("\n");
369 printf("\n");
370 printf("/* The XML tag definitions (forward declarations) */\n");
371
372 printf("\n");
373
374 for(i=0;i<ntagsx;i++)
375 printf("static const xmltag %s_tag;\n",safe(tagsx[i]->type));
376
377 printf("\n");
378 printf("\n");
379 printf("/* The XML tag definition values */\n");
380
381 printf("\n");
382 printf("/*+ The complete set of tags at the top level. +*/\n");
383 printf("static const xmltag * const xml_toplevel_tags[]={");
384 printf("&%s_tag,",safe(tagsx[0]->type));
385 printf("&%s_tag,",safe(tagsx[1]->type));
386 printf("NULL};\n");
387
388 for(i=0;i<ntagsx;i++)
389 {
390 printf("\n");
391 printf("/*+ The %s type tag. +*/\n",tagsx[i]->type);
392 printf("static const xmltag %s_tag=\n",safe(tagsx[i]->type));
393 printf(" {\"%s\",\n",tagsx[i]->name);
394
395 printf(" %d, {",tagsx[i]->nattributes);
396 for(j=0;j<tagsx[i]->nattributes;j++)
397 printf("%s\"%s\"",(j?",":""),tagsx[i]->attributes[j]);
398 printf("%s},\n",(tagsx[i]->nattributes?"":"NULL"));
399
400 printf(" %s_function,\n",safe(tagsx[i]->type));
401
402 printf(" {");
403 for(j=0;j<tagsx[i]->nsubtagsx;j++)
404 printf("&%s_tag,",safe(tagsx[i]->subtagsx[j]->type));
405 printf("NULL}};\n");
406 }
407
408 /* Print the functions */
409
410 printf("\n");
411 printf("\n");
412 printf("/* The XML tag processing functions */\n");
413
414 for(i=0;i<ntagsx;i++)
415 {
416 printf("\n");
417 printf("\n");
418 printf("/*++++++++++++++++++++++++++++++++++++++\n");
419 if(i==0) /* XML tag */
420 printf(" The function that is called when the XML declaration is seen\n");
421 else
422 printf(" The function that is called when the %s XSD type is seen\n",tagsx[i]->type);
423 printf("\n");
424 printf(" int %s_function Returns 0 if no error occured or something else otherwise.\n",safe(tagsx[i]->type));
425 printf("\n");
426 printf(" const char *_tag_ Set to the name of the element tag that triggered this function call.\n");
427 printf("\n");
428 printf(" int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.\n");
429 for(j=0;j<tagsx[i]->nattributes;j++)
430 {
431 printf("\n");
432 printf(" const char *%s The contents of the '%s' attribute (or NULL if not defined).\n",safe(tagsx[i]->attributes[j]),tagsx[i]->attributes[j]);
433 }
434 printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
435 printf("\n");
436
437 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
438
439 for(j=0;j<tagsx[i]->nattributes;j++)
440 printf(",const char *%s",safe(tagsx[i]->attributes[j]));
441
442 printf(")\n");
443
444 printf("{\n");
445
446 if(i==(ntagsx-1)) /* XML tag */
447 {
448 printf(" printf(\"<?%%s\",_tag_);\n");
449 for(j=0;j<tagsx[i]->nattributes;j++)
450 {
451 char *safename=safe(tagsx[i]->attributes[j]);
452 printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename);
453 }
454 printf(" printf(\" ?>\\n\");\n");
455 }
456 else
457 {
458 printf(" printf(\"<%%s%%s\",(_type_==XMLPARSE_TAG_END)?\"/\":\"\",_tag_);\n");
459 for(j=0;j<tagsx[i]->nattributes;j++)
460 {
461 char *safename=safe(tagsx[i]->attributes[j]);
462 printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename);
463 }
464 printf(" printf(\"%%s>\\n\",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?\" /\":\"\");\n");
465 }
466
467 printf(" return(0);\n");
468 printf("}\n");
469 }
470
471 /* Print the main function */
472
473 printf("\n");
474 printf("\n");
475 printf("/*++++++++++++++++++++++++++++++++++++++\n");
476 printf(" A skeleton XML parser.\n");
477 printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
478 printf("\n");
479 printf("int main(int argc,char **argv)\n");
480 printf("{\n");
481 printf(" if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_WARN))\n");
482 printf(" return(1);\n");
483 printf(" else\n");
484 printf(" return(0);\n");
485 printf("}\n");
486
487 return(0);
488 }
489
490
491 /*++++++++++++++++++++++++++++++++++++++
492 A function to return a safe C identifier from an XML tag or attribute name.
493
494 char *safe Returns the safe name in a private string (only use once).
495
496 const char *name The name to convert.
497 ++++++++++++++++++++++++++++++++++++++*/
498
499 static char *safe(const char *name)
500 {
501 static char *safe=NULL; /* static allocation of return value */
502 int i;
503
504 safe=realloc(safe,strlen(name)+1);
505
506 for(i=0;name[i];i++)
507 if(isalnum(name[i]))
508 safe[i]=name[i];
509 else
510 safe[i]='_';
511
512 safe[i]=0;
513
514 return(safe);
515 }

Properties

Name Value
cvs:description An XML parser that can convert XML Scheme description XML files into a skeleton source code file that works with the generic XML parser.