Path: blob/master/venv/Lib/site-packages/lxml/includes/etree_defs.h
811 views
#ifndef HAS_ETREE_DEFS_H1#define HAS_ETREE_DEFS_H23/* quick check for Python/libxml2/libxslt devel setup */4#include "Python.h"5#ifndef PY_VERSION_HEX6# error the development package of Python (header files etc.) is not installed correctly7#else8# if PY_VERSION_HEX < 0x02070000 || PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500009# error this version of lxml requires Python 2.7, 3.5 or later10# endif11#endif1213#include "libxml/xmlversion.h"14#ifndef LIBXML_VERSION15# error the development package of libxml2 (header files etc.) is not installed correctly16#else17#if LIBXML_VERSION < 2070018# error minimum required version of libxml2 is 2.7.019#endif20#endif2122#include "libxslt/xsltconfig.h"23#ifndef LIBXSLT_VERSION24# error the development package of libxslt (header files etc.) is not installed correctly25#else26#if LIBXSLT_VERSION < 1012327# error minimum required version of libxslt is 1.1.2328#endif29#endif303132/* v_arg functions */33#define va_int(ap) va_arg(ap, int)34#define va_charptr(ap) va_arg(ap, char *)3536#ifdef PYPY_VERSION37# define IS_PYPY 138#else39# define IS_PYPY 040#endif4142#if PY_MAJOR_VERSION >= 343# define IS_PYTHON2 0 /* prefer for special casing Python 2.x */44# define IS_PYTHON3 1 /* avoid */45#else46# define IS_PYTHON2 147# define IS_PYTHON3 048#endif4950#if IS_PYTHON251#ifndef LXML_UNICODE_STRINGS52#define LXML_UNICODE_STRINGS 053#endif54#else55#undef LXML_UNICODE_STRINGS56#define LXML_UNICODE_STRINGS 157#endif5859#if !IS_PYPY60# define PyWeakref_LockObject(obj) (NULL)61#endif6263/* Threading is not currently supported by PyPy */64#if IS_PYPY65# ifndef WITHOUT_THREADING66# define WITHOUT_THREADING67# endif68#endif6970#if IS_PYPY71# undef PyFile_AsFile72# define PyFile_AsFile(o) (NULL)73# undef PyByteArray_Check74# define PyByteArray_Check(o) (0)75#elif !IS_PYTHON276/* Python 3+ doesn't have PyFile_*() anymore */77# define PyFile_AsFile(o) (NULL)78#endif7980#if PY_VERSION_HEX <= 0x03030000 && !(defined(CYTHON_PEP393_ENABLED) && CYTHON_PEP393_ENABLED)81#define PyUnicode_IS_READY(op) (0)82#define PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)83#define PyUnicode_KIND(u) (sizeof(Py_UNICODE))84#define PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))85#endif8687#if IS_PYPY88# ifndef PyUnicode_FromFormat89# define PyUnicode_FromFormat PyString_FromFormat90# endif91# if !IS_PYTHON2 && !defined(PyBytes_FromFormat)92# ifdef PyString_FromFormat93# define PyBytes_FromFormat PyString_FromFormat94# else95#include <stdarg.h>96static PyObject* PyBytes_FromFormat(const char* format, ...) {97PyObject *string;98va_list vargs;99#ifdef HAVE_STDARG_PROTOTYPES100va_start(vargs, format);101#else102va_start(vargs);103#endif104string = PyUnicode_FromFormatV(format, vargs);105va_end(vargs);106if (string && PyUnicode_Check(string)) {107PyObject *bstring = PyUnicode_AsUTF8String(string);108Py_DECREF(string);109string = bstring;110}111if (string && !PyBytes_CheckExact(string)) {112Py_DECREF(string);113string = NULL;114PyErr_SetString(PyExc_TypeError, "String formatting and encoding failed to return bytes object");115}116return string;117}118# endif119# endif120#endif121122/* PySlice_GetIndicesEx() has wrong signature in Py<=3.1 */123#if PY_VERSION_HEX >= 0x03020000124# define _lx_PySlice_GetIndicesEx(o, l, b, e, s, sl) PySlice_GetIndicesEx(o, l, b, e, s, sl)125#else126# define _lx_PySlice_GetIndicesEx(o, l, b, e, s, sl) PySlice_GetIndicesEx(((PySliceObject*)o), l, b, e, s, sl)127#endif128129#ifdef WITHOUT_THREADING130# undef PyEval_SaveThread131# define PyEval_SaveThread() (NULL)132# undef PyEval_RestoreThread133# define PyEval_RestoreThread(state) if (state); else {}134# undef PyGILState_Ensure135# define PyGILState_Ensure() (PyGILState_UNLOCKED)136# undef PyGILState_Release137# define PyGILState_Release(state) if (state); else {}138# undef Py_UNBLOCK_THREADS139# define Py_UNBLOCK_THREADS _save = NULL;140# undef Py_BLOCK_THREADS141# define Py_BLOCK_THREADS if (_save); else {}142#endif143144#ifdef WITHOUT_THREADING145# define ENABLE_THREADING 0146#else147# define ENABLE_THREADING 1148#endif149150#if LIBXML_VERSION < 20704151/* FIXME: hack to make new error reporting compile in old libxml2 versions */152# define xmlStructuredErrorContext NULL153# define xmlXIncludeProcessTreeFlagsData(n,o,d) xmlXIncludeProcessTreeFlags(n,o)154#endif155156/* schematron was added in libxml2 2.6.21 */157#ifdef LIBXML_SCHEMATRON_ENABLED158# define ENABLE_SCHEMATRON 1159#else160# define ENABLE_SCHEMATRON 0161# define XML_SCHEMATRON_OUT_QUIET 0162# define XML_SCHEMATRON_OUT_XML 0163# define XML_SCHEMATRON_OUT_ERROR 0164typedef void xmlSchematron;165typedef void xmlSchematronParserCtxt;166typedef void xmlSchematronValidCtxt;167# define xmlSchematronNewDocParserCtxt(doc) NULL168# define xmlSchematronNewParserCtxt(file) NULL169# define xmlSchematronParse(ctxt) NULL170# define xmlSchematronFreeParserCtxt(ctxt)171# define xmlSchematronFree(schema)172# define xmlSchematronNewValidCtxt(schema, options) NULL173# define xmlSchematronValidateDoc(ctxt, doc) 0174# define xmlSchematronFreeValidCtxt(ctxt)175# define xmlSchematronSetValidStructuredErrors(ctxt, errorfunc, data)176#endif177178#if LIBXML_VERSION < 20708179# define HTML_PARSE_NODEFDTD 4180#endif181#if LIBXML_VERSION < 20900182# define XML_PARSE_BIG_LINES 4194304183#endif184185#include "libxml/tree.h"186#ifndef LIBXML2_NEW_BUFFER187typedef xmlBuffer xmlBuf;188# define xmlBufContent(buf) xmlBufferContent(buf)189# define xmlBufUse(buf) xmlBufferLength(buf)190#endif191192/* libexslt 1.1.25+ support EXSLT functions in XPath */193#if LIBXSLT_VERSION < 10125194#define exsltDateXpathCtxtRegister(ctxt, prefix)195#define exsltSetsXpathCtxtRegister(ctxt, prefix)196#define exsltMathXpathCtxtRegister(ctxt, prefix)197#define exsltStrXpathCtxtRegister(ctxt, prefix)198#endif199200#define LXML_GET_XSLT_ENCODING(result_var, style) XSLT_GET_IMPORT_PTR(result_var, style, encoding)201202/* work around MSDEV 6.0 */203#if (_MSC_VER == 1200) && (WINVER < 0x0500)204long _ftol( double ); //defined by VC6 C libs205long _ftol2( double dblSource ) { return _ftol( dblSource ); }206#endif207208#ifdef __GNUC__209/* Test for GCC > 2.95 */210#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))211#define unlikely_condition(x) __builtin_expect((x), 0)212#else /* __GNUC__ > 2 ... */213#define unlikely_condition(x) (x)214#endif /* __GNUC__ > 2 ... */215#else /* __GNUC__ */216#define unlikely_condition(x) (x)217#endif /* __GNUC__ */218219#ifndef Py_TYPE220#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)221#endif222223#define PY_NEW(T) \224(((PyTypeObject*)(T))->tp_new( \225(PyTypeObject*)(T), __pyx_empty_tuple, NULL))226227#define _fqtypename(o) ((Py_TYPE(o))->tp_name)228229#define lxml_malloc(count, item_size) \230(unlikely_condition((size_t)(count) > (size_t) (PY_SSIZE_T_MAX / item_size)) ? NULL : \231(PyMem_Malloc((count) * item_size)))232233#define lxml_realloc(mem, count, item_size) \234(unlikely_condition((size_t)(count) > (size_t) (PY_SSIZE_T_MAX / item_size)) ? NULL : \235(PyMem_Realloc(mem, (count) * item_size)))236237#define lxml_free(mem) PyMem_Free(mem)238239#if PY_MAJOR_VERSION < 3240#define _isString(obj) (PyString_CheckExact(obj) || \241PyUnicode_CheckExact(obj) || \242PyType_IsSubtype(Py_TYPE(obj), &PyBaseString_Type))243#else244/* builtin subtype type checks are almost as fast as exact checks in Py2.7+245* and Unicode is more common in Py3 */246#define _isString(obj) (PyUnicode_Check(obj) || PyBytes_Check(obj))247#endif248249#define _isElement(c_node) \250(((c_node)->type == XML_ELEMENT_NODE) || \251((c_node)->type == XML_COMMENT_NODE) || \252((c_node)->type == XML_ENTITY_REF_NODE) || \253((c_node)->type == XML_PI_NODE))254255#define _isElementOrXInclude(c_node) \256(_isElement(c_node) || \257((c_node)->type == XML_XINCLUDE_START) || \258((c_node)->type == XML_XINCLUDE_END))259260#define _getNs(c_node) \261(((c_node)->ns == 0) ? 0 : ((c_node)->ns->href))262263264#include "string.h"265static void* lxml_unpack_xmldoc_capsule(PyObject* capsule, int* is_owned) {266xmlDoc *c_doc;267void *context;268*is_owned = 0;269if (unlikely_condition(!PyCapsule_IsValid(capsule, (const char*)"libxml2:xmlDoc"))) {270PyErr_SetString(271PyExc_TypeError,272"Not a valid capsule. The capsule argument must be a capsule object with name libxml2:xmlDoc");273return NULL;274}275c_doc = (xmlDoc*) PyCapsule_GetPointer(capsule, (const char*)"libxml2:xmlDoc");276if (unlikely_condition(!c_doc)) return NULL;277278if (unlikely_condition(c_doc->type != XML_DOCUMENT_NODE && c_doc->type != XML_HTML_DOCUMENT_NODE)) {279PyErr_Format(280PyExc_ValueError,281"Illegal document provided: expected XML or HTML, found %d", (int)c_doc->type);282return NULL;283}284285context = PyCapsule_GetContext(capsule);286if (unlikely_condition(!context && PyErr_Occurred())) return NULL;287if (context && strcmp((const char*) context, "destructor:xmlFreeDoc") == 0) {288/* take ownership by setting destructor to NULL */289if (PyCapsule_SetDestructor(capsule, NULL) == 0) {290/* ownership transferred => invalidate capsule by clearing its name */291if (unlikely_condition(PyCapsule_SetName(capsule, NULL))) {292/* this should never happen since everything above succeeded */293xmlFreeDoc(c_doc);294return NULL;295}296*is_owned = 1;297}298}299return c_doc;300}301302/* Macro pair implementation of a depth first tree walker303*304* Calls the code block between the BEGIN and END macros for all elements305* below c_tree_top (exclusively), starting at c_node (inclusively iff306* 'inclusive' is 1). The _ELEMENT_ variants will only stop on nodes307* that match _isElement(), the normal variant will stop on every node308* except text nodes.309*310* To traverse the node and all of its children and siblings in Pyrex, call311* cdef xmlNode* some_node312* BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 1)313* # do something with some_node314* END_FOR_EACH_ELEMENT_FROM(some_node)315*316* To traverse only the children and siblings of a node, call317* cdef xmlNode* some_node318* BEGIN_FOR_EACH_ELEMENT_FROM(some_node.parent, some_node, 0)319* # do something with some_node320* END_FOR_EACH_ELEMENT_FROM(some_node)321*322* To traverse only the children, do:323* cdef xmlNode* some_node324* some_node = parent_node.children325* BEGIN_FOR_EACH_ELEMENT_FROM(parent_node, some_node, 1)326* # do something with some_node327* END_FOR_EACH_ELEMENT_FROM(some_node)328*329* NOTE: 'some_node' MUST be a plain 'xmlNode*' !330*331* NOTE: parent modification during the walk can divert the iterator, but332* should not segfault !333*/334335#define _LX__ELEMENT_MATCH(c_node, only_elements) \336((only_elements) ? (_isElement(c_node)) : 1)337338#define _LX__ADVANCE_TO_NEXT(c_node, only_elements) \339while ((c_node != 0) && (!_LX__ELEMENT_MATCH(c_node, only_elements))) \340c_node = c_node->next;341342#define _LX__TRAVERSE_TO_NEXT(c_stop_node, c_node, only_elements) \343{ \344/* walk through children first */ \345xmlNode* _lx__next = c_node->children; \346if (_lx__next != 0) { \347if (c_node->type == XML_ENTITY_REF_NODE || c_node->type == XML_DTD_NODE) { \348_lx__next = 0; \349} else { \350_LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \351} \352} \353if ((_lx__next == 0) && (c_node != c_stop_node)) { \354/* try siblings */ \355_lx__next = c_node->next; \356_LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \357/* back off through parents */ \358while (_lx__next == 0) { \359c_node = c_node->parent; \360if (c_node == 0) \361break; \362if (c_node == c_stop_node) \363break; \364if ((only_elements) && !_isElement(c_node)) \365break; \366/* we already traversed the parents -> siblings */ \367_lx__next = c_node->next; \368_LX__ADVANCE_TO_NEXT(_lx__next, only_elements) \369} \370} \371c_node = _lx__next; \372}373374#define _LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, only_elements) \375{ \376if (c_node != 0) { \377const xmlNode* _lx__tree_top = (c_tree_top); \378const int _lx__only_elements = (only_elements); \379/* make sure we start at an element */ \380if (!_LX__ELEMENT_MATCH(c_node, _lx__only_elements)) { \381/* we skip the node, so 'inclusive' is irrelevant */ \382if (c_node == _lx__tree_top) \383c_node = 0; /* nothing to traverse */ \384else { \385c_node = c_node->next; \386_LX__ADVANCE_TO_NEXT(c_node, _lx__only_elements) \387} \388} else if (! (inclusive)) { \389/* skip the first node */ \390_LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements) \391} \392\393/* now run the user code on the elements we find */ \394while (c_node != 0) { \395/* here goes the code to be run for each element */396397#define _LX__END_FOR_EACH_FROM(c_node) \398_LX__TRAVERSE_TO_NEXT(_lx__tree_top, c_node, _lx__only_elements) \399} \400} \401}402403404#define BEGIN_FOR_EACH_ELEMENT_FROM(c_tree_top, c_node, inclusive) \405_LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 1)406407#define END_FOR_EACH_ELEMENT_FROM(c_node) \408_LX__END_FOR_EACH_FROM(c_node)409410#define BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive) \411_LX__BEGIN_FOR_EACH_FROM(c_tree_top, c_node, inclusive, 0)412413#define END_FOR_EACH_FROM(c_node) \414_LX__END_FOR_EACH_FROM(c_node)415416417#endif /* HAS_ETREE_DEFS_H */418419420