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 339 - (hide annotations) (download) (as text)
Mon Mar 29 18:17:20 2010 UTC (15 years ago) by amb
File MIME type: text/x-csrc
File size: 11918 byte(s)
Add the option to ignore unknown attributes.
Print out the skeleton file using static functions and variables.

1 amb 334 /***************************************
2 amb 339 $Header: /home/amb/CVS/routino/src/xml/xsd-to-xmlparser.c,v 1.2 2010-03-29 18:17: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     This file Copyright 2010 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     #include <ctype.h>
27     #include <stdlib.h>
28     #include <string.h>
29    
30     #include "xmlparse.h"
31    
32    
33     /* The local variables and functions */
34    
35     int ntags=0;
36     xmltag **tags=NULL;
37     char **types=NULL;
38     char *currenttype=NULL;
39    
40     static char *safe(const char *name);
41    
42    
43     /* The XML tag processing function prototypes */
44    
45 amb 339 static void _xml_function(char *version,char *encoding);
46     static void xsd_schema_function(char *elementFormDefault,char *xmlns_xsd);
47     static void xsd_complexType_function(char *name);
48     static void xsd_attribute_function(char *name,char *type);
49     static void xsd_sequence_function(void);
50     static void xsd_element_function(char *name,char *type,char *minOccurs,char *maxOccurs);
51 amb 334
52    
53     /* The XML tag definitions */
54    
55     /*+ The elementType type tag. +*/
56 amb 339 static xmltag xsd_element_tag=
57     {"xsd:element",
58     {"name","type","minOccurs","maxOccurs",NULL},
59     xsd_element_function,
60     {NULL}};
61 amb 334
62     /*+ The sequenceType type tag. +*/
63 amb 339 static xmltag xsd_sequence_tag=
64     {"xsd:sequence",
65     {NULL},
66     xsd_sequence_function,
67     {&xsd_element_tag,NULL}};
68 amb 334
69     /*+ The attributeType type tag. +*/
70 amb 339 static xmltag xsd_attribute_tag=
71     {"xsd:attribute",
72     {"name","type",NULL},
73     xsd_attribute_function,
74     {NULL}};
75 amb 334
76 amb 339 /*+ The complexType type tag. +*/
77     static xmltag xsd_complexType_tag=
78     {"xsd:complexType",
79     {"name",NULL},
80     xsd_complexType_function,
81     {&xsd_sequence_tag,&xsd_attribute_tag,NULL}};
82    
83     /*+ The schemaType type tag. +*/
84     static xmltag xsd_schema_tag=
85     {"xsd:schema",
86     {"elementFormDefault","xmlns:xsd",NULL},
87     xsd_schema_function,
88     {&xsd_element_tag,&xsd_complexType_tag,NULL}};
89    
90 amb 334 /*+ The ?xmlType type tag. +*/
91 amb 339 static xmltag _xml_tag=
92     {"?xml",
93     {"version","encoding",NULL},
94     _xml_function,
95     {NULL}};
96 amb 334
97    
98     /*+ The complete set of tags at the top level. +*/
99 amb 339 static xmltag *xml_toplevel_tags[]={&_xml_tag,&xsd_schema_tag,NULL};
100 amb 334
101    
102     /* The XML tag processing functions */
103    
104    
105     /*++++++++++++++++++++++++++++++++++++++
106 amb 339 The function that is called when the elementType type is seen
107 amb 334
108     char *name The contents of the 'name' attribute (or NULL if not defined).
109    
110     char *type The contents of the 'type' attribute (or NULL if not defined).
111    
112     char *minOccurs The contents of the 'minOccurs' attribute (or NULL if not defined).
113    
114     char *maxOccurs The contents of the 'maxOccurs' attribute (or NULL if not defined).
115     ++++++++++++++++++++++++++++++++++++++*/
116    
117 amb 339 static void xsd_element_function(char *name,char *type,char *minOccurs,char *maxOccurs)
118 amb 334 {
119     xmltag *tag=NULL;
120     int i,j;
121    
122     for(i=0;i<ntags;i++)
123     if(!strcmp(type,types[i]) && !strcmp(name,tags[i]->name))
124     tag=tags[i];
125    
126     if(!tag)
127     {
128     ntags++;
129     tags=(xmltag**)realloc((void*)tags,ntags*sizeof(xmltag*));
130     types=(char**)realloc((void*)types,ntags*sizeof(char*));
131    
132     tags[ntags-1]=(xmltag*)calloc(1,sizeof(xmltag));
133     tags[ntags-1]->name=strcpy(malloc(strlen(name)+1),name);
134     types[ntags-1]=strcpy(malloc(strlen(type)+1),type);
135    
136     tag=tags[ntags-1];
137     }
138    
139     if(!currenttype)
140     return;
141    
142     for(i=0;i<ntags;i++)
143     if(!strcmp(types[i],currenttype))
144 amb 339 {
145 amb 334 for(j=0;j<XMLPARSE_MAX_SUBTAGS;j++)
146     if(!tags[i]->subtags[j])
147     {
148     tags[i]->subtags[j]=tag;
149     break;
150     }
151 amb 339
152     if(j==XMLPARSE_MAX_SUBTAGS)
153     {fprintf(stderr,"Too many subtags seen for type '%s'.\n",currenttype); exit(1);}
154     }
155 amb 334 }
156    
157    
158     /*++++++++++++++++++++++++++++++++++++++
159 amb 339 The function that is called when the sequenceType type is seen
160 amb 334 ++++++++++++++++++++++++++++++++++++++*/
161    
162 amb 339 static void xsd_sequence_function(void)
163 amb 334 {
164     }
165    
166    
167     /*++++++++++++++++++++++++++++++++++++++
168 amb 339 The function that is called when the attributeType type is seen
169 amb 334
170     char *name The contents of the 'name' attribute (or NULL if not defined).
171    
172     char *type The contents of the 'type' attribute (or NULL if not defined).
173     ++++++++++++++++++++++++++++++++++++++*/
174    
175 amb 339 static void xsd_attribute_function(char *name,char *type)
176 amb 334 {
177     int i,j;
178    
179     for(i=0;i<ntags;i++)
180     if(!strcmp(types[i],currenttype))
181 amb 339 {
182 amb 334 for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
183     if(!tags[i]->attributes[j])
184     {
185     tags[i]->attributes[j]=strcpy(malloc(strlen(name)+1),name);
186     break;
187     }
188 amb 339
189     if(j==XMLPARSE_MAX_ATTRS)
190     {fprintf(stderr,"Too many attributes seen for type '%s'.\n",currenttype); exit(1);}
191     }
192 amb 334 }
193    
194    
195     /*++++++++++++++++++++++++++++++++++++++
196 amb 339 The function that is called when the complexType type is seen
197 amb 334
198     char *name The contents of the 'name' attribute (or NULL if not defined).
199     ++++++++++++++++++++++++++++++++++++++*/
200    
201 amb 339 static void xsd_complexType_function(char *name)
202 amb 334 {
203     currenttype=strcpy(realloc(currenttype,strlen(name)+1),name);
204     }
205    
206    
207     /*++++++++++++++++++++++++++++++++++++++
208 amb 339 The function that is called when the schemaType type is seen
209 amb 334
210     char *elementFormDefault The contents of the 'elementFormDefault' attribute (or NULL if not defined).
211    
212     char *xmlns_xsd The contents of the 'xmlns:xsd' attribute (or NULL if not defined).
213     ++++++++++++++++++++++++++++++++++++++*/
214    
215 amb 339 static void xsd_schema_function(char *elementFormDefault,char *xmlns_xsd)
216 amb 334 {
217     }
218    
219    
220     /*++++++++++++++++++++++++++++++++++++++
221     The function that is called when the ?xmlType type is seen
222    
223     char *version The contents of the 'version' attribute (or NULL if not defined).
224    
225     char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
226     ++++++++++++++++++++++++++++++++++++++*/
227    
228 amb 339 static void _xml_function(char *version,char *encoding)
229 amb 334 {
230     }
231    
232    
233     /*++++++++++++++++++++++++++++++++++++++
234     The XML Schema Definition XML parser and C program generator.
235     ++++++++++++++++++++++++++++++++++++++*/
236    
237     int main(int argc,char **argv)
238     {
239     int i,j,k;
240    
241 amb 339 ParseXML(stdin,xml_toplevel_tags,0);
242 amb 334
243     /* Sort the tags */
244    
245     sorttags:
246    
247     for(i=0;i<ntags;i++)
248     {
249     for(j=0;j<XMLPARSE_MAX_SUBTAGS;j++)
250     if(tags[i]->subtags[j])
251     {
252     for(k=0;k<XMLPARSE_MAX_SUBTAGS;k++)
253     if(tags[i]->subtags[j]==tags[k])
254     break;
255    
256     if(i<k)
257     {
258 amb 339 xmltag *tempx=tags[i];
259     char *tempc=types[i];
260    
261 amb 334 tags[i]=tags[k];
262 amb 339 types[i]=types[k];
263    
264     tags[k]=tempx;
265     types[k]=tempc;
266    
267 amb 334 goto sorttags;
268     }
269     }
270     }
271    
272     currenttype=NULL;
273     xsd_element_function("?xml","?xmlType",NULL,NULL);
274     xsd_complexType_function("?xmlType");
275     xsd_attribute_function("version",NULL);
276     xsd_attribute_function("encoding",NULL);
277    
278     /* Print the header */
279    
280     printf("/***************************************\n");
281     printf(" An automatically generated skeleton XML parser.\n");
282     printf("\n");
283     printf(" Automatically generated by xsd-to-xmlparser.\n");
284     printf(" ***************************************/\n");
285     printf("\n");
286     printf("\n");
287     printf("#include <stdio.h>\n");
288     printf("\n");
289     printf("#include \"xmlparse.h\"\n");
290    
291     /* Print the function prototypes */
292    
293     printf("\n");
294     printf("\n");
295     printf("/* The XML tag processing function prototypes */\n");
296     printf("\n");
297    
298     for(i=ntags-1;i>=0;i--)
299     {
300 amb 339 printf("static void %s_function(",safe(tags[i]->name));
301 amb 334
302     for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
303     if(tags[i]->attributes[j])
304     printf("%schar *%s",(j?",":""),safe(tags[i]->attributes[j]));
305    
306     if(!tags[i]->attributes[0])
307     printf("void");
308    
309     printf(");\n");
310     }
311    
312     /* Print the xmltag variables */
313    
314     printf("\n");
315     printf("\n");
316     printf("/* The XML tag definitions */\n");
317    
318     for(i=0;i<ntags;i++)
319     {
320     printf("\n");
321     printf("/*+ The %s type tag. +*/\n",types[i]);
322 amb 339 printf("static xmltag %s_tag=\n",safe(tags[i]->name));
323     printf(" {\"%s\",\n",tags[i]->name);
324 amb 334
325 amb 339 printf(" {");
326 amb 334 for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
327     if(tags[i]->attributes[j])
328     printf("\"%s\",",tags[i]->attributes[j]);
329     printf("NULL},\n");
330    
331 amb 339 printf(" %s_function,\n",safe(tags[i]->name));
332 amb 334
333 amb 339 printf(" {");
334 amb 334 for(j=0;j<XMLPARSE_MAX_SUBTAGS;j++)
335     if(tags[i]->subtags[j])
336     printf("&%s_tag,",safe(tags[i]->subtags[j]->name));
337     printf("NULL}};\n");
338     }
339    
340     printf("\n");
341     printf("\n");
342     printf("/*+ The complete set of tags at the top level. +*/\n");
343 amb 339 printf("static xmltag *xml_toplevel_tags[]={");
344 amb 334 printf("&%s_tag,",safe(tags[ntags-1]->name));
345     printf("&%s_tag,",safe(tags[ntags-2]->name));
346     printf("NULL};\n");
347    
348     /* Print the functions */
349    
350     printf("\n");
351     printf("\n");
352     printf("/* The XML tag processing functions */\n");
353    
354     for(i=0;i<ntags;i++)
355     {
356     printf("\n");
357     printf("\n");
358     printf("/*++++++++++++++++++++++++++++++++++++++\n");
359     printf(" The function that is called when the %s type is seen\n",types[i]);
360     for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
361     if(tags[i]->attributes[j])
362     {
363     printf("\n");
364     printf(" char *%s The contents of the '%s' attribute (or NULL if not defined).\n",safe(tags[i]->attributes[j]),tags[i]->attributes[j]);
365     }
366     printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
367     printf("\n");
368    
369 amb 339 printf("static void %s_function(",safe(tags[i]->name));
370 amb 334
371     for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
372     if(tags[i]->attributes[j])
373     printf("%schar *%s",(j?",":""),safe(tags[i]->attributes[j]));
374    
375     if(!tags[i]->attributes[0])
376     printf("void");
377    
378     printf(")\n");
379    
380     printf("{\n");
381    
382     printf(" printf(\"<%s",tags[i]->name);
383     for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
384     if(tags[i]->attributes[j])
385     printf(" %s=\\\"%%s\\\"",tags[i]->attributes[j]);
386     printf(">\\n\"");
387     for(j=0;j<XMLPARSE_MAX_ATTRS;j++)
388     if(tags[i]->attributes[j])
389     printf(",(%s?%s:\"\")",safe(tags[i]->attributes[j]),safe(tags[i]->attributes[j]));
390     printf(");\n");
391    
392     printf("}\n");
393     }
394    
395     /* Print the main function */
396    
397     printf("\n");
398     printf("\n");
399     printf("/*++++++++++++++++++++++++++++++++++++++\n");
400     printf(" A skeleton XML parser.\n");
401     printf(" ++++++++++++++++++++++++++++++++++++++*/\n");
402     printf("\n");
403     printf("int main(int argc,char **argv)\n");
404     printf("{\n");
405 amb 339 printf(" ParseXML(stdin,xml_toplevel_tags,1);\n");
406 amb 334 printf("\n");
407     printf(" return(0);\n");
408     printf("}\n");
409    
410     return(0);
411     }
412    
413    
414     /*++++++++++++++++++++++++++++++++++++++
415     A function to return a safe C identifier from an XML tag or attribute name.
416    
417     char *safe Returns the safe name in a private string (only use once).
418    
419     const char *name The name to convert.
420     ++++++++++++++++++++++++++++++++++++++*/
421    
422     static char *safe(const char *name)
423     {
424     static char *safe=NULL;
425     int i;
426    
427     safe=realloc(safe,strlen(name)+1);
428    
429     for(i=0;name[i];i++)
430     if(isalnum(name[i]))
431     safe[i]=name[i];
432     else
433     safe[i]='_';
434    
435     safe[i]=0;
436    
437     return(safe);
438     }

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.