Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1710 - (show annotations) (download) (as text)
Sun Jun 14 09:07:05 2015 UTC (9 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 16464 byte(s)
Audit the use of function static variables to make sure that there are
no implicit assumptions about initialisation conditions that would be
wrong for library usage.  Fix problems and add comments for clarity.

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 xmltag xmlDeclaration_tag;
76 static xmltag schemaType_tag;
77 static xmltag elementType_tag;
78 static xmltag complexType_tag;
79 static xmltag sequenceType_tag;
80 static xmltag attributeType_tag;
81
82
83 /* The XML tag definition values */
84
85 /*+ The complete set of tags at the top level. +*/
86 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL};
87
88 /*+ The xmlDeclaration type tag. +*/
89 static xmltag xmlDeclaration_tag=
90 {"xml",
91 2, {"version","encoding"},
92 xmlDeclaration_function,
93 {NULL}};
94
95 /*+ The schemaType type tag. +*/
96 static 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 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 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 xmltag sequenceType_tag=
118 {"xsd:sequence",
119 0, {NULL},
120 sequenceType_function,
121 {&elementType_tag,NULL}};
122
123 /*+ The attributeType type tag. +*/
124 static 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 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 xmltag *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 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.