Blame src/lxml/includes/etree_defs.h

Packit Service b74dd5
#ifndef HAS_ETREE_DEFS_H
Packit Service b74dd5
#define HAS_ETREE_DEFS_H
Packit Service b74dd5
Packit Service b74dd5
/* quick check for Python/libxml2/libxslt devel setup */
Packit Service b74dd5
#include "Python.h"
Packit Service b74dd5
#ifndef PY_VERSION_HEX
Packit Service b74dd5
#  error the development package of Python (header files etc.) is not installed correctly
Packit Service b74dd5
#else
Packit Service b74dd5
#  if PY_VERSION_HEX < 0x02060000 || PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x03020000
Packit Service b74dd5
#  error this version of lxml requires Python 2.6, 2.7, 3.2 or later
Packit Service b74dd5
#  endif
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#include "libxml/xmlversion.h"
Packit Service b74dd5
#ifndef LIBXML_VERSION
Packit Service b74dd5
#  error the development package of libxml2 (header files etc.) is not installed correctly
Packit Service b74dd5
#else
Packit Service b74dd5
#if LIBXML_VERSION < 20700
Packit Service b74dd5
#  error minimum required version of libxml2 is 2.7.0
Packit Service b74dd5
#endif
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#include "libxslt/xsltconfig.h"
Packit Service b74dd5
#ifndef LIBXSLT_VERSION
Packit Service b74dd5
#  error the development package of libxslt (header files etc.) is not installed correctly
Packit Service b74dd5
#else
Packit Service b74dd5
#if LIBXSLT_VERSION < 10123
Packit Service b74dd5
#  error minimum required version of libxslt is 1.1.23
Packit Service b74dd5
#endif
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
Packit Service b74dd5
/* v_arg functions */
Packit Service b74dd5
#define va_int(ap)     va_arg(ap, int)
Packit Service b74dd5
#define va_charptr(ap) va_arg(ap, char *)
Packit Service b74dd5
Packit Service b74dd5
#ifdef PYPY_VERSION
Packit Service b74dd5
#    define IS_PYPY 1
Packit Service b74dd5
#else
Packit Service b74dd5
#    define IS_PYPY 0
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if PY_MAJOR_VERSION >= 3
Packit Service b74dd5
#  define IS_PYTHON2 0  /* prefer for special casing Python 2.x */
Packit Service b74dd5
#  define IS_PYTHON3 1  /* avoid */
Packit Service b74dd5
#else
Packit Service b74dd5
#  define IS_PYTHON2 1
Packit Service b74dd5
#  define IS_PYTHON3 0
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if IS_PYTHON2
Packit Service b74dd5
#ifndef LXML_UNICODE_STRINGS
Packit Service b74dd5
#define LXML_UNICODE_STRINGS 0
Packit Service b74dd5
#endif
Packit Service b74dd5
#else
Packit Service b74dd5
#undef LXML_UNICODE_STRINGS
Packit Service b74dd5
#define LXML_UNICODE_STRINGS 1
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if !IS_PYPY
Packit Service b74dd5
#  define PyWeakref_LockObject(obj)          (NULL)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
/* Threading is not currently supported by PyPy */
Packit Service b74dd5
#if IS_PYPY
Packit Service b74dd5
#  ifndef WITHOUT_THREADING
Packit Service b74dd5
#    define WITHOUT_THREADING
Packit Service b74dd5
#  endif
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if IS_PYPY
Packit Service b74dd5
#  undef PyFile_AsFile
Packit Service b74dd5
#  define PyFile_AsFile(o)                   (NULL)
Packit Service b74dd5
#  undef PyByteArray_Check
Packit Service b74dd5
#  define PyByteArray_Check(o)               (0)
Packit Service b74dd5
#elif !IS_PYTHON2
Packit Service b74dd5
   /* Python 3+ doesn't have PyFile_*() anymore */
Packit Service b74dd5
#  define PyFile_AsFile(o)                   (NULL)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if PY_VERSION_HEX <= 0x03030000 && !(defined(CYTHON_PEP393_ENABLED) && CYTHON_PEP393_ENABLED)
Packit Service b74dd5
  #define PyUnicode_IS_READY(op)    (0)
Packit Service b74dd5
  #define PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
Packit Service b74dd5
  #define PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
Packit Service b74dd5
  #define PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if IS_PYPY
Packit Service b74dd5
#  ifndef PyUnicode_FromFormat
Packit Service b74dd5
#    define PyUnicode_FromFormat  PyString_FromFormat
Packit Service b74dd5
#  endif
Packit Service b74dd5
#  if !IS_PYTHON2 && !defined(PyBytes_FromFormat)
Packit Service b74dd5
#    ifdef PyString_FromFormat
Packit Service b74dd5
#      define PyBytes_FromFormat  PyString_FromFormat
Packit Service b74dd5
#    else
Packit Service b74dd5
#include <stdarg.h>
Packit Service b74dd5
static PyObject* PyBytes_FromFormat(const char* format, ...) {
Packit Service b74dd5
    PyObject *string;
Packit Service b74dd5
    va_list vargs;
Packit Service b74dd5
#ifdef HAVE_STDARG_PROTOTYPES
Packit Service b74dd5
    va_start(vargs, format);
Packit Service b74dd5
#else
Packit Service b74dd5
    va_start(vargs);
Packit Service b74dd5
#endif
Packit Service b74dd5
    string = PyUnicode_FromFormatV(format, vargs);
Packit Service b74dd5
    va_end(vargs);
Packit Service b74dd5
    if (string && PyUnicode_Check(string)) {
Packit Service b74dd5
        PyObject *bstring = PyUnicode_AsUTF8String(string);
Packit Service b74dd5
        Py_DECREF(string);
Packit Service b74dd5
        string = bstring;
Packit Service b74dd5
    }
Packit Service b74dd5
    if (string && !PyBytes_CheckExact(string)) {
Packit Service b74dd5
        Py_DECREF(string);
Packit Service b74dd5
        string = NULL;
Packit Service b74dd5
        PyErr_SetString(PyExc_TypeError, "String formatting and encoding failed to return bytes object");
Packit Service b74dd5
    }
Packit Service b74dd5
    return string;
Packit Service b74dd5
}
Packit Service b74dd5
#    endif
Packit Service b74dd5
#  endif
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
/* PySlice_GetIndicesEx() has wrong signature in Py<=3.1 */
Packit Service b74dd5
#if PY_VERSION_HEX >= 0x03020000
Packit Service b74dd5
#  define _lx_PySlice_GetIndicesEx(o, l, b, e, s, sl) PySlice_GetIndicesEx(o, l, b, e, s, sl)
Packit Service b74dd5
#else
Packit Service b74dd5
#  define _lx_PySlice_GetIndicesEx(o, l, b, e, s, sl) PySlice_GetIndicesEx(((PySliceObject*)o), l, b, e, s, sl)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#ifdef WITHOUT_THREADING
Packit Service b74dd5
#  undef PyEval_SaveThread
Packit Service b74dd5
#  define PyEval_SaveThread() (NULL)
Packit Service b74dd5
#  undef PyEval_RestoreThread
Packit Service b74dd5
#  define PyEval_RestoreThread(state)  if (state); else {}
Packit Service b74dd5
#  undef PyGILState_Ensure
Packit Service b74dd5
#  define PyGILState_Ensure() (PyGILState_UNLOCKED)
Packit Service b74dd5
#  undef PyGILState_Release
Packit Service b74dd5
#  define PyGILState_Release(state)  if (state); else {}
Packit Service b74dd5
#  undef  Py_UNBLOCK_THREADS
Packit Service b74dd5
#  define Py_UNBLOCK_THREADS  _save = NULL;
Packit Service b74dd5
#  undef  Py_BLOCK_THREADS
Packit Service b74dd5
#  define Py_BLOCK_THREADS  if (_save); else {}
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#ifdef WITHOUT_THREADING
Packit Service b74dd5
#  define ENABLE_THREADING 0
Packit Service b74dd5
#else
Packit Service b74dd5
#  define ENABLE_THREADING 1
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if LIBXML_VERSION < 20704
Packit Service b74dd5
/* FIXME: hack to make new error reporting compile in old libxml2 versions */
Packit Service b74dd5
#  define xmlStructuredErrorContext NULL
Packit Service b74dd5
#  define xmlXIncludeProcessTreeFlagsData(n,o,d) xmlXIncludeProcessTreeFlags(n,o)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
/* schematron was added in libxml2 2.6.21 */
Packit Service b74dd5
#ifdef LIBXML_SCHEMATRON_ENABLED
Packit Service b74dd5
#  define ENABLE_SCHEMATRON 1
Packit Service b74dd5
#else
Packit Service b74dd5
#  define ENABLE_SCHEMATRON 0
Packit Service b74dd5
#  define XML_SCHEMATRON_OUT_QUIET 0
Packit Service b74dd5
#  define XML_SCHEMATRON_OUT_XML 0
Packit Service b74dd5
#  define XML_SCHEMATRON_OUT_ERROR 0
Packit Service b74dd5
   typedef void xmlSchematron;
Packit Service b74dd5
   typedef void xmlSchematronParserCtxt;
Packit Service b74dd5
   typedef void xmlSchematronValidCtxt;
Packit Service b74dd5
#  define xmlSchematronNewDocParserCtxt(doc) NULL
Packit Service b74dd5
#  define xmlSchematronNewParserCtxt(file) NULL
Packit Service b74dd5
#  define xmlSchematronParse(ctxt) NULL
Packit Service b74dd5
#  define xmlSchematronFreeParserCtxt(ctxt)
Packit Service b74dd5
#  define xmlSchematronFree(schema)
Packit Service b74dd5
#  define xmlSchematronNewValidCtxt(schema, options) NULL
Packit Service b74dd5
#  define xmlSchematronValidateDoc(ctxt, doc) 0
Packit Service b74dd5
#  define xmlSchematronFreeValidCtxt(ctxt)
Packit Service b74dd5
#  define xmlSchematronSetValidStructuredErrors(ctxt, errorfunc, data)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#if LIBXML_VERSION < 20708
Packit Service b74dd5
#  define HTML_PARSE_NODEFDTD 4
Packit Service b74dd5
#endif
Packit Service b74dd5
#if LIBXML_VERSION < 20900
Packit Service b74dd5
#  define XML_PARSE_BIG_LINES 4194304
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#include "libxml/tree.h"
Packit Service b74dd5
#ifndef LIBXML2_NEW_BUFFER
Packit Service b74dd5
   typedef xmlBuffer xmlBuf;
Packit Service b74dd5
#  define xmlBufContent(buf) xmlBufferContent(buf)
Packit Service b74dd5
#  define xmlBufUse(buf) xmlBufferLength(buf)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
/* libexslt 1.1.25+ support EXSLT functions in XPath */
Packit Service b74dd5
#if LIBXSLT_VERSION < 10125
Packit Service b74dd5
#define exsltDateXpathCtxtRegister(ctxt, prefix)
Packit Service b74dd5
#define exsltSetsXpathCtxtRegister(ctxt, prefix)
Packit Service b74dd5
#define exsltMathXpathCtxtRegister(ctxt, prefix)
Packit Service b74dd5
#define exsltStrXpathCtxtRegister(ctxt, prefix)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#define LXML_GET_XSLT_ENCODING(result_var, style) XSLT_GET_IMPORT_PTR(result_var, style, encoding)
Packit Service b74dd5
Packit Service b74dd5
/* work around MSDEV 6.0 */
Packit Service b74dd5
#if (_MSC_VER == 1200) && (WINVER < 0x0500)
Packit Service b74dd5
long _ftol( double ); //defined by VC6 C libs
Packit Service b74dd5
long _ftol2( double dblSource ) { return _ftol( dblSource ); }
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#ifdef __GNUC__
Packit Service b74dd5
/* Test for GCC > 2.95 */
Packit Service b74dd5
#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
Packit Service b74dd5
#define unlikely_condition(x) __builtin_expect((x), 0)
Packit Service b74dd5
#else /* __GNUC__ > 2 ... */
Packit Service b74dd5
#define unlikely_condition(x) (x)
Packit Service b74dd5
#endif /* __GNUC__ > 2 ... */
Packit Service b74dd5
#else /* __GNUC__ */
Packit Service b74dd5
#define unlikely_condition(x) (x)
Packit Service b74dd5
#endif /* __GNUC__ */
Packit Service b74dd5
Packit Service b74dd5
#ifndef Py_TYPE
Packit Service b74dd5
  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#define PY_NEW(T) \
Packit Service b74dd5
     (((PyTypeObject*)(T))->tp_new( \
Packit Service b74dd5
             (PyTypeObject*)(T), __pyx_empty_tuple, NULL))
Packit Service b74dd5
Packit Service b74dd5
#define _fqtypename(o)  ((Py_TYPE(o))->tp_name)
Packit Service b74dd5
Packit Service b74dd5
#define lxml_malloc(count, item_size) \
Packit Service b74dd5
    (unlikely_condition((size_t)(count) > (size_t) (PY_SSIZE_T_MAX / item_size)) ? NULL : \
Packit Service b74dd5
     (PyMem_Malloc((count) * item_size)))
Packit Service b74dd5
Packit Service b74dd5
#define lxml_realloc(mem, count, item_size) \
Packit Service b74dd5
    (unlikely_condition((size_t)(count) > (size_t) (PY_SSIZE_T_MAX / item_size)) ? NULL : \
Packit Service b74dd5
     (PyMem_Realloc(mem, (count) * item_size)))
Packit Service b74dd5
Packit Service b74dd5
#define lxml_free(mem)  PyMem_Free(mem)
Packit Service b74dd5
Packit Service b74dd5
#if PY_MAJOR_VERSION < 3
Packit Service b74dd5
#define _isString(obj)   (PyString_CheckExact(obj)  || \
Packit Service b74dd5
                          PyUnicode_CheckExact(obj) || \
Packit Service b74dd5
                          PyType_IsSubtype(Py_TYPE(obj), &PyBaseString_Type))
Packit Service b74dd5
#else
Packit Service b74dd5
/* builtin subtype type checks are almost as fast as exact checks in Py2.7+
Packit Service b74dd5
 * and Unicode is more common in Py3 */
Packit Service b74dd5
#define _isString(obj)   (PyUnicode_Check(obj) || PyBytes_Check(obj))
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
#define _isElement(c_node) \
Packit Service b74dd5
        (((c_node)->type == XML_ELEMENT_NODE) || \
Packit Service b74dd5
         ((c_node)->type == XML_COMMENT_NODE) || \
Packit Service b74dd5
         ((c_node)->type == XML_ENTITY_REF_NODE) || \
Packit Service b74dd5
         ((c_node)->type == XML_PI_NODE))
Packit Service b74dd5
Packit Service b74dd5
#define _isElementOrXInclude(c_node) \
Packit Service b74dd5
        (_isElement(c_node)                     || \
Packit Service b74dd5
         ((c_node)->type == XML_XINCLUDE_START) || \
Packit Service b74dd5
         ((c_node)->type == XML_XINCLUDE_END))
Packit Service b74dd5
Packit Service b74dd5
#define _getNs(c_node) \
Packit Service b74dd5
        (((c_node)->ns == 0) ? 0 : ((c_node)->ns->href))
Packit Service b74dd5
Packit Service b74dd5
Packit Service b74dd5
/* PyCapsule was added in Py2.7 */
Packit Service b74dd5
#if PY_VERSION_HEX >= 0x02070000
Packit Service b74dd5
#include "string.h"
Packit Service b74dd5
static void* lxml_unpack_xmldoc_capsule(PyObject* capsule, int* is_owned) {
Packit Service b74dd5
    xmlDoc *c_doc;
Packit Service b74dd5
    void *context;
Packit Service b74dd5
    *is_owned = 0;
Packit Service b74dd5
    if (unlikely_condition(!PyCapsule_IsValid(capsule, (const char*)"libxml2:xmlDoc"))) {
Packit Service b74dd5
        PyErr_SetString(
Packit Service b74dd5
                PyExc_TypeError,
Packit Service b74dd5
                "Not a valid capsule. The capsule argument must be a capsule object with name libxml2:xmlDoc");
Packit Service b74dd5
        return NULL;
Packit Service b74dd5
    }
Packit Service b74dd5
    c_doc = (xmlDoc*) PyCapsule_GetPointer(capsule, (const char*)"libxml2:xmlDoc");
Packit Service b74dd5
    if (unlikely_condition(!c_doc)) return NULL;
Packit Service b74dd5
Packit Service b74dd5
    if (unlikely_condition(c_doc->type != XML_DOCUMENT_NODE && c_doc->type != XML_HTML_DOCUMENT_NODE)) {
Packit Service b74dd5
        PyErr_Format(
Packit Service b74dd5
            PyExc_ValueError,
Packit Service b74dd5
            "Illegal document provided: expected XML or HTML, found %d", (int)c_doc->type);
Packit Service b74dd5
        return NULL;
Packit Service b74dd5
    }
Packit Service b74dd5
Packit Service b74dd5
    context = PyCapsule_GetContext(capsule);
Packit Service b74dd5
    if (unlikely_condition(!context && PyErr_Occurred())) return NULL;
Packit Service b74dd5
    if (context && strcmp((const char*) context, "destructor:xmlFreeDoc") == 0) {
Packit Service b74dd5
        /* take ownership by setting destructor to NULL */
Packit Service b74dd5
        if (PyCapsule_SetDestructor(capsule, NULL) == 0) {
Packit Service b74dd5
            /* ownership transferred => invalidate capsule by clearing its name */
Packit Service b74dd5
            if (unlikely_condition(PyCapsule_SetName(capsule, NULL))) {
Packit Service b74dd5
                /* this should never happen since everything above succeeded */
Packit Service b74dd5
                xmlFreeDoc(c_doc);
Packit Service b74dd5
                return NULL;
Packit Service b74dd5
            }
Packit Service b74dd5
            *is_owned = 1;
Packit Service b74dd5
        }
Packit Service b74dd5
    }
Packit Service b74dd5
    return c_doc;
Packit Service b74dd5
}
Packit Service b74dd5
#else
Packit Service b74dd5
#  define lxml_unpack_xmldoc_capsule(capsule, is_owned)  ((((void)capsule, 0) || ((void)is_owned, 0)) ? NULL : NULL)
Packit Service b74dd5
#endif
Packit Service b74dd5
Packit Service b74dd5
/* Macro pair implementation of a depth first tree walker
Packit Service b74dd5
 *
Packit Service b74dd5
 * Calls the code block between the BEGIN and END macros for all elements
Packit Service b74dd5
 * below c_tree_top (exclusively), starting at c_node (inclusively iff
Packit Service b74dd5
 * 'inclusive' is 1).  The _ELEMENT_ variants will only stop on nodes
Packit Service b74dd5
 * that match _isElement(), the normal variant will stop on every node
Packit Service b74dd5
 * except text nodes.
Packit Service b74dd5
 * 
Packit Service b74dd5
 * To traverse the node and all of its children and siblings in Pyrex, call
Packit Service b74dd5
 *    cdef xmlNode* some_node
Packit Service b74dd5
 *    BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 1)
Packit Service b74dd5
 *    # do something with some_node
Packit Service b74dd5
 *    END_FOR_EACH_ELEMENT_FROM(some_node)
Packit Service b74dd5
 *
Packit Service b74dd5
 * To traverse only the children and siblings of a node, call
Packit Service b74dd5
 *    cdef xmlNode* some_node
Packit Service b74dd5
 *    BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 0)
Packit Service b74dd5
 *    # do something with some_node
Packit Service b74dd5
 *    END_FOR_EACH_ELEMENT_FROM(some_node)
Packit Service b74dd5
 *
Packit Service b74dd5
 * To traverse only the children, do:
Packit Service b74dd5
 *    cdef xmlNode* some_node
Packit Service b74dd5
 *    some_node = parent_node.children
Packit Service b74dd5
 *    BEGIN_FOR_EACH_ELEMENT_FROM(parent_node, some_node, 1)
Packit Service b74dd5
 *    # do something with some_node
Packit Service b74dd5
 *    END_FOR_EACH_ELEMENT_FROM(some_node)
Packit Service b74dd5
 *
Packit Service b74dd5
 * NOTE: 'some_node' MUST be a plain 'xmlNode*' !
Packit Service b74dd5
 *
Packit Service b74dd5
 * NOTE: parent modification during the walk can divert the iterator, but
Packit Service b74dd5
 *       should not segfault !
Packit Service b74dd5
 */
Packit Service b74dd5
Packit Service b74dd5
#define _LX__ELEMENT_MATCH(c_node, only_elements)  \
Packit Service b74dd5
    ((only_elements) ? (_isElement(c_node)) : 1)
Packit Service b74dd5
Packit Service b74dd5
#define _LX__ADVANCE_TO_NEXT(c_node, only_elements)                        \
Packit Service b74dd5
    while ((c_node != 0) && (!_LX__ELEMENT_MATCH(c_node, only_elements)))  \
Packit Service b74dd5
        c_node = c_node->next;
Packit Service b74dd5
Packit Service b74dd5
#define _LX__TRAVERSE_TO_NEXT(c_stop_node, c_node, only_elements)   \
Packit Service b74dd5
{                                                                   \
Packit Service b74dd5
    /* walk through children first */                               \
Packit Service b74dd5
    xmlNode* _lx__next = c_node->children;		            \
Packit Service b74dd5
    if (_lx__next != 0) {                                           \
Packit Service b74dd5
        if (c_node->type == XML_ENTITY_REF_NODE || c_node->type == XML_DTD_NODE) { \
Packit Service b74dd5
            _lx__next = 0;                                          \
Packit Service b74dd5
        } else {                                                    \
Packit Service b74dd5
            _LX__ADVANCE_TO_NEXT(_lx__next, only_elements)	    \
Packit Service b74dd5
        }                                                           \
Packit Service b74dd5
    }							            \
Packit Service b74dd5
    if ((_lx__next == 0) && (c_node != c_stop_node)) {              \
Packit Service b74dd5
        /* try siblings */                                          \
Packit Service b74dd5
        _lx__next = c_node->next;                                   \
Packit Service b74dd5
        _LX__ADVANCE_TO_NEXT(_lx__next, only_elements)              \
Packit Service b74dd5
        /* back off through parents */                              \
Packit Service b74dd5
        while (_lx__next == 0) {                                    \
Packit Service b74dd5
            c_node = c_node->parent;                                \
Packit Service b74dd5
            if (c_node == 0)                                        \
Packit Service b74dd5
                break;                                              \
Packit Service b74dd5
            if (c_node == c_stop_node)                              \
Packit Service b74dd5
                break;                                              \
Packit Service b74dd5
            if ((only_elements) && !_isElement(c_node))	            \
Packit Service b74dd5
                break;                                              \
Packit Service b74dd5
            /* we already traversed the parents -> siblings */      \
Packit Service b74dd5
            _lx__next = c_node->next;                               \
Packit Service b74dd5
            _LX__ADVANCE_TO_NEXT(_lx__next, only_elements)	    \
Packit Service b74dd5
        }                                                           \
Packit Service b74dd5
    }                                                               \
Packit Service b74dd5
    c_node = _lx__next;                                             \
Packit Service b74dd5
}
Packit Service b74dd5
Packit Service b74dd5
#define _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, only_elements)     \
Packit Service b74dd5
{									      \
Packit Service b74dd5
    if (c_node != 0) {							      \
Packit Service b74dd5
        const xmlNode* _lx__tree_top = (c_tree_top);                          \
Packit Service b74dd5
        const int _lx__only_elements = (only_elements);                       \
Packit Service b74dd5
        /* make sure we start at an element */                   	      \
Packit Service b74dd5
        if (!_LX__ELEMENT_MATCH(c_node, _lx__only_elements)) {		      \
Packit Service b74dd5
            /* we skip the node, so 'inclusive' is irrelevant */              \
Packit Service b74dd5
            if (c_node == _lx__tree_top)                                      \
Packit Service b74dd5
                c_node = 0; /* nothing to traverse */                         \
Packit Service b74dd5
            else {                                                            \
Packit Service b74dd5
                c_node = c_node->next;                                        \
Packit Service b74dd5
                _LX__ADVANCE_TO_NEXT(c_node, _lx__only_elements)              \
Packit Service b74dd5
            }                                                                 \
Packit Service b74dd5
        } else if (! (inclusive)) {                                           \
Packit Service b74dd5
            /* skip the first node */                                         \
Packit Service b74dd5
            _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements)  \
Packit Service b74dd5
        }                                                                     \
Packit Service b74dd5
                                                                              \
Packit Service b74dd5
        /* now run the user code on the elements we find */                   \
Packit Service b74dd5
        while (c_node != 0) {                                                 \
Packit Service b74dd5
            /* here goes the code to be run for each element */
Packit Service b74dd5
Packit Service b74dd5
#define _LX__END_FOR_EACH_FROM(c_node)                                        \
Packit Service b74dd5
            _LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements)  \
Packit Service b74dd5
        }                                                                     \
Packit Service b74dd5
    }                                                                         \
Packit Service b74dd5
}
Packit Service b74dd5
Packit Service b74dd5
Packit Service b74dd5
#define BEGIN_FOR_EACH_ELEMENT_FROM(c_tree_top, c_node, inclusive)   \
Packit Service b74dd5
    _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 1)
Packit Service b74dd5
Packit Service b74dd5
#define END_FOR_EACH_ELEMENT_FROM(c_node)   \
Packit Service b74dd5
    _LX__END_FOR_EACH_FROM(c_node)
Packit Service b74dd5
Packit Service b74dd5
#define BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive)   \
Packit Service b74dd5
    _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 0)
Packit Service b74dd5
Packit Service b74dd5
#define END_FOR_EACH_FROM(c_node)   \
Packit Service b74dd5
    _LX__END_FOR_EACH_FROM(c_node)
Packit Service b74dd5
Packit Service b74dd5
Packit Service b74dd5
#endif /* HAS_ETREE_DEFS_H */