Merge branch 'upstream'
[routino] / src / xmlparse.h
1 /***************************************
2  $Header: /home/amb/routino/src/RCS/xmlparse.h,v 1.12 2010/05/14 17:55:56 amb Exp $
3
4  A simple XML parser
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 #ifndef XMLPARSE_H
26 #define XMLPARSE_H    /*+ To stop multiple inclusions. +*/
27
28 #include <stdio.h>
29
30
31 /*+ The maximum number of attributes per tag. +*/
32 #define XMLPARSE_MAX_ATTRS   16
33
34 /*+ The maximum number of subtags per tag. +*/
35 #define XMLPARSE_MAX_SUBTAGS 16
36
37 /*+ A flag to indicate the start and/or end of a tag. +*/
38 #define XMLPARSE_TAG_START    1
39 #define XMLPARSE_TAG_END      2
40
41
42 /*+ A forward definition of the xmltag +*/
43 typedef struct _xmltag xmltag;
44
45
46 /*+ A structure to hold the definition of a tag. +*/
47 struct _xmltag
48 {
49  char *name;                            /*+ The name of the tag. +*/
50
51  int  nattributes;                      /*+ The number of valid attributes for the tag. +*/
52  char *attributes[XMLPARSE_MAX_ATTRS];  /*+ The valid attributes for the tag. +*/
53
54  int  (*callback)();                    /*+ The callback function when the tag is seen. +*/
55
56  xmltag *subtags[XMLPARSE_MAX_SUBTAGS]; /*+ The list of valid tags contained within this one (null terminated). +*/
57 };
58
59
60 /* XML Parser options */
61
62 #define XMLPARSE_UNKNOWN_ATTRIBUTES     0x0003
63 #define XMLPARSE_UNKNOWN_ATTR_ERROR     0x0000 /* Flag an error and exit. */
64 #define XMLPARSE_UNKNOWN_ATTR_ERRNONAME 0x0001 /* Flag an error and exit unless a namespace is specified. */
65 #define XMLPARSE_UNKNOWN_ATTR_WARN      0x0002 /* Warn about the problem and continue. */
66 #define XMLPARSE_UNKNOWN_ATTR_IGNORE    0x0003 /* Ignore the potential problem. */
67
68 #define XMLPARSE_RETURN_ATTR_ENCODED    0x0004 /* Return the XML attribute strings without decoding them. */
69
70
71 /* XML parser functions */
72
73 int ParseXML(FILE *file,xmltag **tags,int options);
74
75 unsigned long ParseXML_LineNumber(void);
76
77 char *ParseXML_Decode_Entity_Ref(const char *string);
78 char *ParseXML_Decode_Char_Ref(const char *string);
79 char *ParseXML_Encode_Safe_XML(const char *string);
80
81 int ParseXML_GetInteger(const char *string,int *number);
82 int ParseXML_GetFloating(const char *string,double *number);
83
84 /* Macros to simplify the callback functions */
85
86 #define XMLPARSE_MESSAGE(tag,message) \
87  do \
88    { \
89     fprintf(stderr,"XML Parser: Error on line %ld: " message " in <%s> tag.\n",ParseXML_LineNumber(),tag); \
90     return(1); \
91    } \
92     while(0)
93
94 #define XMLPARSE_INVALID(tag,attribute) \
95  do \
96    { \
97     fprintf(stderr,"XML Parser: Error on line %ld: Invalid value for '" #attribute "' attribute in <%s> tag.\n",ParseXML_LineNumber(),tag); \
98     return(1); \
99    } \
100     while(0)
101
102 #define XMLPARSE_ASSERT_STRING(tag,attribute) \
103  do \
104    { \
105     if(!attribute) \
106       { \
107        fprintf(stderr,"XML Parser: Error on line %ld: '" #attribute "' attribute must be specified in <%s> tag.\n",ParseXML_LineNumber(),tag); \
108        return(1); \
109       } \
110    } \
111     while(0)
112
113 #define XMLPARSE_ASSERT_INTEGER(tag,attribute,result)  \
114  do \
115    { \
116     if(!attribute || !*attribute || !ParseXML_GetInteger(attribute,&result)) \
117       { \
118        fprintf(stderr,"XML Parser: Error on line %ld: '" #attribute "' attribute must be a integer in <%s> tag.\n",ParseXML_LineNumber(),tag); \
119        return(1); \
120       } \
121    } \
122     while(0)
123
124 #define XMLPARSE_ASSERT_FLOATING(tag,attribute,result)  \
125  do \
126    { \
127     if(!attribute || !*attribute || !ParseXML_GetFloating(attribute,&result)) \
128       { \
129        fprintf(stderr,"XML Parser: Error on line %ld: '" #attribute "' attribute must be a number in <%s> tag.\n",ParseXML_LineNumber(),tag); \
130        return(1); \
131       } \
132    } \
133     while(0)
134
135
136 #endif /* XMLPARSE_H */