Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1784 - (hide 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 amb 334 /***************************************
2 amb 373 $Header: /home/amb/CVS/routino/src/xml/xsd-to-xmlparser.c,v 1.10 2010-04-23 18:41:20 amb Exp $
3 amb 334
4     An XML parser for simplified XML Schema Definitions to create XML parser skeletons.
5    
6     Part of the Routino routing software.
7     ******************/ /******************
8 amb 1680 This file Copyright 2010-2015 Andrew M. Bishop
9 amb 334
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 amb 1680 #if !defined(_MSC_VER)
27 amb 1192 #include <unistd.h>
28 amb 1680 #endif
29 amb 334 #include <ctype.h>
30     #include <stdlib.h>
31     #include <string.h>
32    
33     #include "xmlparse.h"
34    
35    
36 amb 367 /*+ 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 amb 334 /* The local variables and functions */
55    
56 amb 367 int ntagsx=0;
57     xmltagx **tagsx=NULL;
58 amb 334 char *currenttype=NULL;
59    
60     static char *safe(const char *name);
61    
62    
63     /* The XML tag processing function prototypes */
64    
65 amb 373 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 amb 1204 static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs);
68 amb 373 static int complexType_function(const char *_tag_,int _type_,const char *name);
69 amb 1204 static int sequenceType_function(const char *_tag_,int _type_);
70 amb 373 static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type);
71 amb 334
72    
73 amb 1204 /* The XML tag definitions (forward declarations) */
74 amb 334
75 amb 1719 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 amb 1204
82    
83     /* The XML tag definition values */
84    
85     /*+ The complete set of tags at the top level. +*/
86 amb 1719 static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL};
87 amb 1204
88     /*+ The xmlDeclaration type tag. +*/
89 amb 1719 static const xmltag xmlDeclaration_tag=
90 amb 1204 {"xml",
91     2, {"version","encoding"},
92     xmlDeclaration_function,
93     {NULL}};
94    
95     /*+ The schemaType type tag. +*/
96 amb 1719 static const xmltag schemaType_tag=
97 amb 1204 {"xsd:schema",
98     2, {"elementFormDefault","xmlns:xsd"},
99     schemaType_function,
100     {&elementType_tag,&complexType_tag,NULL}};
101    
102 amb 334 /*+ The elementType type tag. +*/
103 amb 1719 static const xmltag elementType_tag=
104 amb 339 {"xsd:element",
105 amb 355 4, {"name","type","minOccurs","maxOccurs"},
106 amb 367 elementType_function,
107 amb 339 {NULL}};
108 amb 334
109 amb 1204 /*+ The complexType type tag. +*/
110 amb 1719 static const xmltag complexType_tag=
111 amb 1204 {"xsd:complexType",
112     1, {"name"},
113     complexType_function,
114     {&sequenceType_tag,&attributeType_tag,NULL}};
115    
116 amb 334 /*+ The sequenceType type tag. +*/
117 amb 1719 static const xmltag sequenceType_tag=
118 amb 339 {"xsd:sequence",
119 amb 355 0, {NULL},
120 amb 367 sequenceType_function,
121     {&elementType_tag,NULL}};
122 amb 334
123     /*+ The attributeType type tag. +*/
124 amb 1719 static const xmltag attributeType_tag=
125 amb 339 {"xsd:attribute",
126 amb 355 2, {"name","type"},
127 amb 367 attributeType_function,
128 amb 339 {NULL}};
129 amb 334
130 amb 339
131 amb 1204 /* The XML tag processing functions */
132 amb 339
133 amb 334
134 amb 1204 /*++++++++++++++++++++++++++++++++++++++
135     The function that is called when the XML declaration is seen
136 amb 334
137 amb 1204 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
138 amb 334
139 amb 1204 const char *_tag_ Set to the name of the element tag that triggered this function call.
140 amb 334
141 amb 1204 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 amb 334
143 amb 1204 const char *version The contents of the 'version' attribute (or NULL if not defined).
144 amb 334
145 amb 1204 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 amb 334 /*++++++++++++++++++++++++++++++++++++++
165 amb 1204 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 amb 344 The function that is called when the elementType XSD type is seen
186 amb 334
187 amb 367 int elementType_function Returns 0 if no error occured or something else otherwise.
188 amb 363
189 amb 373 const char *_tag_ Set to the name of the element tag that triggered this function call.
190    
191 amb 344 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 amb 355 const char *name The contents of the 'name' attribute (or NULL if not defined).
194 amb 334
195 amb 355 const char *type The contents of the 'type' attribute (or NULL if not defined).
196 amb 334
197 amb 355 const char *minOccurs The contents of the 'minOccurs' attribute (or NULL if not defined).
198 amb 334
199 amb 355 const char *maxOccurs The contents of the 'maxOccurs' attribute (or NULL if not defined).
200 amb 334 ++++++++++++++++++++++++++++++++++++++*/
201    
202 amb 373 static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs)
203 amb 334 {
204 amb 367 xmltagx *tagx=NULL;
205     int i;
206 amb 334
207 amb 344 if(_type_==XMLPARSE_TAG_END)
208 amb 363 return(0);
209 amb 344
210 amb 367 for(i=0;i<ntagsx;i++)
211     if(!strcmp(type,tagsx[i]->type) && !strcmp(name,tagsx[i]->name))
212     tagx=tagsx[i];
213 amb 334
214 amb 367 if(!tagx)
215 amb 334 {
216 amb 367 ntagsx++;
217     tagsx=(xmltagx**)realloc((void*)tagsx,ntagsx*sizeof(xmltagx*));
218 amb 334
219 amb 367 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 amb 334
223 amb 367 tagx=tagsx[ntagsx-1];
224 amb 334 }
225    
226     if(!currenttype)
227 amb 363 return(0);
228 amb 334
229 amb 367 for(i=0;i<ntagsx;i++)
230     if(!strcmp(tagsx[i]->type,currenttype))
231 amb 339 {
232 amb 367 tagsx[i]->subtagsx[tagsx[i]->nsubtagsx]=tagx;
233     tagsx[i]->nsubtagsx++;
234 amb 339
235 amb 367 if(tagsx[i]->nsubtagsx==XMLPARSE_MAX_SUBTAGS)
236 amb 339 {fprintf(stderr,"Too many subtags seen for type '%s'.\n",currenttype); exit(1);}
237     }
238 amb 363
239     return(0);
240 amb 334 }
241    
242    
243     /*++++++++++++++++++++++++++++++++++++++
244 amb 1204 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 amb 344 The function that is called when the sequenceType XSD type is seen
268    
269 amb 367 int sequenceType_function Returns 0 if no error occured or something else otherwise.
270 amb 363
271 amb 373 const char *_tag_ Set to the name of the element tag that triggered this function call.
272    
273 amb 344 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 amb 334 ++++++++++++++++++++++++++++++++++++++*/
275    
276 amb 373 static int sequenceType_function(const char *_tag_,int _type_)
277 amb 334 {
278 amb 363 return(0);
279 amb 334 }
280    
281    
282     /*++++++++++++++++++++++++++++++++++++++
283 amb 344 The function that is called when the attributeType XSD type is seen
284 amb 334
285 amb 367 int attributeType_function Returns 0 if no error occured or something else otherwise.
286 amb 363
287 amb 373 const char *_tag_ Set to the name of the element tag that triggered this function call.
288    
289 amb 344 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 amb 355 const char *name The contents of the 'name' attribute (or NULL if not defined).
292 amb 334
293 amb 355 const char *type The contents of the 'type' attribute (or NULL if not defined).
294 amb 334 ++++++++++++++++++++++++++++++++++++++*/
295    
296 amb 373 static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type)
297 amb 334 {
298 amb 367 int i;
299 amb 334
300 amb 344 if(_type_==XMLPARSE_TAG_END)
301 amb 363 return(0);
302 amb 344
303 amb 367 for(i=0;i<ntagsx;i++)
304     if(!strcmp(tagsx[i]->type,currenttype))
305 amb 339 {
306 amb 367 tagsx[i]->attributes[tagsx[i]->nattributes]=strcpy(malloc(strlen(name)+1),name);
307     tagsx[i]->nattributes++;
308 amb 339
309 amb 367 if(tagsx[i]->nattributes==XMLPARSE_MAX_ATTRS)
310 amb 339 {fprintf(stderr,"Too many attributes seen for type '%s'.\n",currenttype); exit(1);}
311     }
312 amb 363
313     return(0);
314 amb 334 }
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 amb 1204 int i,j;
324 amb 334
325 amb 1204 /* Parse the XSD file */
326    
327 amb 1192 if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE))
328 amb 349 {
329     fprintf(stderr,"Cannot parse XML file - exiting.\n");
330     exit(1);
331     }
332 amb 334
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 amb 1680 printf("#if !defined(_MSC_VER)\n");
344 amb 1192 printf("#include <unistd.h>\n");
345 amb 1680 printf("#endif\n");
346 amb 334 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 amb 1204 for(i=0;i<ntagsx;i++)
357 amb 334 {
358 amb 373 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
359 amb 334
360 amb 367 for(j=0;j<tagsx[i]->nattributes;j++)
361     printf(",const char *%s",safe(tagsx[i]->attributes[j]));
362 amb 334
363     printf(");\n");
364     }
365    
366     /* Print the xmltag variables */
367    
368     printf("\n");
369     printf("\n");
370 amb 1204 printf("/* The XML tag definitions (forward declarations) */\n");
371 amb 334
372 amb 1204 printf("\n");
373    
374 amb 367 for(i=0;i<ntagsx;i++)
375 amb 1719 printf("static const xmltag %s_tag;\n",safe(tagsx[i]->type));
376 amb 1204
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 amb 1719 printf("static const xmltag * const xml_toplevel_tags[]={");
384 amb 1204 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 amb 334 {
390     printf("\n");
391 amb 367 printf("/*+ The %s type tag. +*/\n",tagsx[i]->type);
392 amb 1719 printf("static const xmltag %s_tag=\n",safe(tagsx[i]->type));
393 amb 367 printf(" {\"%s\",\n",tagsx[i]->name);
394 amb 334
395 amb 367 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 amb 334
400 amb 367 printf(" %s_function,\n",safe(tagsx[i]->type));
401 amb 334
402 amb 339 printf(" {");
403 amb 367 for(j=0;j<tagsx[i]->nsubtagsx;j++)
404     printf("&%s_tag,",safe(tagsx[i]->subtagsx[j]->type));
405 amb 334 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 amb 367 for(i=0;i<ntagsx;i++)
415 amb 334 {
416     printf("\n");
417     printf("\n");
418     printf("/*++++++++++++++++++++++++++++++++++++++\n");
419 amb 1204 if(i==0) /* XML tag */
420 amb 367 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 amb 344 printf("\n");
424 amb 367 printf(" int %s_function Returns 0 if no error occured or something else otherwise.\n",safe(tagsx[i]->type));
425 amb 363 printf("\n");
426 amb 373 printf(" const char *_tag_ Set to the name of the element tag that triggered this function call.\n");
427     printf("\n");
428 amb 344 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 amb 367 for(j=0;j<tagsx[i]->nattributes;j++)
430 amb 355 {
431     printf("\n");
432 amb 367 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 amb 355 }
434 amb 334 printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
435     printf("\n");
436    
437 amb 373 printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type));
438 amb 334
439 amb 367 for(j=0;j<tagsx[i]->nattributes;j++)
440     printf(",const char *%s",safe(tagsx[i]->attributes[j]));
441 amb 334
442     printf(")\n");
443    
444     printf("{\n");
445    
446 amb 367 if(i==(ntagsx-1)) /* XML tag */
447 amb 349 {
448 amb 373 printf(" printf(\"<?%%s\",_tag_);\n");
449 amb 367 for(j=0;j<tagsx[i]->nattributes;j++)
450 amb 355 {
451 amb 367 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 amb 355 }
454 amb 352 printf(" printf(\" ?>\\n\");\n");
455 amb 349 }
456     else
457     {
458 amb 373 printf(" printf(\"<%%s%%s\",(_type_==XMLPARSE_TAG_END)?\"/\":\"\",_tag_);\n");
459 amb 367 for(j=0;j<tagsx[i]->nattributes;j++)
460 amb 355 {
461 amb 367 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 amb 355 }
464 amb 352 printf(" printf(\"%%s>\\n\",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?\" /\":\"\");\n");
465 amb 349 }
466 amb 334
467 amb 363 printf(" return(0);\n");
468 amb 334 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 amb 1192 printf(" if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_WARN))\n");
482 amb 349 printf(" return(1);\n");
483     printf(" else\n");
484     printf(" return(0);\n");
485 amb 334 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 amb 1784 static char *safe=NULL; /* static allocation of return value */
502 amb 334 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.