mxml.h 12.2 KB
Newer Older
Michael R Sweet's avatar
Michael R Sweet committed
1
/*
Michael Sweet's avatar
Michael Sweet committed
2
 * Header file for Mini-XML, a small XML file parsing library.
Michael R Sweet's avatar
Michael R Sweet committed
3
 *
Michael Sweet's avatar
Michael Sweet committed
4
 * Copyright 2003-2017 by Michael R Sweet.
Michael R Sweet's avatar
Michael R Sweet committed
5
 *
6 7 8 9 10
 * These coded instructions, statements, and computer programs are the
 * property of Michael R Sweet and are protected by Federal copyright
 * law.  Distribution and use rights are outlined in the file "COPYING"
 * which should have been included with this file.  If this file is
 * missing or damaged, see the license at:
Michael R Sweet's avatar
Michael R Sweet committed
11
 *
Michael Sweet's avatar
Michael Sweet committed
12
 *     https://michaelrsweet.github.io/mxml
Michael R Sweet's avatar
Michael R Sweet committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 */

/*
 * Prevent multiple inclusion...
 */

#ifndef _mxml_h_
#  define _mxml_h_

/*
 * Include necessary headers...
 */

#  include <stdio.h>
#  include <stdlib.h>
#  include <string.h>
29
#  include <ctype.h>
30
#  include <errno.h>
Michael R Sweet's avatar
Michael R Sweet committed
31 32 33 34 35 36


/*
 * Constants...
 */

37
#  define MXML_MAJOR_VERSION	2	/* Major version number */
Michael R Sweet's avatar
Michael R Sweet committed
38
#  define MXML_MINOR_VERSION	12	/* Minor version number */
39

40 41 42
#  define MXML_TAB		8	/* Tabs every N columns */

#  define MXML_NO_CALLBACK	0	/* Don't use a type callback */
43 44 45
#  define MXML_INTEGER_CALLBACK	mxml_integer_cb
					/* Treat all data as integers */
#  define MXML_OPAQUE_CALLBACK	mxml_opaque_cb
46
					/* Treat all data as opaque */
47 48 49
#  define MXML_REAL_CALLBACK	mxml_real_cb
					/* Treat all data as real numbers */
#  define MXML_TEXT_CALLBACK	0	/* Treat all data as text */
50 51
#  define MXML_IGNORE_CALLBACK	mxml_ignore_cb
					/* Ignore all non-element content */
52

53
#  define MXML_NO_PARENT	0	/* No parent for the node */
54 55 56 57

#  define MXML_DESCEND		1	/* Descend when finding/walking */
#  define MXML_NO_DESCEND	0	/* Don't descend when finding/walking */
#  define MXML_DESCEND_FIRST	-1	/* Descend for first find */
Michael R Sweet's avatar
Michael R Sweet committed
58

59 60 61 62
#  define MXML_WS_BEFORE_OPEN	0	/* Callback for before open tag */
#  define MXML_WS_AFTER_OPEN	1	/* Callback for after open tag */
#  define MXML_WS_BEFORE_CLOSE	2	/* Callback for before close tag */
#  define MXML_WS_AFTER_CLOSE	3	/* Callback for after close tag */
63 64 65 66 67

#  define MXML_ADD_BEFORE	0	/* Add node before specified node */
#  define MXML_ADD_AFTER	1	/* Add node after specified node */
#  define MXML_ADD_TO_PARENT	NULL	/* Add node relative to parent */

Michael R Sweet's avatar
Michael R Sweet committed
68 69 70 71 72

/*
 * Data types...
 */

73 74 75 76 77 78 79 80 81 82
typedef enum mxml_sax_event_e		/**** SAX event type. ****/
{
  MXML_SAX_CDATA,			/* CDATA node */
  MXML_SAX_COMMENT,			/* Comment node */
  MXML_SAX_DATA,			/* Data node */
  MXML_SAX_DIRECTIVE,			/* Processing directive node */
  MXML_SAX_ELEMENT_CLOSE,		/* Element closed */
  MXML_SAX_ELEMENT_OPEN			/* Element opened */
} mxml_sax_event_t;

83
typedef enum mxml_type_e		/**** The XML node type. ****/
Michael R Sweet's avatar
Michael R Sweet committed
84
{
Michael R Sweet's avatar
Michael R Sweet committed
85
  MXML_IGNORE = -1,			/* Ignore/throw away node @since Mini-XML 2.3@ */
Michael R Sweet's avatar
Michael R Sweet committed
86 87 88 89
  MXML_ELEMENT,				/* XML element with attributes */
  MXML_INTEGER,				/* Integer value */
  MXML_OPAQUE,				/* Opaque string */
  MXML_REAL,				/* Real value */
90
  MXML_TEXT,				/* Text fragment */
Michael R Sweet's avatar
Michael R Sweet committed
91
  MXML_CUSTOM				/* Custom data @since Mini-XML 2.1@ */
Michael R Sweet's avatar
Michael R Sweet committed
92 93
} mxml_type_t;

94 95 96
typedef void (*mxml_custom_destroy_cb_t)(void *);
					/**** Custom data destructor ****/

97
typedef void (*mxml_error_cb_t)(const char *);
98 99
					/**** Error callback function ****/

100
typedef struct mxml_attr_s		/**** An XML element attribute value. @private@ ****/
Michael R Sweet's avatar
Michael R Sweet committed
101
{
102 103
  char			*name;		/* Attribute name */
  char			*value;		/* Attribute value */
Michael R Sweet's avatar
Michael R Sweet committed
104 105
} mxml_attr_t;

106
typedef struct mxml_element_s		/**** An XML element value. @private@ ****/
Michael R Sweet's avatar
Michael R Sweet committed
107
{
108 109 110
  char			*name;		/* Name of element */
  int			num_attrs;	/* Number of attributes */
  mxml_attr_t		*attrs;		/* Attributes */
Michael R Sweet's avatar
Michael R Sweet committed
111 112
} mxml_element_t;

113
typedef struct mxml_text_s		/**** An XML text value. @private@ ****/
114
{
115 116
  int			whitespace;	/* Leading whitespace? */
  char			*string;	/* Fragment string */
117 118
} mxml_text_t;

119
typedef struct mxml_custom_s		/**** An XML custom value. @private@ ****/
120 121
{
  void			*data;		/* Pointer to (allocated) custom data */
122
  mxml_custom_destroy_cb_t destroy;	/* Pointer to destructor function */
123 124
} mxml_custom_t;

125
typedef union mxml_value_u		/**** An XML node value. @private@ ****/
126 127 128 129 130 131
{
  mxml_element_t	element;	/* Element */
  int			integer;	/* Integer number */
  char			*opaque;	/* Opaque string */
  double		real;		/* Real number */
  mxml_text_t		text;		/* Text fragment */
Michael R Sweet's avatar
Michael R Sweet committed
132
  mxml_custom_t		custom;		/* Custom data @since Mini-XML 2.1@ */
133 134
} mxml_value_t;

135
struct mxml_node_s			/**** An XML node. @private@ ****/
Michael R Sweet's avatar
Michael R Sweet committed
136
{
137
  mxml_type_t		type;		/* Node type */
138 139 140 141 142
  struct mxml_node_s	*next;		/* Next node under same parent */
  struct mxml_node_s	*prev;		/* Previous node under same parent */
  struct mxml_node_s	*parent;	/* Parent node */
  struct mxml_node_s	*child;		/* First child node */
  struct mxml_node_s	*last_child;	/* Last child node */
143
  mxml_value_t		value;		/* Node value */
144 145
  int			ref_count;	/* Use count */
  void			*user_data;	/* User data */
146
};
Michael R Sweet's avatar
Michael R Sweet committed
147

148 149 150
typedef struct mxml_node_s mxml_node_t;	/**** An XML node. ****/

struct mxml_index_s			 /**** An XML node index. @private@ ****/
151 152 153 154 155 156
{
  char			*attr;		/* Attribute used for indexing or NULL */
  int			num_nodes;	/* Number of nodes in index */
  int			alloc_nodes;	/* Allocated nodes in index */
  int			cur_node;	/* Current node */
  mxml_node_t		**nodes;	/* Node array */
157 158 159 160
};

typedef struct mxml_index_s mxml_index_t;
					/**** An XML node index. ****/
161

162 163 164
typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *);
					/**** Custom data load callback function ****/

165
typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *);
166 167
					/**** Custom data save callback function ****/

168 169 170
typedef int (*mxml_entity_cb_t)(const char *);
					/**** Entity callback function */

171 172 173 174 175 176
typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
					/**** Load callback function ****/

typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
					/**** Save callback function ****/

177
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
178 179
					/**** SAX callback function ****/

Michael R Sweet's avatar
Michael R Sweet committed
180 181 182 183 184 185 186 187 188 189 190 191 192

/*
 * C++ support...
 */

#  ifdef __cplusplus
extern "C" {
#  endif /* __cplusplus */

/*
 * Prototypes...
 */

193 194
extern void		mxmlAdd(mxml_node_t *parent, int where,
			        mxml_node_t *child, mxml_node_t *node);
Michael R Sweet's avatar
Michael R Sweet committed
195
extern void		mxmlDelete(mxml_node_t *node);
Michael R Sweet's avatar
Michael R Sweet committed
196 197
extern void		mxmlElementDeleteAttr(mxml_node_t *node,
			                      const char *name);
Michael R Sweet's avatar
Michael R Sweet committed
198
extern const char	*mxmlElementGetAttr(mxml_node_t *node, const char *name);
199 200
extern const char       *mxmlElementGetAttrByIndex(mxml_node_t *node, int idx, const char **name);
extern int              mxmlElementGetAttrCount(mxml_node_t *node);
Michael R Sweet's avatar
Michael R Sweet committed
201 202
extern void		mxmlElementSetAttr(mxml_node_t *node, const char *name,
			                   const char *value);
203 204 205 206 207 208
extern void		mxmlElementSetAttrf(mxml_node_t *node, const char *name,
			                    const char *format, ...)
#    ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 3, 4)))
#    endif /* __GNUC__ */
;
209
extern int		mxmlEntityAddCallback(mxml_entity_cb_t cb);
210 211
extern const char	*mxmlEntityGetName(int val);
extern int		mxmlEntityGetValue(const char *name);
212
extern void		mxmlEntityRemoveCallback(mxml_entity_cb_t cb);
Michael R Sweet's avatar
Michael R Sweet committed
213
extern mxml_node_t	*mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
214
			                 const char *element, const char *attr,
215
					 const char *value, int descend);
216 217 218 219
extern mxml_node_t	*mxmlFindPath(mxml_node_t *node, const char *path);
extern const char	*mxmlGetCDATA(mxml_node_t *node);
extern const void	*mxmlGetCustom(mxml_node_t *node);
extern const char	*mxmlGetElement(mxml_node_t *node);
220 221 222
extern mxml_node_t	*mxmlGetFirstChild(mxml_node_t *node);
extern int		mxmlGetInteger(mxml_node_t *node);
extern mxml_node_t	*mxmlGetLastChild(mxml_node_t *node);
223 224
extern mxml_node_t	*mxmlGetNextSibling(mxml_node_t *node);
extern const char	*mxmlGetOpaque(mxml_node_t *node);
225
extern mxml_node_t	*mxmlGetParent(mxml_node_t *node);
226
extern mxml_node_t	*mxmlGetPrevSibling(mxml_node_t *node);
227
extern double		mxmlGetReal(mxml_node_t *node);
228 229
extern int		mxmlGetRefCount(mxml_node_t *node);
extern const char	*mxmlGetText(mxml_node_t *node, int *whitespace);
230 231
extern mxml_type_t	mxmlGetType(mxml_node_t *node);
extern void		*mxmlGetUserData(mxml_node_t *node);
232 233 234 235 236
extern void		mxmlIndexDelete(mxml_index_t *ind);
extern mxml_node_t	*mxmlIndexEnum(mxml_index_t *ind);
extern mxml_node_t	*mxmlIndexFind(mxml_index_t *ind,
			               const char *element,
			               const char *value);
237
extern int		mxmlIndexGetCount(mxml_index_t *ind);
238 239 240
extern mxml_index_t	*mxmlIndexNew(mxml_node_t *node, const char *element,
			              const char *attr);
extern mxml_node_t	*mxmlIndexReset(mxml_index_t *ind);
241 242
extern mxml_node_t	*mxmlLoadFd(mxml_node_t *top, int fd,
			            mxml_type_t (*cb)(mxml_node_t *));
Michael R Sweet's avatar
Michael R Sweet committed
243 244
extern mxml_node_t	*mxmlLoadFile(mxml_node_t *top, FILE *fp,
			              mxml_type_t (*cb)(mxml_node_t *));
245 246
extern mxml_node_t	*mxmlLoadString(mxml_node_t *top, const char *s,
			                mxml_type_t (*cb)(mxml_node_t *));
247
extern mxml_node_t	*mxmlNewCDATA(mxml_node_t *parent, const char *string);
248
extern mxml_node_t	*mxmlNewCustom(mxml_node_t *parent, void *data,
249
			               mxml_custom_destroy_cb_t destroy);
Michael R Sweet's avatar
Michael R Sweet committed
250 251 252
extern mxml_node_t	*mxmlNewElement(mxml_node_t *parent, const char *name);
extern mxml_node_t	*mxmlNewInteger(mxml_node_t *parent, int integer);
extern mxml_node_t	*mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
253 254 255 256 257
extern mxml_node_t	*mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...)
#    ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 2, 3)))
#    endif /* __GNUC__ */
;
Michael R Sweet's avatar
Michael R Sweet committed
258
extern mxml_node_t	*mxmlNewReal(mxml_node_t *parent, double real);
259 260
extern mxml_node_t	*mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
extern mxml_node_t	*mxmlNewTextf(mxml_node_t *parent, int whitespace, const char *format, ...)
261 262 263 264
#    ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 3, 4)))
#    endif /* __GNUC__ */
;
265
extern mxml_node_t	*mxmlNewXML(const char *version);
266
extern int		mxmlRelease(mxml_node_t *node);
267
extern void		mxmlRemove(mxml_node_t *node);
268
extern int		mxmlRetain(mxml_node_t *node);
269
extern char		*mxmlSaveAllocString(mxml_node_t *node,
270
			        	     mxml_save_cb_t cb);
271
extern int		mxmlSaveFd(mxml_node_t *node, int fd,
272
			           mxml_save_cb_t cb);
273
extern int		mxmlSaveFile(mxml_node_t *node, FILE *fp,
274
			             mxml_save_cb_t cb);
275
extern int		mxmlSaveString(mxml_node_t *node, char *buffer,
276 277 278 279 280 281 282 283 284 285
			               int bufsize, mxml_save_cb_t cb);
extern mxml_node_t	*mxmlSAXLoadFd(mxml_node_t *top, int fd,
			               mxml_type_t (*cb)(mxml_node_t *),
			               mxml_sax_cb_t sax, void *sax_data);
extern mxml_node_t	*mxmlSAXLoadFile(mxml_node_t *top, FILE *fp,
			                 mxml_type_t (*cb)(mxml_node_t *),
			                 mxml_sax_cb_t sax, void *sax_data);
extern mxml_node_t	*mxmlSAXLoadString(mxml_node_t *top, const char *s,
			                   mxml_type_t (*cb)(mxml_node_t *),
			                   mxml_sax_cb_t sax, void *sax_data);
286
extern int		mxmlSetCDATA(mxml_node_t *node, const char *data);
287
extern int		mxmlSetCustom(mxml_node_t *node, void *data,
288
			              mxml_custom_destroy_cb_t destroy);
289 290
extern void		mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
			                      mxml_custom_save_cb_t save);
291
extern int		mxmlSetElement(mxml_node_t *node, const char *name);
292
extern void		mxmlSetErrorCallback(mxml_error_cb_t cb);
293 294
extern int		mxmlSetInteger(mxml_node_t *node, int integer);
extern int		mxmlSetOpaque(mxml_node_t *node, const char *opaque);
295 296 297 298 299
extern int		mxmlSetOpaquef(mxml_node_t *node, const char *format, ...)
#    ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 2, 3)))
#    endif /* __GNUC__ */
;
300 301 302 303 304 305 306 307 308
extern int		mxmlSetReal(mxml_node_t *node, double real);
extern int		mxmlSetText(mxml_node_t *node, int whitespace,
			            const char *string);
extern int		mxmlSetTextf(mxml_node_t *node, int whitespace,
			             const char *format, ...)
#    ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 3, 4)))
#    endif /* __GNUC__ */
;
309
extern int		mxmlSetUserData(mxml_node_t *node, void *data);
310
extern void		mxmlSetWrapMargin(int column);
311 312 313 314
extern mxml_node_t	*mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
			              int descend);
extern mxml_node_t	*mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
			              int descend);
Michael R Sweet's avatar
Michael R Sweet committed
315 316


317
/*
Michael R Sweet's avatar
Michael R Sweet committed
318
 * Semi-private functions...
319 320
 */

Michael R Sweet's avatar
Michael R Sweet committed
321
extern void		mxml_error(const char *format, ...);
322
extern mxml_type_t	mxml_ignore_cb(mxml_node_t *node);
Michael R Sweet's avatar
Michael R Sweet committed
323 324 325
extern mxml_type_t	mxml_integer_cb(mxml_node_t *node);
extern mxml_type_t	mxml_opaque_cb(mxml_node_t *node);
extern mxml_type_t	mxml_real_cb(mxml_node_t *node);
326 327


Michael R Sweet's avatar
Michael R Sweet committed
328 329 330 331 332 333 334 335
/*
 * C++ support...
 */

#  ifdef __cplusplus
}
#  endif /* __cplusplus */
#endif /* !_mxml_h_ */