1 /*
2  * See Licensing and Copyright notice in naev.h
3  */
4 
5 
6 
7 #ifndef XML_H
8 #  define XML_H
9 
10 #include <errno.h>
11 
12 #include "libxml/parser.h"
13 #include "libxml/xmlwriter.h"
14 
15 #include "log.h"
16 #include "opengl.h"
17 
18 
19 #define XML_NODE_START  1
20 #define XML_NODE_TEXT   3
21 
22 /**
23  * @brief Only handle nodes.
24  */
25 #define xml_onlyNodes(n)    \
26    if (((n)==NULL) || ((n)->type!=XML_NODE_START)) \
27       continue;
28 
29 /* checks to see if node n is of name s */
30 #define xml_isNode(n,s)    \
31    ((n!=NULL) && ((n)->type==XML_NODE_START) && \
32    (strcmp((char*)(n)->name,s)==0))
33 
34 /* gets the next node */
35 #define xml_nextNode(n)     \
36    ((n!=NULL) && ((n = n->next) != NULL))
37 
38 /* gets the property s of node n. WARNING: MALLOCS! */
39 #define xml_nodeProp(n,s)     (char*)xmlGetProp(n,(xmlChar*)s)
40 
41 /* get data different ways */
42 #define xml_raw(n)            ((char*)(n)->children->content)
43 #define xml_get(n)            (((n)->children == NULL) ? NULL : (char*)(n)->children->content)
44 #define xml_getInt(n)         ((xml_get(n) == NULL) ? 0  : strtol(  xml_raw(n), (char**)NULL, 10))
45 #define xml_getUInt(n)        ((xml_get(n) == NULL) ? 0  : strtoul( xml_raw(n), (char**)NULL, 10))
46 #define xml_getLong(n)        ((xml_get(n) == NULL) ? 0  : strtoll( xml_raw(n), (char**)NULL, 10))
47 #define xml_getULong(n)       ((xml_get(n) == NULL) ? 0  : strtoull(xml_raw(n), (char**)NULL, 10))
48 #define xml_getFloat(n)       ((xml_get(n) == NULL) ? 0. : atof(xml_raw(n)))
49 #define xml_getStrd(n)        ((xml_get(n) == NULL) ? NULL : strdup(xml_raw(n)))
50 
51 
52 /*
53  * reader crap
54  */
55 #define xmlr_int(n,s,i) \
56    {if (xml_isNode(n,s)) { \
57       i = xml_getInt(n); continue; }}
58 #define xmlr_uint(n,s,i) \
59    {if (xml_isNode(n,s)) { \
60       i = xml_getUInt(n); continue; }}
61 #define xmlr_long(n,s,l) \
62    {if (xml_isNode(n,s)) { \
63       l = xml_getLong(n); continue; }}
64 #define xmlr_ulong(n,s,l) \
65    {if (xml_isNode(n,s)) { \
66       l = xml_getULong(n); continue; }}
67 #define xmlr_float(n,s,f) \
68    {if (xml_isNode(n,s)) { \
69       f = xml_getFloat(n); continue; }}
70 #define xmlr_floatR(n,s,f) \
71    {if (xml_isNode(n,s)) { \
72       f = xml_getFloat(n); return 0; }}
73 #define xmlr_str(n,s,str) \
74    {if (xml_isNode(n,s)) { \
75       str = xml_get(n); continue; }}
76 #define xmlr_strd(n,s,str) \
77    {if (xml_isNode(n,s)) { \
78       if (str != NULL) { \
79          WARN("Node '%s' already loaded and being trying to replace '%s' with '%s'", \
80                s, str, xml_raw(n) ); } \
81       str = ((xml_get(n) == NULL) ? NULL : strdup(xml_raw(n))); continue; }}
82 #define xmlr_attr(n,s,a) \
83    a = xml_nodeProp(n,s)
84 
85 /*
86  * writer crap
87  */
88 /* encompassing element */
89 #define xmlw_startElem(w,str)   \
90 do {if (xmlTextWriterStartElement(w,(xmlChar*)str) < 0) { \
91    ERR("xmlw: unable to create start element"); return -1; } } while(0)
92 #define xmlw_endElem(w) \
93 do {if (xmlTextWriterEndElement(w) < 0) { \
94    ERR("xmlw: unable to create end element"); return -1; } } while(0)
95 /* other stuff */
96 #define xmlw_elemEmpty(w,n)   \
97 do { xmlw_startElem(w,n); xmlw_endElem(w); } while(0)
98 #define xmlw_elem(w,n,str,args...) \
99 do { if (xmlTextWriterWriteFormatElement(w,(xmlChar*)n, \
100       str, ## args) < 0) { \
101    ERR("xmlw: unable to write format element"); return -1; } } while(0)
102 #define xmlw_raw(w,b,l) \
103 do {if (xmlTextWriterWriteRawLen(w,(xmlChar*)b,l) < 0) { \
104    ERR("xmlw: unable to write raw element"); return -1; } } while(0)
105 #define xmlw_attr(w,str,val...)  \
106 do {if (xmlTextWriterWriteFormatAttribute(w,(xmlChar*)str, \
107       ## val) < 0) { \
108    ERR("xmlw: unable to write element attribute"); return -1; } } while(0)
109 #define xmlw_str(w,str,val...) \
110 do {if (xmlTextWriterWriteFormatString(w,str, ## val) < 0) { \
111    ERR("xmlw: unable to write element data"); return -1; } } while(0)
112 /* document level */
113 #define xmlw_start(w) \
114 do {if (xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) { \
115    ERR("xmlw: unable to start document"); return -1; } } while(0)
116 #define xmlw_done(w) \
117 do {if (xmlTextWriterEndDocument(w) < 0) { \
118    ERR("xmlw: unable to end document"); return -1; } } while(0)
119 
120 
121 /*
122  * Functions for generic complex reading.
123  */
124 glTexture* xml_parseTexture( xmlNodePtr node,
125       const char *path, int defsx, int defsy,
126       const unsigned int flags );
127 
128 
129 /*
130  * Functions for generic complex writing.
131  */
132 void xmlw_setParams( xmlTextWriterPtr writer );
133 
134 
135 #endif /* XML_H */
136