1 #ifndef HAS_ETREE_DEFS_H
2 #define HAS_ETREE_DEFS_H
4 /* quick check for Python/libxml2/libxslt devel setup */
7 # error the development package of Python (header files etc.) is not installed correctly
9 #include "libxml/xmlversion.h"
10 #ifndef LIBXML_VERSION
11 # error the development package of libxml2 (header files etc.) is not installed correctly
13 #include "libxslt/xsltconfig.h"
14 #ifndef LIBXSLT_VERSION
15 # error the development package of libxslt (header files etc.) is not installed correctly
20 #define va_int(ap) va_arg(ap, int)
21 #define va_charptr(ap) va_arg(ap, char *)
23 /* Threading can crash under Python <= 2.4.1 */
24 #if PY_VERSION_HEX < 0x02040200
25 # ifndef WITHOUT_THREADING
26 # define WITHOUT_THREADING
30 /* Python 3 doesn't have PyFile_*(), PyString_*(), ... */
31 #if PY_VERSION_HEX >= 0x03000000
32 # define PyFile_AsFile(o) (NULL)
33 # define PyString_Check(o) PyBytes_Check(o)
34 # define PyString_FromStringAndSize(s, len) PyBytes_FromStringAndSize(s, len)
35 # define PyString_FromFormat PyBytes_FromFormat
36 # define PyString_GET_SIZE(s) PyBytes_GET_SIZE(s)
37 # define PyString_AS_STRING(s) PyBytes_AS_STRING(s)
39 #if PY_VERSION_HEX < 0x02060000
40 /* we currently only use three parameters - MSVC can't compile (s, ...) */
41 # define PyUnicode_FromFormat(s, a, b) (NULL)
45 #if PY_VERSION_HEX >= 0x03000000
51 #ifdef WITHOUT_THREADING
52 # define PyEval_SaveThread() (NULL)
53 # define PyEval_RestoreThread(state)
54 # define PyGILState_Ensure() (PyGILState_UNLOCKED)
55 # define PyGILState_Release(state)
56 # undef Py_UNBLOCK_THREADS
57 # define Py_UNBLOCK_THREADS
58 # undef Py_BLOCK_THREADS
59 # define Py_BLOCK_THREADS
62 #ifdef WITHOUT_THREADING
63 # define ENABLE_THREADING 0
65 # define ENABLE_THREADING 1
68 /* libxml2 version specific setup */
69 #if LIBXML_VERSION < 20621
70 /* (X|HT)ML_PARSE_COMPACT were added in libxml2 2.6.21 */
71 # define XML_PARSE_COMPACT 1 << 16
72 # define HTML_PARSE_COMPACT XML_PARSE_COMPACT
74 /* HTML_PARSE_RECOVER was added in libxml2 2.6.21 */
75 # define HTML_PARSE_RECOVER XML_PARSE_RECOVER
78 #if LIBXML_VERSION < 20700
79 /* These were added in libxml2 2.7.0 */
80 # define XML_PARSE_OLD10 1 << 17
81 # define XML_PARSE_NOBASEFIX 1 << 18
82 # define XML_PARSE_HUGE 1 << 19
85 /* added to xmlsave API in libxml2 2.6.23 */
86 #if LIBXML_VERSION < 20623
87 # define xmlSaveToBuffer(buffer, encoding, options)
90 /* added to xmlsave API in libxml2 2.6.22 */
91 #if LIBXML_VERSION < 20622
92 # define XML_SAVE_NO_EMPTY 1<<2, /* no empty tags */
93 # define XML_SAVE_NO_XHTML 1<<3 /* disable XHTML1 specific rules */
96 /* added to xmlsave API in libxml2 2.6.21 */
97 #if LIBXML_VERSION < 20621
98 # define XML_SAVE_NO_DECL 1<<1, /* drop the xml declaration */
101 /* schematron was added in libxml2 2.6.21 */
102 #ifdef LIBXML_SCHEMATRON_ENABLED
103 # define ENABLE_SCHEMATRON 1
104 # if LIBXML_VERSION < 20632
105 /* schematron error reporting was added in libxml2 2.6.32 */
106 # define xmlSchematronSetValidStructuredErrors(ctxt, errorfunc, data)
107 # define XML_SCHEMATRON_OUT_ERROR 0
110 # define ENABLE_SCHEMATRON 0
111 # define XML_SCHEMATRON_OUT_QUIET 0
112 # define XML_SCHEMATRON_OUT_XML 0
113 # define XML_SCHEMATRON_OUT_ERROR 0
114 typedef void xmlSchematron;
115 typedef void xmlSchematronParserCtxt;
116 typedef void xmlSchematronValidCtxt;
117 # define xmlSchematronNewDocParserCtxt(doc) NULL
118 # define xmlSchematronNewParserCtxt(file) NULL
119 # define xmlSchematronParse(ctxt) NULL
120 # define xmlSchematronFreeParserCtxt(ctxt)
121 # define xmlSchematronFree(schema)
122 # define xmlSchematronNewValidCtxt(schema, options) NULL
123 # define xmlSchematronValidateDoc(ctxt, doc) 0
124 # define xmlSchematronFreeValidCtxt(ctxt)
125 # define xmlSchematronSetValidStructuredErrors(ctxt, errorfunc, data)
129 /* work around MSDEV 6.0 */
130 #if (_MSC_VER == 1200) && (WINVER < 0x0500)
131 long _ftol( double ); //defined by VC6 C libs
132 long _ftol2( double dblSource ) { return _ftol( dblSource ); }
136 /* Test for GCC > 2.95 */
137 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
138 #define unlikely_condition(x) __builtin_expect((x), 0)
139 #else /* __GNUC__ > 2 ... */
140 #define unlikely_condition(x) (x)
141 #endif /* __GNUC__ > 2 ... */
143 #define unlikely_condition(x) (x)
144 #endif /* __GNUC__ */
147 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
151 (((PyTypeObject*)(T))->tp_new( \
152 (PyTypeObject*)(T), __pyx_empty_tuple, NULL))
154 #define _fqtypename(o) ((Py_TYPE(o))->tp_name)
156 #if PY_MAJOR_VERSION < 3
157 #define _isString(obj) (PyString_CheckExact(obj) || \
158 PyUnicode_CheckExact(obj) || \
159 PyObject_TypeCheck(obj, &PyBaseString_Type))
161 #define _isString(obj) (PyUnicode_CheckExact(obj) || \
162 PyBytes_CheckExact(obj) || \
163 PyUnicode_Check(obj) || \
167 #define _isElement(c_node) \
168 (((c_node)->type == XML_ELEMENT_NODE) || \
169 ((c_node)->type == XML_COMMENT_NODE) || \
170 ((c_node)->type == XML_ENTITY_REF_NODE) || \
171 ((c_node)->type == XML_PI_NODE))
173 #define _isElementOrXInclude(c_node) \
174 (_isElement(c_node) || \
175 ((c_node)->type == XML_XINCLUDE_START) || \
176 ((c_node)->type == XML_XINCLUDE_END))
178 #define _getNs(c_node) \
179 (((c_node)->ns == 0) ? 0 : ((c_node)->ns->href))
181 /* Macro pair implementation of a depth first tree walker
183 * Calls the code block between the BEGIN and END macros for all elements
184 * below c_tree_top (exclusively), starting at c_node (inclusively iff
185 * 'inclusive' is 1). The _ELEMENT_ variants will only stop on nodes
186 * that match _isElement(), the normal variant will stop on every node
189 * To traverse the node and all of its children and siblings in Pyrex, call
190 * cdef xmlNode* some_node
191 * BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 1)
192 * # do something with some_node
193 * END_FOR_EACH_ELEMENT_FROM(some_node)
195 * To traverse only the children and siblings of a node, call
196 * cdef xmlNode* some_node
197 * BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 0)
198 * # do something with some_node
199 * END_FOR_EACH_ELEMENT_FROM(some_node)
201 * To traverse only the children, do:
202 * cdef xmlNode* some_node
203 * some_node = parent_node.children
204 * BEGIN_FOR_EACH_ELEMENT_FROM(parent_node, some_node, 1)
205 * # do something with some_node
206 * END_FOR_EACH_ELEMENT_FROM(some_node)
208 * NOTE: 'some_node' MUST be a plain 'xmlNode*' !
210 * NOTE: parent modification during the walk can divert the iterator, but
211 * should not segfault !
214 #define _LX__ELEMENT_MATCH(c_node, only_elements) \
215 ((only_elements) ? (_isElement(c_node)) : 1)
217 #define _LX__ADVANCE_TO_NEXT(c_node, only_elements) \
218 while ((c_node != 0) && (!_LX__ELEMENT_MATCH(c_node, only_elements))) \
219 c_node = c_node->next;
221 #define _LX__TRAVERSE_TO_NEXT(c_stop_node, c_node, only_elements) \
223 /* walk through children first */ \
224 xmlNode* _lx__next = c_node->children; \
225 if (_lx__next != 0) { \
226 if (c_node->type == XML_ENTITY_REF_NODE || c_node->type == XML_DTD_NODE) { \
229 _LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \
232 if ((_lx__next == 0) && (c_node != c_stop_node)) { \
234 _lx__next = c_node->next; \
235 _LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \
236 /* back off through parents */ \
237 while (_lx__next == 0) { \
238 c_node = c_node->parent; \
241 if (c_node == c_stop_node) \
243 if ((only_elements) && !_isElement(c_node)) \
245 /* we already traversed the parents -> siblings */ \
246 _lx__next = c_node->next; \
247 _LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \
250 c_node = _lx__next; \
253 #define _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, only_elements) \
256 const xmlNode* _lx__tree_top = (c_tree_top); \
257 const int _lx__only_elements = (only_elements); \
258 /* make sure we start at an element */ \
259 if (!_LX__ELEMENT_MATCH(c_node, _lx__only_elements)) { \
260 /* we skip the node, so 'inclusive' is irrelevant */ \
261 if (c_node == _lx__tree_top) \
262 c_node = 0; /* nothing to traverse */ \
264 c_node = c_node->next; \
265 _LX__ADVANCE_TO_NEXT(c_node, _lx__only_elements) \
267 } else if (! (inclusive)) { \
268 /* skip the first node */ \
269 _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements) \
272 /* now run the user code on the elements we find */ \
273 while (c_node != 0) { \
274 /* here goes the code to be run for each element */
276 #define _LX__END_FOR_EACH_FROM(c_node) \
277 _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements) \
283 #define BEGIN_FOR_EACH_ELEMENT_FROM(c_tree_top, c_node, inclusive) \
284 _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 1)
286 #define END_FOR_EACH_ELEMENT_FROM(c_node) \
287 _LX__END_FOR_EACH_FROM(c_node)
289 #define BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive) \
290 _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 0)
292 #define END_FOR_EACH_FROM(c_node) \
293 _LX__END_FOR_EACH_FROM(c_node)
296 #endif /* HAS_ETREE_DEFS_H */