Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/xml/xsd-to-xmlparser.c
Parent Directory
|
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)
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. |