Upload Tizen:Base source
[toolchains/python-lxml.git] / src / lxml / etree_defs.h
1 #ifndef HAS_ETREE_DEFS_H
2 #define HAS_ETREE_DEFS_H
3
4 /* quick check for Python/libxml2/libxslt devel setup */
5 #include "Python.h"
6 #ifndef PY_VERSION_HEX
7 #  error the development package of Python (header files etc.) is not installed correctly
8 #endif
9 #include "libxml/xmlversion.h"
10 #ifndef LIBXML_VERSION
11 #  error the development package of libxml2 (header files etc.) is not installed correctly
12 #endif
13 #include "libxslt/xsltconfig.h"
14 #ifndef LIBXSLT_VERSION
15 #  error the development package of libxslt (header files etc.) is not installed correctly
16 #endif
17
18
19 /* v_arg functions */
20 #define va_int(ap)     va_arg(ap, int)
21 #define va_charptr(ap) va_arg(ap, char *)
22
23 /* Threading can crash under Python <= 2.4.1 */
24 #if PY_VERSION_HEX < 0x02040200
25 #  ifndef WITHOUT_THREADING
26 #    define WITHOUT_THREADING
27 #  endif
28 #endif
29
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)
38 #else
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)
42 #endif
43 #endif
44
45 #if PY_VERSION_HEX >= 0x03000000
46 #  define IS_PYTHON3 1
47 #else
48 #  define IS_PYTHON3 0
49 #endif
50
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
60 #endif
61
62 #ifdef WITHOUT_THREADING
63 #  define ENABLE_THREADING 0
64 #else
65 #  define ENABLE_THREADING 1
66 #endif
67
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
73
74 /* HTML_PARSE_RECOVER was added in libxml2 2.6.21 */
75 #  define HTML_PARSE_RECOVER XML_PARSE_RECOVER
76 #endif
77
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
83 #endif
84
85 /* added to xmlsave API in libxml2 2.6.23 */
86 #if LIBXML_VERSION < 20623
87 #  define xmlSaveToBuffer(buffer, encoding, options)
88 #endif
89
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 */
94 #endif
95
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 */
99 #endif
100
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
108 #  endif
109 #else
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)
126 #endif
127
128
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 ); }
133 #endif
134
135 #ifdef __GNUC__
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 ... */
142 #else /* __GNUC__ */
143 #define unlikely_condition(x) (x)
144 #endif /* __GNUC__ */
145
146 #ifndef Py_TYPE
147   #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
148 #endif
149
150 #define PY_NEW(T) \
151      (((PyTypeObject*)(T))->tp_new( \
152              (PyTypeObject*)(T), __pyx_empty_tuple, NULL))
153
154 #define _fqtypename(o)  ((Py_TYPE(o))->tp_name)
155
156 #if PY_MAJOR_VERSION < 3
157 #define _isString(obj)   (PyString_CheckExact(obj)  || \
158                           PyUnicode_CheckExact(obj) || \
159                           PyObject_TypeCheck(obj, &PyBaseString_Type))
160 #else
161 #define _isString(obj)   (PyUnicode_CheckExact(obj) || \
162                           PyBytes_CheckExact(obj) || \
163                           PyUnicode_Check(obj) || \
164                           PyBytes_Check(obj))
165 #endif
166
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))
172
173 #define _isElementOrXInclude(c_node) \
174         (_isElement(c_node)                     || \
175          ((c_node)->type == XML_XINCLUDE_START) || \
176          ((c_node)->type == XML_XINCLUDE_END))
177
178 #define _getNs(c_node) \
179         (((c_node)->ns == 0) ? 0 : ((c_node)->ns->href))
180
181 /* Macro pair implementation of a depth first tree walker
182  *
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
187  * except text nodes.
188  * 
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)
194  *
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)
200  *
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)
207  *
208  * NOTE: 'some_node' MUST be a plain 'xmlNode*' !
209  *
210  * NOTE: parent modification during the walk can divert the iterator, but
211  *       should not segfault !
212  */
213
214 #define _LX__ELEMENT_MATCH(c_node, only_elements)  \
215     ((only_elements) ? (_isElement(c_node)) : 1)
216
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;
220
221 #define _LX__TRAVERSE_TO_NEXT(c_stop_node, c_node, only_elements)   \
222 {                                                                   \
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) { \
227             _lx__next = 0;                                          \
228         } else {                                                    \
229             _LX__ADVANCE_TO_NEXT(_lx__next, only_elements)          \
230         }                                                           \
231     }                                                               \
232     if ((_lx__next == 0) && (c_node != c_stop_node)) {              \
233         /* try siblings */                                          \
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;                                \
239             if (c_node == 0)                                        \
240                 break;                                              \
241             if (c_node == c_stop_node)                              \
242                 break;                                              \
243             if ((only_elements) && !_isElement(c_node))             \
244                 break;                                              \
245             /* we already traversed the parents -> siblings */      \
246             _lx__next = c_node->next;                               \
247             _LX__ADVANCE_TO_NEXT(_lx__next, only_elements)          \
248         }                                                           \
249     }                                                               \
250     c_node = _lx__next;                                             \
251 }
252
253 #define _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, only_elements)     \
254 {                                                                             \
255     if (c_node != 0) {                                                        \
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 */                         \
263             else {                                                            \
264                 c_node = c_node->next;                                        \
265                 _LX__ADVANCE_TO_NEXT(c_node, _lx__only_elements)              \
266             }                                                                 \
267         } else if (! (inclusive)) {                                           \
268             /* skip the first node */                                         \
269             _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements)  \
270         }                                                                     \
271                                                                               \
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 */
275
276 #define _LX__END_FOR_EACH_FROM(c_node)                                        \
277             _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements)  \
278         }                                                                     \
279     }                                                                         \
280 }
281
282
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)
285
286 #define END_FOR_EACH_ELEMENT_FROM(c_node)   \
287     _LX__END_FOR_EACH_FROM(c_node)
288
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)
291
292 #define END_FOR_EACH_FROM(c_node)   \
293     _LX__END_FOR_EACH_FROM(c_node)
294
295
296 #endif /* HAS_ETREE_DEFS_H */