Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 1 | /* |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 2 | * "$Id: mxml.h 451 2014-01-04 21:50:06Z msweet $" |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 3 | * |
| 4 | * Header file for Mini-XML, a small XML-like file parsing library. |
| 5 | * |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 6 | * Copyright 2003-2014 by Michael R Sweet. |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 7 | * |
| 8 | * These coded instructions, statements, and computer programs are the |
| 9 | * property of Michael R Sweet and are protected by Federal copyright |
| 10 | * law. Distribution and use rights are outlined in the file "COPYING" |
| 11 | * which should have been included with this file. If this file is |
| 12 | * missing or damaged, see the license at: |
| 13 | * |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 14 | * http://www.msweet.org/projects.php/Mini-XML |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 15 | */ |
| 16 | |
| 17 | /* |
| 18 | * Prevent multiple inclusion... |
| 19 | */ |
| 20 | |
| 21 | #ifndef _mxml_h_ |
| 22 | # define _mxml_h_ |
| 23 | |
| 24 | /* |
| 25 | * Include necessary headers... |
| 26 | */ |
| 27 | |
| 28 | # include <stdio.h> |
| 29 | # include <stdlib.h> |
| 30 | # include <string.h> |
| 31 | # include <ctype.h> |
| 32 | # include <errno.h> |
| 33 | |
| 34 | |
| 35 | /* |
| 36 | * Constants... |
| 37 | */ |
| 38 | |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 39 | # define MXML_MAJOR_VERSION 2 /* Major version number */ |
| 40 | # define MXML_MINOR_VERSION 8 /* Minor version number */ |
| 41 | |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 42 | # define MXML_TAB 8 /* Tabs every N columns */ |
| 43 | |
| 44 | # define MXML_NO_CALLBACK 0 /* Don't use a type callback */ |
| 45 | # define MXML_INTEGER_CALLBACK mxml_integer_cb |
| 46 | /* Treat all data as integers */ |
| 47 | # define MXML_OPAQUE_CALLBACK mxml_opaque_cb |
| 48 | /* Treat all data as opaque */ |
| 49 | # define MXML_REAL_CALLBACK mxml_real_cb |
| 50 | /* Treat all data as real numbers */ |
| 51 | # define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ |
| 52 | # define MXML_IGNORE_CALLBACK mxml_ignore_cb |
| 53 | /* Ignore all non-element content */ |
| 54 | |
| 55 | # define MXML_NO_PARENT 0 /* No parent for the node */ |
| 56 | |
| 57 | # define MXML_DESCEND 1 /* Descend when finding/walking */ |
| 58 | # define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */ |
| 59 | # define MXML_DESCEND_FIRST -1 /* Descend for first find */ |
| 60 | |
| 61 | # define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */ |
| 62 | # define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */ |
| 63 | # define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */ |
| 64 | # define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */ |
| 65 | |
| 66 | # define MXML_ADD_BEFORE 0 /* Add node before specified node */ |
| 67 | # define MXML_ADD_AFTER 1 /* Add node after specified node */ |
| 68 | # define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */ |
| 69 | |
| 70 | |
| 71 | /* |
| 72 | * Data types... |
| 73 | */ |
| 74 | |
| 75 | typedef enum mxml_sax_event_e /**** SAX event type. ****/ |
| 76 | { |
| 77 | MXML_SAX_CDATA, /* CDATA node */ |
| 78 | MXML_SAX_COMMENT, /* Comment node */ |
| 79 | MXML_SAX_DATA, /* Data node */ |
| 80 | MXML_SAX_DIRECTIVE, /* Processing directive node */ |
| 81 | MXML_SAX_ELEMENT_CLOSE, /* Element closed */ |
| 82 | MXML_SAX_ELEMENT_OPEN /* Element opened */ |
| 83 | } mxml_sax_event_t; |
| 84 | |
| 85 | typedef enum mxml_type_e /**** The XML node type. ****/ |
| 86 | { |
| 87 | MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */ |
| 88 | MXML_ELEMENT, /* XML element with attributes */ |
| 89 | MXML_INTEGER, /* Integer value */ |
| 90 | MXML_OPAQUE, /* Opaque string */ |
| 91 | MXML_REAL, /* Real value */ |
| 92 | MXML_TEXT, /* Text fragment */ |
| 93 | MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ |
| 94 | } mxml_type_t; |
| 95 | |
| 96 | typedef void (*mxml_custom_destroy_cb_t)(void *); |
| 97 | /**** Custom data destructor ****/ |
| 98 | |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 99 | typedef void (*mxml_error_cb_t)(const char *); |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 100 | /**** Error callback function ****/ |
| 101 | |
| 102 | typedef struct mxml_attr_s /**** An XML element attribute value. @private@ ****/ |
| 103 | { |
| 104 | char *name; /* Attribute name */ |
| 105 | char *value; /* Attribute value */ |
| 106 | } mxml_attr_t; |
| 107 | |
| 108 | typedef struct mxml_element_s /**** An XML element value. @private@ ****/ |
| 109 | { |
| 110 | char *name; /* Name of element */ |
| 111 | int num_attrs; /* Number of attributes */ |
| 112 | mxml_attr_t *attrs; /* Attributes */ |
| 113 | } mxml_element_t; |
| 114 | |
| 115 | typedef struct mxml_text_s /**** An XML text value. @private@ ****/ |
| 116 | { |
| 117 | int whitespace; /* Leading whitespace? */ |
| 118 | char *string; /* Fragment string */ |
| 119 | } mxml_text_t; |
| 120 | |
| 121 | typedef struct mxml_custom_s /**** An XML custom value. @private@ ****/ |
| 122 | { |
| 123 | void *data; /* Pointer to (allocated) custom data */ |
| 124 | mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ |
| 125 | } mxml_custom_t; |
| 126 | |
| 127 | typedef union mxml_value_u /**** An XML node value. @private@ ****/ |
| 128 | { |
| 129 | mxml_element_t element; /* Element */ |
| 130 | int integer; /* Integer number */ |
| 131 | char *opaque; /* Opaque string */ |
| 132 | double real; /* Real number */ |
| 133 | mxml_text_t text; /* Text fragment */ |
| 134 | mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ |
| 135 | } mxml_value_t; |
| 136 | |
| 137 | struct mxml_node_s /**** An XML node. @private@ ****/ |
| 138 | { |
| 139 | mxml_type_t type; /* Node type */ |
| 140 | struct mxml_node_s *next; /* Next node under same parent */ |
| 141 | struct mxml_node_s *prev; /* Previous node under same parent */ |
| 142 | struct mxml_node_s *parent; /* Parent node */ |
| 143 | struct mxml_node_s *child; /* First child node */ |
| 144 | struct mxml_node_s *last_child; /* Last child node */ |
| 145 | mxml_value_t value; /* Node value */ |
| 146 | int ref_count; /* Use count */ |
| 147 | void *user_data; /* User data */ |
| 148 | }; |
| 149 | |
| 150 | typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/ |
| 151 | |
| 152 | struct mxml_index_s /**** An XML node index. @private@ ****/ |
| 153 | { |
| 154 | char *attr; /* Attribute used for indexing or NULL */ |
| 155 | int num_nodes; /* Number of nodes in index */ |
| 156 | int alloc_nodes; /* Allocated nodes in index */ |
| 157 | int cur_node; /* Current node */ |
| 158 | mxml_node_t **nodes; /* Node array */ |
| 159 | }; |
| 160 | |
| 161 | typedef struct mxml_index_s mxml_index_t; |
| 162 | /**** An XML node index. ****/ |
| 163 | |
| 164 | typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *); |
| 165 | /**** Custom data load callback function ****/ |
| 166 | |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 167 | typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *); |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 168 | /**** Custom data save callback function ****/ |
| 169 | |
| 170 | typedef int (*mxml_entity_cb_t)(const char *); |
| 171 | /**** Entity callback function */ |
| 172 | |
| 173 | typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *); |
| 174 | /**** Load callback function ****/ |
| 175 | |
| 176 | typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int); |
| 177 | /**** Save callback function ****/ |
| 178 | |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 179 | typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *); |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 180 | /**** SAX callback function ****/ |
| 181 | |
| 182 | |
| 183 | /* |
| 184 | * C++ support... |
| 185 | */ |
| 186 | |
| 187 | # ifdef __cplusplus |
| 188 | extern "C" { |
| 189 | # endif /* __cplusplus */ |
| 190 | |
| 191 | /* |
| 192 | * Prototypes... |
| 193 | */ |
| 194 | |
| 195 | extern void mxmlAdd(mxml_node_t *parent, int where, |
| 196 | mxml_node_t *child, mxml_node_t *node); |
| 197 | extern void mxmlDelete(mxml_node_t *node); |
| 198 | extern void mxmlElementDeleteAttr(mxml_node_t *node, |
| 199 | const char *name); |
| 200 | extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); |
| 201 | extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, |
| 202 | const char *value); |
| 203 | extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, |
| 204 | const char *format, ...) |
| 205 | # ifdef __GNUC__ |
| 206 | __attribute__ ((__format__ (__printf__, 3, 4))) |
| 207 | # endif /* __GNUC__ */ |
| 208 | ; |
| 209 | extern int mxmlEntityAddCallback(mxml_entity_cb_t cb); |
| 210 | extern const char *mxmlEntityGetName(int val); |
| 211 | extern int mxmlEntityGetValue(const char *name); |
| 212 | extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb); |
| 213 | extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, |
| 214 | const char *name, const char *attr, |
| 215 | const char *value, int descend); |
| 216 | extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path); |
| 217 | extern const char *mxmlGetCDATA(mxml_node_t *node); |
| 218 | extern const void *mxmlGetCustom(mxml_node_t *node); |
| 219 | extern const char *mxmlGetElement(mxml_node_t *node); |
| 220 | extern mxml_node_t *mxmlGetFirstChild(mxml_node_t *node); |
| 221 | extern int mxmlGetInteger(mxml_node_t *node); |
| 222 | extern mxml_node_t *mxmlGetLastChild(mxml_node_t *node); |
| 223 | extern mxml_node_t *mxmlGetNextSibling(mxml_node_t *node); |
| 224 | 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 | extern int mxmlGetRefCount(mxml_node_t *node); |
| 229 | extern const char *mxmlGetText(mxml_node_t *node, int *whitespace); |
| 230 | extern mxml_type_t mxmlGetType(mxml_node_t *node); |
| 231 | extern void *mxmlGetUserData(mxml_node_t *node); |
| 232 | extern void mxmlIndexDelete(mxml_index_t *ind); |
| 233 | extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); |
| 234 | extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, |
| 235 | const char *element, |
| 236 | const char *value); |
| 237 | extern int mxmlIndexGetCount(mxml_index_t *ind); |
| 238 | extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, |
| 239 | const char *attr); |
| 240 | extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); |
| 241 | extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, |
| 242 | mxml_type_t (*cb)(mxml_node_t *)); |
| 243 | extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, |
| 244 | mxml_type_t (*cb)(mxml_node_t *)); |
| 245 | extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, |
| 246 | 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); |
| 250 | extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name); |
| 251 | extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer); |
| 252 | extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque); |
| 253 | extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real); |
| 254 | extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, |
| 255 | const char *string); |
| 256 | extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, |
| 257 | const char *format, ...) |
| 258 | # ifdef __GNUC__ |
| 259 | __attribute__ ((__format__ (__printf__, 3, 4))) |
| 260 | # endif /* __GNUC__ */ |
| 261 | ; |
| 262 | extern mxml_node_t *mxmlNewXML(const char *version); |
| 263 | extern int mxmlRelease(mxml_node_t *node); |
| 264 | extern void mxmlRemove(mxml_node_t *node); |
| 265 | extern int mxmlRetain(mxml_node_t *node); |
| 266 | extern char *mxmlSaveAllocString(mxml_node_t *node, |
| 267 | mxml_save_cb_t cb); |
| 268 | extern int mxmlSaveFd(mxml_node_t *node, int fd, |
| 269 | mxml_save_cb_t cb); |
| 270 | extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, |
| 271 | mxml_save_cb_t cb); |
| 272 | extern int mxmlSaveString(mxml_node_t *node, char *buffer, |
| 273 | int bufsize, mxml_save_cb_t cb); |
| 274 | extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, |
| 275 | mxml_type_t (*cb)(mxml_node_t *), |
| 276 | mxml_sax_cb_t sax, void *sax_data); |
| 277 | extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp, |
| 278 | mxml_type_t (*cb)(mxml_node_t *), |
| 279 | mxml_sax_cb_t sax, void *sax_data); |
| 280 | extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, |
| 281 | mxml_type_t (*cb)(mxml_node_t *), |
| 282 | mxml_sax_cb_t sax, void *sax_data); |
| 283 | extern int mxmlSetCDATA(mxml_node_t *node, const char *data); |
| 284 | extern int mxmlSetCustom(mxml_node_t *node, void *data, |
| 285 | mxml_custom_destroy_cb_t destroy); |
| 286 | extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, |
| 287 | mxml_custom_save_cb_t save); |
| 288 | extern int mxmlSetElement(mxml_node_t *node, const char *name); |
| 289 | extern void mxmlSetErrorCallback(mxml_error_cb_t cb); |
| 290 | extern int mxmlSetInteger(mxml_node_t *node, int integer); |
| 291 | extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); |
| 292 | extern int mxmlSetReal(mxml_node_t *node, double real); |
| 293 | extern int mxmlSetText(mxml_node_t *node, int whitespace, |
| 294 | const char *string); |
| 295 | extern int mxmlSetTextf(mxml_node_t *node, int whitespace, |
| 296 | const char *format, ...) |
| 297 | # ifdef __GNUC__ |
| 298 | __attribute__ ((__format__ (__printf__, 3, 4))) |
| 299 | # endif /* __GNUC__ */ |
| 300 | ; |
| 301 | extern int mxmlSetUserData(mxml_node_t *node, void *data); |
| 302 | extern void mxmlSetWrapMargin(int column); |
| 303 | extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, |
| 304 | int descend); |
| 305 | extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, |
| 306 | int descend); |
| 307 | |
| 308 | |
| 309 | /* |
| 310 | * Semi-private functions... |
| 311 | */ |
| 312 | |
| 313 | extern void mxml_error(const char *format, ...); |
| 314 | extern mxml_type_t mxml_ignore_cb(mxml_node_t *node); |
| 315 | extern mxml_type_t mxml_integer_cb(mxml_node_t *node); |
| 316 | extern mxml_type_t mxml_opaque_cb(mxml_node_t *node); |
| 317 | extern mxml_type_t mxml_real_cb(mxml_node_t *node); |
| 318 | |
| 319 | |
| 320 | /* |
| 321 | * C++ support... |
| 322 | */ |
| 323 | |
| 324 | # ifdef __cplusplus |
| 325 | } |
| 326 | # endif /* __cplusplus */ |
| 327 | #endif /* !_mxml_h_ */ |
| 328 | |
| 329 | |
| 330 | /* |
Jon Medhurst | 96b5615 | 2014-10-30 18:01:15 +0000 | [diff] [blame] | 331 | * End of "$Id: mxml.h 451 2014-01-04 21:50:06Z msweet $". |
Jon Medhurst | aaf37a3 | 2013-06-11 12:10:56 +0100 | [diff] [blame] | 332 | */ |