VPR-6.0

libvpr/include/ezxml.h

Go to the documentation of this file.
00001 /** 
00002  * @file ezxml.h
00003  *
00004  * Copyright 2004-2006 Aaron Voisine <aaron@voisine.org>
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining
00007  * a copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sublicense, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00018  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00021  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00022  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00023  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00024  */
00025 
00026 #ifndef _EZXML_H
00027 #define _EZXML_H
00028 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <stdarg.h>
00032 #include <fcntl.h>
00033 
00034 #ifdef __cplusplus
00035 extern "C"
00036 {
00037 #endif
00038 
00039 #define EZXML_BUFSIZE 1024      /**< size of internal memory buffers */
00040 #define EZXML_NAMEM   0x80      /**< name is malloced */
00041 #define EZXML_TXTM    0x40      /**< txt is malloced */
00042 #define EZXML_DUP     0x20      /**< attribute name and value are strduped */
00043 #define EZXML_ERRL 128          /**< maximum error string length */
00044 
00045     typedef struct ezxml *ezxml_t;
00046     struct ezxml
00047     {
00048         char *name;             /**< tag name */
00049         char **attr;            /**< tag attributes { name, value, name, value, ... NULL } */
00050         char *txt;              /**< tag character content, empty string if none */
00051         size_t off;             /**< tag offset from start of parent tag character content */
00052         ezxml_t next;           /**< next tag with same name in this section at this depth */
00053         ezxml_t sibling;        /**< next tag with different name in same section and depth */
00054         ezxml_t ordered;        /**< next tag, same section and depth, in original order */
00055         ezxml_t child;          /**< head of sub tag list, NULL if none */
00056         ezxml_t parent;         /**< parent tag, NULL if current tag is root tag */
00057         short flags;            /**< additional information */
00058         /* Jason Luu June 22, 2010, Added line number support */
00059         int line;
00060     };
00061 
00062         /* Jason Luu June 22, 2010, Moved root definition to header */
00063         /** additional data for the root tag */
00064         typedef struct ezxml_root *ezxml_root_t;
00065         struct ezxml_root
00066         {                               
00067                 struct ezxml xml;               /**< is a super-struct built on top of ezxml struct */
00068                 ezxml_t cur;            /**< current xml tree insertion point */
00069                 char *m;                        /**< original xml string */
00070                 size_t len;                     /**< length of allocated memory for mmap, -1 for malloc */
00071                 char *u;                        /**< UTF-8 conversion of string if original was UTF-16 */
00072                 char *s;                        /**< start of work area */
00073                 char *e;                        /**< end of work area */
00074                 char **ent;                     /**< general entities (ampersand sequences) */
00075                 char ***attr;           /**< default attributes */
00076                 char ***pi;                     /**< processing instructions */
00077                 short standalone;               /**< non-zero if <?xml standalone="yes"?> */
00078                 char err[EZXML_ERRL];   /**< error string */
00079         };
00080 
00081 
00082 /** Given a string of xml data and its length, parses it and creates an ezxml 
00083  * structure. For efficiency, modifies the data by adding null terminators 
00084  * and decoding ampersand sequences. If you don't want this, copy the data and 
00085  * pass in the copy. Returns NULL on failure. 
00086  */
00087     ezxml_t ezxml_parse_str(char *s,
00088                             size_t len);
00089 
00090 /** A wrapper for ezxml_parse_str() that accepts a file descriptor. First 
00091  * attempts to mem map the file. Failing that, reads the file into memory. 
00092  * Returns NULL on failure. 
00093  */
00094     ezxml_t ezxml_parse_fd(int fd);
00095 
00096 /** a wrapper for ezxml_parse_fd() that accepts a file name */
00097     ezxml_t ezxml_parse_file(const char *file);
00098 
00099 /** Wrapper for ezxml_parse_str() that accepts a file stream. Reads the entire 
00100  * stream into memory and then parses it. For xml files, use ezxml_parse_file()
00101  * or ezxml_parse_fd() 
00102  */
00103     ezxml_t ezxml_parse_fp(FILE * fp);
00104 
00105 /** returns the first child tag (one level deeper) with the given name or NULL 
00106  * if not found 
00107  */
00108     ezxml_t ezxml_child(ezxml_t xml,
00109                         const char *name);
00110 
00111 /** returns the next tag of the same name in the same section and depth or NULL 
00112  * if not found 
00113  */
00114 #define ezxml_next(xml) ((xml) ? xml->next : NULL)
00115 
00116 /** Returns the Nth tag with the same name in the same section at the same depth 
00117  * or NULL if not found. An index of 0 returns the tag given. 
00118  */
00119     ezxml_t ezxml_idx(ezxml_t xml,
00120                       int idx);
00121 
00122 /** returns the name of the given tag */
00123 #define ezxml_name(xml) ((xml) ? xml->name : NULL)
00124 
00125 /** returns the given tag's character content or empty string if none */
00126 #define ezxml_txt(xml) ((xml) ? xml->txt : "")
00127 
00128 /** returns the value of the requested tag attribute, or NULL if not found */
00129     const char *ezxml_attr(ezxml_t xml,
00130                            const char *attr);
00131 
00132 /** Traverses the ezxml sturcture to retrieve a specific subtag. Takes a 
00133 * variable length list of tag names and indexes. The argument list must be 
00134 * terminated by either an index of -1 or an empty string tag name. Example:  
00135 * title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); 
00136 * This retrieves the title of the 3rd book on the 1st shelf of library. 
00137 * Returns NULL if not found. 
00138 */
00139     ezxml_t ezxml_get(ezxml_t xml,
00140                       ...);
00141 
00142 /** Converts an ezxml structure back to xml. Returns a string of xml data that 
00143  * must be freed. 
00144  */
00145     char *ezxml_toxml(ezxml_t xml);
00146 
00147 /** returns a NULL terminated array of processing instructions for the given 
00148  * target 
00149  */
00150     const char **ezxml_pi(ezxml_t xml,
00151                           const char *target);
00152 
00153 /** frees the memory allocated for an ezxml structure */
00154     void ezxml_free(ezxml_t xml);
00155 
00156 /** returns parser error message or empty string if none */
00157     const char *ezxml_error(ezxml_t xml);
00158 
00159 /** returns a new empty ezxml structure with the given root tag name */
00160     ezxml_t ezxml_new(const char *name);
00161 
00162 /** wrapper for ezxml_new() that strdup()s name */
00163 #define ezxml_new_d(name) ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM)
00164 
00165 /** Adds a child tag. off is the offset of the child tag relative to the start 
00166  * of the parent tag's character content. Returns the child tag. 
00167  */
00168         ezxml_t ezxml_add_child(
00169                                 ezxml_t xml,
00170                             const char *name,
00171                             size_t off);
00172 
00173 /** wrapper for ezxml_add_child() that strdup()s name */
00174 #define ezxml_add_child_d(xml, name, off) \
00175     ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM)
00176 
00177 /** sets the character content for the given tag and returns the tag */
00178     ezxml_t ezxml_set_txt(ezxml_t xml,
00179                           const char *txt);
00180 
00181 /** wrapper for ezxml_set_txt() that strdup()s txt */
00182 #define ezxml_set_txt_d(xml, txt) \
00183     ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM)
00184 
00185 /** Sets the given tag attribute or adds a new attribute if not found. A value 
00186  * of NULL will remove the specified attribute. Returns the tag given. 
00187  */
00188     ezxml_t ezxml_set_attr(ezxml_t xml,
00189                            const char *name,
00190                            const char *value);
00191 
00192 /** Wrapper for ezxml_set_attr() that strdup()s name/value. Value cannot be NULL */
00193 #define ezxml_set_attr_d(xml, name, value) \
00194     ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value))
00195 
00196 /** sets a flag for the given tag and returns the tag */
00197     ezxml_t ezxml_set_flag(ezxml_t xml,
00198                            short flag);
00199 
00200 /** removes a tag along with its subtags without freeing its memory */
00201     ezxml_t ezxml_cut(ezxml_t xml);
00202 
00203 /** inserts an existing tag into an ezxml structure */
00204     ezxml_t ezxml_insert(ezxml_t xml,
00205                          ezxml_t dest,
00206                          size_t off);
00207 
00208 /** Moves an existing tag to become a subtag of dest at the given offset from 
00209  * the start of dest's character content. Returns the moved tag. 
00210  */
00211 #define ezxml_move(xml, dest, off) ezxml_insert(ezxml_cut(xml), dest, off)
00212 
00213 /** removes a tag along with all its subtags */
00214 #define ezxml_remove(xml) ezxml_free(ezxml_cut(xml))
00215 
00216 #ifdef __cplusplus
00217 }
00218 #endif
00219 #endif                          /* _EZXML_H */