diff options
Diffstat (limited to 'python')
-rwxr-xr-x | python/generator.py | 10 | ||||
-rw-r--r-- | python/libxml.c | 169 | ||||
-rw-r--r-- | python/libxml.py | 5 | ||||
-rw-r--r-- | python/libxml2-py.c | 315 | ||||
-rw-r--r-- | python/libxml2-python-api.xml | 8 | ||||
-rwxr-xr-x | python/setup.py | 2 | ||||
-rw-r--r-- | python/tests/Makefile.am | 10 | ||||
-rw-r--r-- | python/tests/Makefile.in | 10 | ||||
-rwxr-xr-x | python/tests/sync.py | 135 |
9 files changed, 464 insertions, 200 deletions
diff --git a/python/generator.py b/python/generator.py index 4c6c8ab..3ae5729 100755 --- a/python/generator.py +++ b/python/generator.py @@ -302,6 +302,8 @@ def skip_function(name): return 1 if name == "xmlFreeParserCtxt": return 1 + if name == "xmlCleanupParser": + return 1 if name == "xmlFreeTextReader": return 1 # if name[0:11] == "xmlXPathNew": @@ -1037,17 +1039,25 @@ def buildWrappers(): classes.write(" self.%s = None\n" % ref[1]) classes.write(" if _obj != None:self._o = _obj;return\n") classes.write(" self._o = None\n\n"); + destruct=None if classes_destructors.has_key(classname): classes.write(" def __del__(self):\n") classes.write(" if self._o != None:\n") classes.write(" libxml2mod.%s(self._o)\n" % classes_destructors[classname]); classes.write(" self._o = None\n\n"); + destruct=classes_destructors[classname] flist = function_classes[classname] flist.sort(functionCompare) oldfile = "" for info in flist: (index, func, name, ret, args, file) = info + # + # Do not provide as method the destructors for the class + # to avoid double free + # + if name == destruct: + continue; if file != oldfile: if file == "python_accessor": classes.write(" # accessors for %s\n" % (classname)) diff --git a/python/libxml.c b/python/libxml.c index 4ab69fb..3db0f5f 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -52,6 +52,22 @@ void initlibxml2mod(void); xmlGenericError(xmlGenericErrorContext, \ "Unimplemented block at %s:%d\n", \ __FILE__, __LINE__); +/* + * the following vars are used for XPath extensions, but + * are also referenced within the parser cleanup routine. + */ +static int libxml_xpathCallbacksInitialized = 0; + +typedef struct libxml_xpathCallback { + xmlXPathContextPtr ctx; + xmlChar *name; + xmlChar *ns_uri; + PyObject *function; +} libxml_xpathCallback, *libxml_xpathCallbackPtr; +typedef libxml_xpathCallback libxml_xpathCallbackArray[]; +static int libxml_xpathCallbacksAllocd = 10; +static libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL; +static int libxml_xpathCallbacksNb = 0; /************************************************************************ * * @@ -75,6 +91,21 @@ static xmlMallocFunc mallocFunc = NULL; static xmlReallocFunc reallocFunc = NULL; static xmlStrdupFunc strdupFunc = NULL; +static void +libxml_xmlErrorInitialize(void); /* forward declare */ + +PyObject * +libxml_xmlMemoryUsed(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) +{ + long ret; + PyObject *py_retval; + + ret = xmlMemUsed(); + + py_retval = libxml_longWrap(ret); + return (py_retval); +} + PyObject * libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { @@ -104,13 +135,21 @@ libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) (strdupFunc == xmlMemoryStrdup)) { libxmlMemoryAllocatedBase = xmlMemUsed(); } else { + /* + * cleanup first, because some memory has been + * allocated with the non-debug malloc in xmlInitParser + * when the python module was imported + */ + xmlCleanupParser(); ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup); if (ret < 0) goto error; libxmlMemoryAllocatedBase = xmlMemUsed(); + /* reinitialize */ + xmlInitParser(); + libxml_xmlErrorInitialize(); } - xmlInitParser(); ret = 0; } else if (libxmlMemoryDebugActivated == 0) { libxmlMemoryAllocatedBase = xmlMemUsed(); @@ -133,6 +172,46 @@ libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) } PyObject * +libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + + int ix; + long freed = -1; + + if (libxmlMemoryDebug) { + freed = xmlMemUsed(); + } + + xmlCleanupParser(); + /* + * Need to confirm whether we really want to do this (required for + * memcheck) in all cases... + */ + + if (libxml_xpathCallbacks != NULL) { /* if ext funcs declared */ + for (ix=0; ix<libxml_xpathCallbacksNb; ix++) { + if ((*libxml_xpathCallbacks)[ix].name != NULL) + xmlFree((*libxml_xpathCallbacks)[ix].name); + if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL) + xmlFree((*libxml_xpathCallbacks)[ix].ns_uri); + } + libxml_xpathCallbacksNb = 0; + xmlFree(libxml_xpathCallbacks); + libxml_xpathCallbacks = NULL; + } + + if (libxmlMemoryDebug) { + freed -= xmlMemUsed(); + libxmlMemoryAllocatedBase -= freed; + if (libxmlMemoryAllocatedBase < 0) + libxmlMemoryAllocatedBase = 0; + } + + Py_INCREF(Py_None); + return(Py_None); +} + +PyObject * libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self, ATTRIBUTE_UNUSED PyObject * args) { @@ -1386,7 +1465,7 @@ libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self, return (NULL); #ifdef DEBUG_ERROR - printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx, + printf("libxml_xmlRegisterErrorHandler(%p, %p) called\n", pyobj_ctx, pyobj_f); #endif @@ -1776,18 +1855,6 @@ libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { * * ************************************************************************/ -static int libxml_xpathCallbacksInitialized = 0; - -typedef struct libxml_xpathCallback { - xmlXPathContextPtr ctx; - xmlChar *name; - xmlChar *ns_uri; - PyObject *function; -} libxml_xpathCallback, *libxml_xpathCallbackPtr; -static libxml_xpathCallback libxml_xpathCallbacks[10]; -static int libxml_xpathCallbacksNb = 0; -static int libxml_xpathCallbacksMax = 10; - static void libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) { @@ -1816,9 +1883,9 @@ libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) */ for (i = 0; i < libxml_xpathCallbacksNb; i++) { if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */ - (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) && - (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) { - current_function = libxml_xpathCallbacks[i].function; + (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && + (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { + current_function = (*libxml_xpathCallbacks)[i].function; } } if (current_function == NULL) { @@ -1859,9 +1926,9 @@ libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name, * and functionURI fields. */ for (i = 0; i < libxml_xpathCallbacksNb; i++) { - if ((ctxt == libxml_xpathCallbacks[i].ctx) && - (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) && - (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) { + if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) && + (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && + (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { return (libxml_xmlXPathFuncCallback); } } @@ -1879,12 +1946,14 @@ libxml_xpathCallbacksInitialize(void) #ifdef DEBUG_XPATH printf("libxml_xpathCallbacksInitialized called\n"); #endif + libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc( + libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback)); - for (i = 0; i < libxml_xpathCallbacksMax; i++) { - libxml_xpathCallbacks[i].ctx = NULL; - libxml_xpathCallbacks[i].name = NULL; - libxml_xpathCallbacks[i].ns_uri = NULL; - libxml_xpathCallbacks[i].function = NULL; + for (i = 0; i < libxml_xpathCallbacksAllocd; i++) { + (*libxml_xpathCallbacks)[i].ctx = NULL; + (*libxml_xpathCallbacks)[i].name = NULL; + (*libxml_xpathCallbacks)[i].ns_uri = NULL; + (*libxml_xpathCallbacks)[i].function = NULL; } libxml_xpathCallbacksInitialized = 1; } @@ -1921,27 +1990,30 @@ libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self, ctx, name, ns_uri); #endif for (i = 0; i < libxml_xpathCallbacksNb; i++) { - if ((ctx == libxml_xpathCallbacks[i].ctx) && - (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) && - (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) { + if ((ctx == (*libxml_xpathCallbacks)[i].ctx) && + (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && + (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { Py_XINCREF(pyobj_f); - Py_XDECREF(libxml_xpathCallbacks[i].function); - libxml_xpathCallbacks[i].function = pyobj_f; + Py_XDECREF((*libxml_xpathCallbacks)[i].function); + (*libxml_xpathCallbacks)[i].function = pyobj_f; c_retval = 1; goto done; } } - if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) { - printf("libxml_registerXPathFunction() table full\n"); - } else { - i = libxml_xpathCallbacksNb++; - Py_XINCREF(pyobj_f); - libxml_xpathCallbacks[i].ctx = ctx; - libxml_xpathCallbacks[i].name = xmlStrdup(name); - libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri); - libxml_xpathCallbacks[i].function = pyobj_f; + if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) { + libxml_xpathCallbacksAllocd+=10; + libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc( + libxml_xpathCallbacks, + libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback)); + } + i = libxml_xpathCallbacksNb++; + Py_XINCREF(pyobj_f); + (*libxml_xpathCallbacks)[i].ctx = ctx; + (*libxml_xpathCallbacks)[i].name = xmlStrdup(name); + (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri); + (*libxml_xpathCallbacks)[i].function = pyobj_f; c_retval = 1; - } + done: py_retval = libxml_intWrap((int) c_retval); return (py_retval); @@ -3228,20 +3300,19 @@ void initlibxml2mod(void) { static int initialized = 0; - PyObject *m; if (initialized != 0) return; - /* XXX xmlInitParser does much more than this */ - xmlInitGlobals(); -#ifdef LIBXML_OUTPUT_ENABLED - xmlRegisterDefaultOutputCallbacks(); -#endif /* LIBXML_OUTPUT_ENABLED */ - xmlRegisterDefaultInputCallbacks(); - m = Py_InitModule((char *) "libxml2mod", libxmlMethods); - initialized = 1; + + /* intialize the python extension module */ + Py_InitModule((char *) "libxml2mod", libxmlMethods); + + /* initialize libxml2 */ + xmlInitParser(); libxml_xmlErrorInitialize(); + initialized = 1; + #ifdef MERGED_MODULES initlibxsltmod(); #endif diff --git a/python/libxml.py b/python/libxml.py index 0c3ba6c..5980974 100644 --- a/python/libxml.py +++ b/python/libxml.py @@ -618,6 +618,11 @@ class xmlTextReaderCore: # assert f is _xmlTextReaderErrorFunc return arg +# +# The cleanup now goes though a wrappe in libxml.c +# +def cleanupParser(): + libxml2mod.xmlPythonCleanupParser() # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # diff --git a/python/libxml2-py.c b/python/libxml2-py.c index f70d4f8..a0a6958 100644 --- a/python/libxml2-py.c +++ b/python/libxml2-py.c @@ -123,6 +123,22 @@ libxml_xmlReaderForFile(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { return(py_retval); } +#ifdef LIBXML_XPATH_ENABLED +PyObject * +libxml_xmlXPathNewFloat(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + xmlXPathObjectPtr c_retval; + double val; + + if (!PyArg_ParseTuple(args, (char *)"d:xmlXPathNewFloat", &val)) + return(NULL); + + c_retval = xmlXPathNewFloat(val); + py_retval = libxml_xmlXPathObjectPtrWrap((xmlXPathObjectPtr) c_retval); + return(py_retval); +} + +#endif /* LIBXML_XPATH_ENABLED */ PyObject * libxml_xmlTextReaderExpand(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; @@ -1771,23 +1787,6 @@ libxml_xmlNormalizeURIPath(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { } PyObject * -libxml_xmlNewTextReader(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - xmlTextReaderPtr c_retval; - xmlParserInputBufferPtr input; - PyObject *pyobj_input; - char * URI; - - if (!PyArg_ParseTuple(args, (char *)"Oz:xmlNewTextReader", &pyobj_input, &URI)) - return(NULL); - input = (xmlParserInputBufferPtr) PyinputBuffer_Get(pyobj_input); - - c_retval = xmlNewTextReader(input, URI); - py_retval = libxml_xmlTextReaderPtrWrap((xmlTextReaderPtr) c_retval); - return(py_retval); -} - -PyObject * libxml_xmlUCSIsCombiningDiacriticalMarksforSymbols(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -1855,24 +1854,6 @@ libxml_xmlParserInputBufferRead(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) return(py_retval); } -#ifdef LIBXML_XPATH_ENABLED -PyObject * -libxml_xmlXPathOrderDocElems(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - long c_retval; - xmlDocPtr doc; - PyObject *pyobj_doc; - - if (!PyArg_ParseTuple(args, (char *)"O:xmlXPathOrderDocElems", &pyobj_doc)) - return(NULL); - doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); - - c_retval = xmlXPathOrderDocElems(doc); - py_retval = libxml_intWrap((int) c_retval); - return(py_retval); -} - -#endif /* LIBXML_XPATH_ENABLED */ PyObject * libxml_xmlUCSIsLinearBIdeograms(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; @@ -1967,22 +1948,6 @@ libxml_xmlCtxtReadFile(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #ifdef LIBXML_XPATH_ENABLED PyObject * -libxml_xmlXPathNewFloat(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - xmlXPathObjectPtr c_retval; - double val; - - if (!PyArg_ParseTuple(args, (char *)"d:xmlXPathNewFloat", &val)) - return(NULL); - - c_retval = xmlXPathNewFloat(val); - py_retval = libxml_xmlXPathObjectPtrWrap((xmlXPathObjectPtr) c_retval); - return(py_retval); -} - -#endif /* LIBXML_XPATH_ENABLED */ -#ifdef LIBXML_XPATH_ENABLED -PyObject * libxml_xmlXPathRegisterNs(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -2641,27 +2606,6 @@ libxml_xmlRelaxNGValidateDoc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* LIBXML_SCHEMAS_ENABLED */ PyObject * -libxml_xmlNewChild(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - xmlNodePtr c_retval; - xmlNodePtr parent; - PyObject *pyobj_parent; - xmlNsPtr ns; - PyObject *pyobj_ns; - xmlChar * name; - xmlChar * content; - - if (!PyArg_ParseTuple(args, (char *)"OOzz:xmlNewChild", &pyobj_parent, &pyobj_ns, &name, &content)) - return(NULL); - parent = (xmlNodePtr) PyxmlNode_Get(pyobj_parent); - ns = (xmlNsPtr) PyxmlNode_Get(pyobj_ns); - - c_retval = xmlNewChild(parent, ns, name, content); - py_retval = libxml_xmlNodePtrWrap((xmlNodePtr) c_retval); - return(py_retval); -} - -PyObject * libxml_xmlSearchNs(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlNsPtr c_retval; @@ -2886,23 +2830,6 @@ libxml_xmlXPathNextNamespace(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* LIBXML_XPATH_ENABLED */ PyObject * -libxml_xmlTextReaderRelaxNGValidate(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - int c_retval; - xmlTextReaderPtr reader; - PyObject *pyobj_reader; - char * rng; - - if (!PyArg_ParseTuple(args, (char *)"Oz:xmlTextReaderRelaxNGValidate", &pyobj_reader, &rng)) - return(NULL); - reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader); - - c_retval = xmlTextReaderRelaxNGValidate(reader, rng); - py_retval = libxml_intWrap((int) c_retval); - return(py_retval); -} - -PyObject * libxml_xmlNewDocText(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlNodePtr c_retval; @@ -3102,25 +3029,27 @@ libxml_xmlThrDefLineNumbersDefaultValue(PyObject *self ATTRIBUTE_UNUSED, PyObjec return(py_retval); } -#ifdef LIBXML_XINCLUDE_ENABLED PyObject * -libxml_xmlXIncludeProcessTreeFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { +libxml_xmlNewChild(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; - int c_retval; - xmlNodePtr tree; - PyObject *pyobj_tree; - int flags; + xmlNodePtr c_retval; + xmlNodePtr parent; + PyObject *pyobj_parent; + xmlNsPtr ns; + PyObject *pyobj_ns; + xmlChar * name; + xmlChar * content; - if (!PyArg_ParseTuple(args, (char *)"Oi:xmlXIncludeProcessTreeFlags", &pyobj_tree, &flags)) + if (!PyArg_ParseTuple(args, (char *)"OOzz:xmlNewChild", &pyobj_parent, &pyobj_ns, &name, &content)) return(NULL); - tree = (xmlNodePtr) PyxmlNode_Get(pyobj_tree); + parent = (xmlNodePtr) PyxmlNode_Get(pyobj_parent); + ns = (xmlNsPtr) PyxmlNode_Get(pyobj_ns); - c_retval = xmlXIncludeProcessTreeFlags(tree, flags); - py_retval = libxml_intWrap((int) c_retval); + c_retval = xmlNewChild(parent, ns, name, content); + py_retval = libxml_xmlNodePtrWrap((xmlNodePtr) c_retval); return(py_retval); } -#endif /* LIBXML_XINCLUDE_ENABLED */ PyObject * libxml_xmlGetID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; @@ -4058,6 +3987,20 @@ libxml_xmlConvertSGMLCatalog(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { } PyObject * +libxml_xmlParserHandleReference(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + xmlParserCtxtPtr ctxt; + PyObject *pyobj_ctxt; + + if (!PyArg_ParseTuple(args, (char *)"O:xmlParserHandleReference", &pyobj_ctxt)) + return(NULL); + ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); + + xmlParserHandleReference(ctxt); + Py_INCREF(Py_None); + return(Py_None); +} + +PyObject * libxml_xmlEncodeEntitiesReentrant(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlChar * c_retval; @@ -5153,6 +5096,20 @@ libxml_xmlNewReference(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { } PyObject * +libxml_xmlUCSIsCJKSymbolsandPunctuation(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + int code; + + if (!PyArg_ParseTuple(args, (char *)"i:xmlUCSIsCJKSymbolsandPunctuation", &code)) + return(NULL); + + c_retval = xmlUCSIsCJKSymbolsandPunctuation(code); + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +PyObject * libxml_xmlUCSIsOgham(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -6021,22 +5978,6 @@ libxml_xmlXPathPopString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* LIBXML_XPATH_ENABLED */ PyObject * -libxml_xmlURIGetPort(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - int c_retval; - xmlURIPtr URI; - PyObject *pyobj_URI; - - if (!PyArg_ParseTuple(args, (char *)"O:xmlURIGetPort", &pyobj_URI)) - return(NULL); - URI = (xmlURIPtr) PyURI_Get(pyobj_URI); - - c_retval = URI->port; - py_retval = libxml_intWrap((int) c_retval); - return(py_retval); -} - -PyObject * libxml_xmlUCSIsCatC(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -6307,14 +6248,6 @@ libxml_xmlXPtrNewCollapsedRange(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) #endif /* LIBXML_XPTR_ENABLED */ PyObject * -libxml_xmlCleanupParser(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) { - - xmlCleanupParser(); - Py_INCREF(Py_None); - return(Py_None); -} - -PyObject * libxml_xmlTextConcat(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -6706,17 +6639,20 @@ libxml_xmlStrchr(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { } PyObject * -libxml_xmlParserHandleReference(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - xmlParserCtxtPtr ctxt; - PyObject *pyobj_ctxt; +libxml_xmlNewTextReader(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + xmlTextReaderPtr c_retval; + xmlParserInputBufferPtr input; + PyObject *pyobj_input; + char * URI; - if (!PyArg_ParseTuple(args, (char *)"O:xmlParserHandleReference", &pyobj_ctxt)) + if (!PyArg_ParseTuple(args, (char *)"Oz:xmlNewTextReader", &pyobj_input, &URI)) return(NULL); - ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); + input = (xmlParserInputBufferPtr) PyinputBuffer_Get(pyobj_input); - xmlParserHandleReference(ctxt); - Py_INCREF(Py_None); - return(Py_None); + c_retval = xmlNewTextReader(input, URI); + py_retval = libxml_xmlTextReaderPtrWrap((xmlTextReaderPtr) c_retval); + return(py_retval); } PyObject * @@ -9212,6 +9148,21 @@ libxml_xmlNanoHTTPCleanup(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIB } PyObject * +libxml_xmlBuildRelativeURI(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + xmlChar * c_retval; + xmlChar * URI; + xmlChar * base; + + if (!PyArg_ParseTuple(args, (char *)"zz:xmlBuildRelativeURI", &URI, &base)) + return(NULL); + + c_retval = xmlBuildRelativeURI(URI, base); + py_retval = libxml_xmlCharPtrWrap((xmlChar *) c_retval); + return(py_retval); +} + +PyObject * libxml_xmlParseQuotedString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlChar * c_retval; @@ -9381,20 +9332,6 @@ libxml_xmlCatalogConvert(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBU } PyObject * -libxml_xmlUCSIsCJKSymbolsandPunctuation(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { - PyObject *py_retval; - int c_retval; - int code; - - if (!PyArg_ParseTuple(args, (char *)"i:xmlUCSIsCJKSymbolsandPunctuation", &code)) - return(NULL); - - c_retval = xmlUCSIsCJKSymbolsandPunctuation(code); - py_retval = libxml_intWrap((int) c_retval); - return(py_retval); -} - -PyObject * libxml_xmlUCSIsTaiXuanJingSymbols(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -9430,6 +9367,23 @@ libxml_htmlDocDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* LIBXML_HTML_ENABLED */ PyObject * +libxml_xmlTextReaderRelaxNGValidate(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlTextReaderPtr reader; + PyObject *pyobj_reader; + char * rng; + + if (!PyArg_ParseTuple(args, (char *)"Oz:xmlTextReaderRelaxNGValidate", &pyobj_reader, &rng)) + return(NULL); + reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader); + + c_retval = xmlTextReaderRelaxNGValidate(reader, rng); + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +PyObject * libxml_xmlNanoFTPInit(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) { xmlNanoFTPInit(); @@ -9763,6 +9717,22 @@ libxml_xmlXPathConcatFunction(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { } #endif /* LIBXML_XPATH_ENABLED */ +#ifdef LIBXML_SCHEMAS_ENABLED +PyObject * +libxml_xmlSchemaCollapseString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + xmlChar * c_retval; + xmlChar * value; + + if (!PyArg_ParseTuple(args, (char *)"z:xmlSchemaCollapseString", &value)) + return(NULL); + + c_retval = xmlSchemaCollapseString(value); + py_retval = libxml_xmlCharPtrWrap((xmlChar *) c_retval); + return(py_retval); +} + +#endif /* LIBXML_SCHEMAS_ENABLED */ PyObject * libxml_xmlTextReaderConstNamespaceUri(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; @@ -9838,6 +9808,25 @@ libxml_xmlStrdup(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { return(py_retval); } +#ifdef LIBXML_XINCLUDE_ENABLED +PyObject * +libxml_xmlXIncludeProcessTreeFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlNodePtr tree; + PyObject *pyobj_tree; + int flags; + + if (!PyArg_ParseTuple(args, (char *)"Oi:xmlXIncludeProcessTreeFlags", &pyobj_tree, &flags)) + return(NULL); + tree = (xmlNodePtr) PyxmlNode_Get(pyobj_tree); + + c_retval = xmlXIncludeProcessTreeFlags(tree, flags); + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +#endif /* LIBXML_XINCLUDE_ENABLED */ #ifdef LIBXML_XPATH_ENABLED PyObject * libxml_xmlXPathNamespaceURIFunction(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { @@ -10536,6 +10525,22 @@ libxml_xmlXPathMultValues(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* LIBXML_XPATH_ENABLED */ PyObject * +libxml_xmlURIGetPort(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlURIPtr URI; + PyObject *pyobj_URI; + + if (!PyArg_ParseTuple(args, (char *)"O:xmlURIGetPort", &pyobj_URI)) + return(NULL); + URI = (xmlURIPtr) PyURI_Get(pyobj_URI); + + c_retval = URI->port; + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +PyObject * libxml_xmlParseFile(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlDocPtr c_retval; @@ -11274,6 +11279,24 @@ libxml_xmlUCSIsBoxDrawing(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { return(py_retval); } +#ifdef LIBXML_XPATH_ENABLED +PyObject * +libxml_xmlXPathOrderDocElems(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + long c_retval; + xmlDocPtr doc; + PyObject *pyobj_doc; + + if (!PyArg_ParseTuple(args, (char *)"O:xmlXPathOrderDocElems", &pyobj_doc)) + return(NULL); + doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); + + c_retval = xmlXPathOrderDocElems(doc); + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +#endif /* LIBXML_XPATH_ENABLED */ #ifdef LIBXML_HTML_ENABLED PyObject * libxml_htmlNodeDumpFormatOutput(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml index d5a4cbe..b933290 100644 --- a/python/libxml2-python-api.xml +++ b/python/libxml2-python-api.xml @@ -306,5 +306,13 @@ <return type='int' info="The error line" field="line"/> <arg name='Error' type='xmlErrorPtr' info='the Error'/> </function> + <function name='xmlPythonCleanupParser' file='python'> + <info>Cleanup function for the XML library. It tries to reclaim all parsing related global memory allocated for the library processing. It doesn't deallocate any document related memory. Calling this function should not prevent reusing the library but one should call xmlCleanupParser() only when the process has finished using the library or XML document built with it.</info> + <return type='void'/> + </function> + <function name='xmlMemoryUsed' file='python'> + <info>Returns the total amount of memory allocated by libxml2</info> + <return type='int' info='number of bytes allocated'/> + </function> </symbols> </api> diff --git a/python/setup.py b/python/setup.py index 5bafd54..eb39621 100755 --- a/python/setup.py +++ b/python/setup.py @@ -226,7 +226,7 @@ else: setup (name = "libxml2-python", # On *nix, the version number is created from setup.py.in # On windows, it is set by configure.js - version = "2.6.10", + version = "2.6.11", description = descr, author = "Daniel Veillard", author_email = "veillard@redhat.com", diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am index bf04878..259a1bf 100644 --- a/python/tests/Makefile.am +++ b/python/tests/Makefile.am @@ -33,6 +33,7 @@ PYTESTS= \ readererr.py\ relaxng.py \ thread2.py \ + sync.py \ tstLastError.py \ indexes.py @@ -45,8 +46,13 @@ EXTRA_DIST = $(PYTESTS) $(XMLS) if WITH_PYTHON tests: $(PYTESTS) - -@(PYTHONPATH="..:../.libs:$(srcdir)/..:$$PYTHONPATH" ; export PYTHONPATH; \ - for test in $(PYTESTS) ; do echo "-- $$test" ; $(PYTHON) $(srcdir)/$$test ; done) + echo "## running Python regression tests" + -@(PYTHONPATH="..:../.libs:$(srcdir)/..:$$PYTHONPATH" ; \ + export PYTHONPATH; \ + for test in $(PYTESTS) ; \ + do log=`$(PYTHON) $(srcdir)/$$test` ; \ + if [ "`echo $$log | grep OK`" = "" ] ; then \ + echo "-- $$test" ; echo "$$log" ; fi ; done) else tests: endif diff --git a/python/tests/Makefile.in b/python/tests/Makefile.in index 893a517..f5e50ec 100644 --- a/python/tests/Makefile.in +++ b/python/tests/Makefile.in @@ -275,6 +275,7 @@ PYTESTS = \ readererr.py\ relaxng.py \ thread2.py \ + sync.py \ tstLastError.py \ indexes.py @@ -444,8 +445,13 @@ uninstall-am: uninstall-info-am @WITH_PYTHON_TRUE@tests: $(PYTESTS) -@WITH_PYTHON_TRUE@ -@(PYTHONPATH="..:../.libs:$(srcdir)/..:$$PYTHONPATH" ; export PYTHONPATH; \ -@WITH_PYTHON_TRUE@ for test in $(PYTESTS) ; do echo "-- $$test" ; $(PYTHON) $(srcdir)/$$test ; done) +@WITH_PYTHON_TRUE@ echo "## running Python regression tests" +@WITH_PYTHON_TRUE@ -@(PYTHONPATH="..:../.libs:$(srcdir)/..:$$PYTHONPATH" ; \ +@WITH_PYTHON_TRUE@ export PYTHONPATH; \ +@WITH_PYTHON_TRUE@ for test in $(PYTESTS) ; \ +@WITH_PYTHON_TRUE@ do log=`$(PYTHON) $(srcdir)/$$test` ; \ +@WITH_PYTHON_TRUE@ if [ "`echo $$log | grep OK`" = "" ] ; then \ +@WITH_PYTHON_TRUE@ echo "-- $$test" ; echo "$$log" ; fi ; done) @WITH_PYTHON_FALSE@tests: clean: diff --git a/python/tests/sync.py b/python/tests/sync.py new file mode 100755 index 0000000..2141875 --- /dev/null +++ b/python/tests/sync.py @@ -0,0 +1,135 @@ +#!/usr/bin/python -u +import sys +import libxml2 + +# Memory debug specific +libxml2.debugMemory(1) + +log = "" + +class callback: + def startDocument(self): + global log + log = log + "startDocument:" + + def endDocument(self): + global log + log = log + "endDocument:" + + def startElement(self, tag, attrs): + global log + log = log + "startElement %s %s:" % (tag, attrs) + + def endElement(self, tag): + global log + log = log + "endElement %s:" % (tag) + + def characters(self, data): + global log + log = log + "characters: %s:" % (data) + + def warning(self, msg): + global log + log = log + "warning: %s:" % (msg) + + def error(self, msg): + global log + log = log + "error: %s:" % (msg) + + def fatalError(self, msg): + global log + log = log + "fatalError: %s:" % (msg) + +handler = callback() + +log="" +chunk="""<foo><bar2/>""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2></bar2>""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2>""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 None:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2 a="1" b='2' />""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2 a="1" b='2' >""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2 a="1" b='2' ></bar2>""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +log="" +chunk="""<foo><bar2 a="b='1' />""" +ctxt = libxml2.createPushParser(handler, None, 0, "test.xml") +ctxt.parseChunk(chunk, len(chunk), 0) +ctxt=None + +reference = "startDocument:startElement foo None:" +if log != reference: + print "Error got: %s" % log + print "Exprected: %s" % reference + sys.exit(1) + +# Memory debug specific +libxml2.cleanupParser() +if libxml2.debugMemory(1) == 0: + print "OK" +else: + print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + libxml2.dumpMemory() |