Routino SVN Repository Browser

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

ViewVC logotype

Contents of /branches/destination-access/src/xml/xsd-to-xmlparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1984 - (show annotations) (download) (as text)
Sun Apr 7 16:24:19 2019 UTC (5 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 16621 byte(s)
Merge from trunk (robustness and sanitizer findings).

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, 2019 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
159 if(currenttype)
160 free(currenttype);
161 currenttype=NULL;
162
163 return(0);
164 }
165
166
167 /*++++++++++++++++++++++++++++++++++++++
168 The function that is called when the schemaType XSD type is seen
169
170 int schemaType_function Returns 0 if no error occured or something else otherwise.
171
172 const char *_tag_ Set to the name of the element tag that triggered this function call.
173
174 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
175
176 const char *elementFormDefault The contents of the 'elementFormDefault' attribute (or NULL if not defined).
177
178 const char *xmlns_xsd The contents of the 'xmlns:xsd' attribute (or NULL if not defined).
179 ++++++++++++++++++++++++++++++++++++++*/
180
181 static int schemaType_function(const char *_tag_,int _type_,const char *elementFormDefault,const char *xmlns_xsd)
182 {
183 return(0);
184 }
185
186
187 /*++++++++++++++++++++++++++++++++++++++
188 The function that is called when the elementType XSD type is seen
189
190 int elementType_function Returns 0 if no error occured or something else otherwise.
191
192 const char *_tag_ Set to the name of the element tag that triggered this function call.
193
194 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
195
196 const char *name The contents of the 'name' attribute (or NULL if not defined).
197
198 const char *type The contents of the 'type' attribute (or NULL if not defined).
199
200 const char *minOccurs The contents of the 'minOccurs' attribute (or NULL if not defined).
201
202 const char *maxOccurs The contents of the 'maxOccurs' attribute (or NULL if not defined).
203 ++++++++++++++++++++++++++++++++++++++*/
204
205 static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs)
206 {
207 xmltagx *tagx=NULL;
208 int i;
209
210 if(_type_==XMLPARSE_TAG_END)
211 return(0);
212
213 for(i=0;i<ntagsx;i++)
214 if(!strcmp(type,tagsx[i]->type) && !strcmp(name,tagsx[i]->name))
215 tagx=tagsx[i];
216
217 if(!tagx)
218 {
219 ntagsx++;
220 tagsx=(xmltagx**)realloc((void*)tagsx,ntagsx*sizeof(xmltagx*));
221
222 tagsx[ntagsx-1]=(xmltagx*)calloc(1,sizeof(xmltagx));
223 tagsx[ntagsx-1]->name=strcpy(malloc(strlen(name)+1),name);
224 tagsx[ntagsx-1]->type=strcpy(malloc(strlen(type)+1),type);
225
226 tagx=tagsx[ntagsx-1];
227 }
228
229 if(!currenttype)
230 return(0);
231
232 for(i=0;i<ntagsx;i++)
233 if(!strcmp(tagsx[i]->type,currenttype))
234 {
235 tagsx[i]->subtagsx[tagsx[i]->nsubtagsx]=tagx;
236 tagsx[i]->nsubtagsx++;
237
238 if(tagsx[i]->nsubtagsx==XMLPARSE_MAX_SUBTAGS)
239 {fprintf(stderr,"Too many subtags seen for type '%s'.\n",currenttype); exit(1);}
240 }
241
242 return(0);
243 }
244
245
246 /*++++++++++++++++++++++++++++++++++++++
247 The function that is called when the complexType XSD type is seen
248
249 int complexType_function Returns 0 if no error occured or something else otherwise.
250
251 const char *_tag_ Set to the name of the element tag that triggered this function call.
252
253 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
254
255 const char *name The contents of the 'name' attribute (or NULL if not defined).
256 ++++++++++++++++++++++++++++++++++++++*/
257
258 static int complexType_function(const char *_tag_,int _type_,const char *name)
259 {
260 if(_type_==XMLPARSE_TAG_END)
261 return(0);
262
263 currenttype=strcpy(realloc(currenttype,strlen(name)+1),name);
264
265 return(0);
266 }
267
268
269 /*++++++++++++++++++++++++++++++++++++++
270 The function that is called when the sequenceType XSD type is seen
271
272 int sequenceType_function Returns 0 if no error occured or something else otherwise.
273
274 const char *_tag_ Set to the name of the element tag that triggered this function call.
275
276 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
277 ++++++++++++++++++++++++++++++++++++++*/
278
279 static int sequenceType_function(const char *_tag_,int _type_)
280 {
281 return(0);
282 }
283
284
285 /*++++++++++++++++++++++++++++++++++++++
286 The function that is called when the attributeType XSD type is seen
287
288 int attributeType_function Returns 0 if no error occured or something else otherwise.
289
290 const char *_tag_ Set to the name of the element tag that triggered this function call.
291
292 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
293
294 const char *name The contents of the 'name' attribute (or NULL if not defined).
295
296 const char *type The contents of the 'type' attribute (or NULL if not defined).
297 ++++++++++++++++++++++++++++++++++++++*/
298
299 static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type)
300 {
301 int i;
302
303 if(_type_==XMLPARSE_TAG_END)
304 return(0);
305
306 for(i=0;i<ntagsx;i++)
307 if(!strcmp(tagsx[i]->type,currenttype))
308 {
309 tagsx[i]->attributes[tagsx[i]->nattributes]=strcpy(malloc(strlen(name)+1),name);
310 tagsx[i]->nattributes++;
311
312 if(tagsx[i]->nattributes==XMLPARSE_MAX_ATTRS)
313 {fprintf(stderr,"Too many attributes seen for type '%s'.\n",currenttype); exit(1);}
314 }
315
316 return(0);
317 }
318
319
320 /*++++++++++++++++++++++++++++++++++++++
321 The XML Schema Definition XML parser and C program generator.
322 ++++++++++++++++++++++++++++++++++++++*/
323
324 int main(int argc,char **argv)
325 {
326 int i,j;
327
328 /* Parse the XSD file */
329
330 if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE))
331 {
332 fprintf(stderr,"Cannot parse XML file - exiting.\n");
333 exit(1);
334 }
335
336 /* Print the header */
337
338 printf("/***************************************\n");
339 printf(" An automatically generated skeleton XML parser.\n");
340 printf("\n");
341 printf(" Automatically generated by xsd-to-xmlparser.\n");
342 printf(" ***************************************/\n");
343 printf("\n");
344 printf("\n");
345 printf("#include <stdio.h>\n");
346 printf("#if !defined(_MSC_VER)\n");
347 printf("#include <unistd.h>\n");
348 printf("#endif\n");
349 printf("\n");
350 printf("#include \"xmlparse.h\"\n");
351
352 /* Print the function prototypes */
353
354 printf("\n");
355 printf("\n");
356 printf("/* The XML tag processing function prototypes */\n");
357 printf("\n");
358
359 for(i=0;i<ntagsx;i++)
360 {
361 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
362
363 for(j=0;j<tagsx[i]->nattributes;j++)
364 printf(",const char *%s",safe(tagsx[i]->attributes[j]));
365
366 printf(");\n");
367 }
368
369 /* Print the xmltag variables */
370
371 printf("\n");
372 printf("\n");
373 printf("/* The XML tag definitions (forward declarations) */\n");
374
375 printf("\n");
376
377 for(i=0;i<ntagsx;i++)
378 printf("static const xmltag %s_tag;\n",safe(tagsx[i]->type));
379
380 printf("\n");
381 printf("\n");
382 printf("/* The XML tag definition values */\n");
383
384 printf("\n");
385 printf("/*+ The complete set of tags at the top level. +*/\n");
386 printf("static const xmltag * const xml_toplevel_tags[]={");
387 printf("&%s_tag,",safe(tagsx[0]->type));
388 printf("&%s_tag,",safe(tagsx[1]->type));
389 printf("NULL};\n");
390
391 for(i=0;i<ntagsx;i++)
392 {
393 printf("\n");
394 printf("/*+ The %s type tag. +*/\n",tagsx[i]->type);
395 printf("static const xmltag %s_tag=\n",safe(tagsx[i]->type));
396 printf(" {\"%s\",\n",tagsx[i]->name);
397
398 printf(" %d, {",tagsx[i]->nattributes);
399 for(j=0;j<tagsx[i]->nattributes;j++)
400 printf("%s\"%s\"",(j?",":""),tagsx[i]->attributes[j]);
401 printf("%s},\n",(tagsx[i]->nattributes?"":"NULL"));
402
403 printf(" %s_function,\n",safe(tagsx[i]->type));
404
405 printf(" {");
406 for(j=0;j<tagsx[i]->nsubtagsx;j++)
407 printf("&%s_tag,",safe(tagsx[i]->subtagsx[j]->type));
408 printf("NULL}};\n");
409 }
410
411 /* Print the functions */
412
413 printf("\n");
414 printf("\n");
415 printf("/* The XML tag processing functions */\n");
416
417 for(i=0;i<ntagsx;i++)
418 {
419 printf("\n");
420 printf("\n");
421 printf("/*++++++++++++++++++++++++++++++++++++++\n");
422 if(i==0) /* XML tag */
423 printf(" The function that is called when the XML declaration is seen\n");
424 else
425 printf(" The function that is called when the %s XSD type is seen\n",tagsx[i]->type);
426 printf("\n");
427 printf(" int %s_function Returns 0 if no error occured or something else otherwise.\n",safe(tagsx[i]->type));
428 printf("\n");
429 printf(" const char *_tag_ Set to the name of the element tag that triggered this function call.\n");
430 printf("\n");
431 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");
432 for(j=0;j<tagsx[i]->nattributes;j++)
433 {
434 printf("\n");
435 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]);
436 }
437 printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
438 printf("\n");
439
440 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
441
442 for(j=0;j<tagsx[i]->nattributes;j++)
443 printf(",const char *%s",safe(tagsx[i]->attributes[j]));
444
445 printf(")\n");
446
447 printf("{\n");
448
449 if(i==(ntagsx-1)) /* XML tag */
450 {
451 printf(" printf(\"<?%%s\",_tag_);\n");
452 for(j=0;j<tagsx[i]->nattributes;j++)
453 {
454 char *safename=safe(tagsx[i]->attributes[j]);
455 printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename);
456 }
457 printf(" printf(\" ?>\\n\");\n");
458 }
459 else
460 {
461 printf(" printf(\"<%%s%%s\",(_type_==XMLPARSE_TAG_END)?\"/\":\"\",_tag_);\n");
462 for(j=0;j<tagsx[i]->nattributes;j++)
463 {
464 char *safename=safe(tagsx[i]->attributes[j]);
465 printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename);
466 }
467 printf(" printf(\"%%s>\\n\",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?\" /\":\"\");\n");
468 }
469
470 printf(" return(0);\n");
471 printf("}\n");
472 }
473
474 /* Print the main function */
475
476 printf("\n");
477 printf("\n");
478 printf("/*++++++++++++++++++++++++++++++++++++++\n");
479 printf(" A skeleton XML parser.\n");
480 printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
481 printf("\n");
482 printf("int main(int argc,char **argv)\n");
483 printf("{\n");
484 printf(" if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_WARN))\n");
485 printf(" return(1);\n");
486 printf(" else\n");
487 printf(" return(0);\n");
488 printf("}\n");
489
490 return(0);
491 }
492
493
494 /*++++++++++++++++++++++++++++++++++++++
495 A function to return a safe C identifier from an XML tag or attribute name.
496
497 char *safe Returns the safe name in a private string (only use once).
498
499 const char *name The name to convert.
500 ++++++++++++++++++++++++++++++++++++++*/
501
502 static char *safe(const char *name)
503 {
504 static char *safe=NULL; /* static allocation of return value */
505 int i;
506
507 safe=realloc(safe,strlen(name)+1);
508
509 for(i=0;name[i];i++)
510 if(isalnum(name[i]))
511 safe[i]=name[i];
512 else
513 safe[i]='_';
514
515 safe[i]=0;
516
517 return(safe);
518 }

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.