improving some documentation comments found and fixed a mem leak with
* tree.c: improving some documentation comments
* xmlregexp.c: found and fixed a mem leak with python regression tests
* doc/*: rebuilt the doc and the API XML file including the
xmlregexp.h xmlautomata.h and xmlunicode.h headers
* python/generator.py python/libxml2class.txt python/libxml_wrap.h
python/types.c: added access to the XML Schemas regexps from
python
* python/tests/Makefile.am python/tests/regexp.py: added a
simple regexp bindings test
Daniel
diff --git a/python/generator.py b/python/generator.py
index e2a4204..ed3196d 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -270,6 +270,7 @@
'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
+ 'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
}
py_return_types = {
@@ -409,6 +410,10 @@
include.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
export.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
output.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
+ elif file == "xmlregexp":
+ include.write("#ifdef LIBXML_REGEXP_ENABLED\n");
+ export.write("#ifdef LIBXML_REGEXP_ENABLED\n");
+ output.write("#ifdef LIBXML_REGEXP_ENABLED\n");
include.write("PyObject * ")
include.write("libxml_%s(PyObject *self, PyObject *args);\n" % (name));
@@ -468,6 +473,10 @@
include.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
export.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
output.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
+ elif file == "xmlregexp":
+ include.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
+ export.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
+ output.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
return 1
def buildStubs():
@@ -587,6 +596,7 @@
"xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
+ "xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
}
converter_type = {
@@ -613,6 +623,7 @@
"URI": "xmlFreeURI",
# "outputBuffer": "xmlOutputBufferClose",
"inputBuffer": "xmlFreeParserInputBuffer",
+ "xmlReg": "xmlRegFreeRegexp",
}
functions_noexcept = {
@@ -661,6 +672,10 @@
elif name[0:20] == "xmlParserInputBuffer" and file != "python":
func = name[20:]
func = string.lower(func[0:1]) + func[1:]
+ elif name[0:9] == "xmlRegexp":
+ func = "regexp" + name[9:]
+ elif name[0:6] == "xmlReg":
+ func = "regexp" + name[6:]
elif name[0:11] == "xmlACatalog":
func = name[11:]
func = string.lower(func[0:1]) + func[1:]
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index f528fa3..0340fb6 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -12,6 +12,7 @@
htmlParseFile()
# functions from module HTMLtree
+htmlIsBooleanAttr()
htmlNewDoc()
htmlNewDocNoDtD()
@@ -122,7 +123,7 @@
htmlCreatePushParser()
htmlSAXParseFile()
newNode()
-registerErrorHandler()
+regexpisterErrorHandler()
setEntityLoader()
# functions from module tree
@@ -155,10 +156,150 @@
fileMatch()
iOFTPMatch()
iOHTTPMatch()
+normalizeWindowsPath()
parserGetDirectory()
-registerDefaultInputCallbacks()
-registerDefaultOutputCallbacks()
-registerHTTPPostCallbacks()
+regexpisterDefaultInputCallbacks()
+regexpisterDefaultOutputCallbacks()
+regexpisterHTTPPostCallbacks()
+
+# functions from module xmlregexp
+regexpCompile()
+
+# functions from module xmlunicode
+uCSIsAlphabeticPresentationForms()
+uCSIsArabic()
+uCSIsArabicPresentationFormsA()
+uCSIsArabicPresentationFormsB()
+uCSIsArmenian()
+uCSIsArrows()
+uCSIsBasicLatin()
+uCSIsBengali()
+uCSIsBlock()
+uCSIsBlockElements()
+uCSIsBopomofo()
+uCSIsBopomofoExtended()
+uCSIsBoxDrawing()
+uCSIsBraillePatterns()
+uCSIsByzantineMusicalSymbols()
+uCSIsCJKCompatibility()
+uCSIsCJKCompatibilityForms()
+uCSIsCJKCompatibilityIdeographs()
+uCSIsCJKCompatibilityIdeographsSupplement()
+uCSIsCJKRadicalsSupplement()
+uCSIsCJKSymbolsandPunctuation()
+uCSIsCJKUnifiedIdeographs()
+uCSIsCJKUnifiedIdeographsExtensionA()
+uCSIsCJKUnifiedIdeographsExtensionB()
+uCSIsCat()
+uCSIsCatC()
+uCSIsCatCc()
+uCSIsCatCf()
+uCSIsCatCo()
+uCSIsCatCs()
+uCSIsCatL()
+uCSIsCatLl()
+uCSIsCatLm()
+uCSIsCatLo()
+uCSIsCatLt()
+uCSIsCatLu()
+uCSIsCatM()
+uCSIsCatMc()
+uCSIsCatMe()
+uCSIsCatMn()
+uCSIsCatN()
+uCSIsCatNd()
+uCSIsCatNl()
+uCSIsCatNo()
+uCSIsCatP()
+uCSIsCatPc()
+uCSIsCatPd()
+uCSIsCatPe()
+uCSIsCatPf()
+uCSIsCatPi()
+uCSIsCatPo()
+uCSIsCatPs()
+uCSIsCatS()
+uCSIsCatSc()
+uCSIsCatSk()
+uCSIsCatSm()
+uCSIsCatSo()
+uCSIsCatZ()
+uCSIsCatZl()
+uCSIsCatZp()
+uCSIsCatZs()
+uCSIsCherokee()
+uCSIsCombiningDiacriticalMarks()
+uCSIsCombiningHalfMarks()
+uCSIsCombiningMarksforSymbols()
+uCSIsControlPictures()
+uCSIsCurrencySymbols()
+uCSIsCyrillic()
+uCSIsDeseret()
+uCSIsDevanagari()
+uCSIsDingbats()
+uCSIsEnclosedAlphanumerics()
+uCSIsEnclosedCJKLettersandMonths()
+uCSIsEthiopic()
+uCSIsGeneralPunctuation()
+uCSIsGeometricShapes()
+uCSIsGeorgian()
+uCSIsGothic()
+uCSIsGreek()
+uCSIsGreekExtended()
+uCSIsGujarati()
+uCSIsGurmukhi()
+uCSIsHalfwidthandFullwidthForms()
+uCSIsHangulCompatibilityJamo()
+uCSIsHangulJamo()
+uCSIsHangulSyllables()
+uCSIsHebrew()
+uCSIsHighPrivateUseSurrogates()
+uCSIsHighSurrogates()
+uCSIsHiragana()
+uCSIsIPAExtensions()
+uCSIsIdeographicDescriptionCharacters()
+uCSIsKanbun()
+uCSIsKangxiRadicals()
+uCSIsKannada()
+uCSIsKatakana()
+uCSIsKhmer()
+uCSIsLao()
+uCSIsLatin1Supplement()
+uCSIsLatinExtendedA()
+uCSIsLatinExtendedAdditional()
+uCSIsLatinExtendedB()
+uCSIsLetterlikeSymbols()
+uCSIsLowSurrogates()
+uCSIsMalayalam()
+uCSIsMathematicalAlphanumericSymbols()
+uCSIsMathematicalOperators()
+uCSIsMiscellaneousSymbols()
+uCSIsMiscellaneousTechnical()
+uCSIsMongolian()
+uCSIsMusicalSymbols()
+uCSIsMyanmar()
+uCSIsNumberForms()
+uCSIsOgham()
+uCSIsOldItalic()
+uCSIsOpticalCharacterRecognition()
+uCSIsOriya()
+uCSIsPrivateUse()
+uCSIsRunic()
+uCSIsSinhala()
+uCSIsSmallFormVariants()
+uCSIsSpacingModifierLetters()
+uCSIsSpecials()
+uCSIsSuperscriptsandSubscripts()
+uCSIsSyriac()
+uCSIsTags()
+uCSIsTamil()
+uCSIsTelugu()
+uCSIsThaana()
+uCSIsThai()
+uCSIsTibetan()
+uCSIsUnifiedCanadianAboriginalSyllabics()
+uCSIsYiRadicals()
+uCSIsYiSyllables()
# functions from module xmlversion
checkVersion()
@@ -351,38 +492,38 @@
# functions from module xpath
xpathNewContext()
-Class xpathContext()
- # accessors
- contextDoc()
- contextNode()
- contextPosition()
- contextSize()
- function()
- functionURI()
- setContextDoc()
- setContextNode()
-
- # functions from module python
- registerXPathFunction()
-
- # functions from module xpath
- xpathEval()
- xpathEvalExpression()
- xpathFreeContext()
-
- # functions from module xpathInternals
- xpathNewParserContext()
- xpathNsLookup()
- xpathRegisterAllFunctions()
- xpathRegisterNs()
- xpathRegisteredFuncsCleanup()
- xpathRegisteredNsCleanup()
- xpathRegisteredVariablesCleanup()
- xpathVariableLookup()
- xpathVariableLookupNS()
Class xmlAttribute(xmlNode)
+
+
+Class xmlNs(xmlNode)
+
+ # functions from module tree
+ copyNamespace()
+ copyNamespaceList()
+ freeNs()
+ freeNsList()
+ newNodeEatName()
+
+ # functions from module xpathInternals
+ xpathNodeSetFreeNs()
+
+
+Class xmlDtd(xmlNode)
+
+ # functions from module debugXML
+ debugDumpDTD()
+
+ # functions from module tree
+ copyDtd()
+ freeDtd()
+
+ # functions from module valid
+ dtdAttrDesc()
+ dtdElementDesc()
+ dtdQAttrDesc()
+ dtdQElementDesc()
Class catalog()
# functions from module catalog
@@ -396,27 +537,6 @@
resolvePublic()
resolveSystem()
resolveURI()
-
-
-Class xmlElement(xmlNode)
-
-
-Class xmlAttr(xmlNode)
-
- # functions from module debugXML
- debugDumpAttr()
- debugDumpAttrList()
-
- # functions from module tree
- freeProp()
- freePropList()
- removeProp()
-
-
-Class xmlEntity(xmlNode)
-
- # functions from module parserInternals
- handleEntity()
Class xpathParserContext()
# accessors
context()
@@ -443,6 +563,7 @@
xpathMultValues()
xpathNamespaceURIFunction()
xpathNormalizeFunction()
+ xpathNotEqualValues()
xpathNotFunction()
xpathNumberFunction()
xpathParseNCName()
@@ -540,44 +661,6 @@
stringDecodeEntities()
-Class xmlDtd(xmlNode)
-
- # functions from module debugXML
- debugDumpDTD()
-
- # functions from module tree
- copyDtd()
- freeDtd()
-
- # functions from module valid
- dtdAttrDesc()
- dtdElementDesc()
- dtdQAttrDesc()
- dtdQElementDesc()
-
-
-Class xmlNs(xmlNode)
-
- # functions from module tree
- copyNamespace()
- copyNamespaceList()
- freeNs()
- freeNsList()
- newNodeEatName()
-
- # functions from module xpathInternals
- xpathNodeSetFreeNs()
-
-
-Class inputBuffer(ioReadWrapper)
-
- # functions from module xmlIO
- freeParserInputBuffer()
- grow()
- push()
- read()
-
-
Class outputBuffer(ioWriteWrapper)
# functions from module xmlIO
@@ -585,6 +668,34 @@
flush()
write()
writeString()
+
+
+Class xmlElement(xmlNode)
+
+
+Class xmlEntity(xmlNode)
+
+ # functions from module parserInternals
+ handleEntity()
+
+
+Class xmlAttr(xmlNode)
+
+ # functions from module debugXML
+ debugDumpAttr()
+ debugDumpAttrList()
+
+ # functions from module tree
+ freeProp()
+ freePropList()
+ removeProp()
+Class xmlReg()
+
+ # functions from module xmlregexp
+ regexpExec()
+ regexpFreeRegexp()
+ regexpIsDeterminist()
+ regexpPrint()
Class URI()
# accessors
authority()
@@ -611,3 +722,41 @@
parseURIReference()
printURI()
saveUri()
+Class xpathContext()
+ # accessors
+ contextDoc()
+ contextNode()
+ contextPosition()
+ contextSize()
+ function()
+ functionURI()
+ setContextDoc()
+ setContextNode()
+
+ # functions from module python
+ regexpisterXPathFunction()
+
+ # functions from module xpath
+ xpathEval()
+ xpathEvalExpression()
+ xpathFreeContext()
+
+ # functions from module xpathInternals
+ xpathNewParserContext()
+ xpathNsLookup()
+ xpathRegisterAllFunctions()
+ xpathRegisterNs()
+ xpathRegisteredFuncsCleanup()
+ xpathRegisteredNsCleanup()
+ xpathRegisteredVariablesCleanup()
+ xpathVariableLookup()
+ xpathVariableLookupNS()
+
+
+Class inputBuffer(ioReadWrapper)
+
+ # functions from module xmlIO
+ freeParserInputBuffer()
+ grow()
+ push()
+ read()
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
index 752c7f7..efa79d0 100644
--- a/python/libxml_wrap.h
+++ b/python/libxml_wrap.h
@@ -14,6 +14,9 @@
#include <libxml/HTMLtree.h>
#include <libxml/xinclude.h>
#include <libxml/xpointer.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlautomata.h>
#define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \
(((PyxmlNode_Object *)(v))->obj))
@@ -55,6 +58,14 @@
xmlCatalogPtr obj;
} Pycatalog_Object;
+#define PyxmlReg_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlReg_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRegexpPtr obj;
+} PyxmlReg_Object;
+
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
(((PyURI_Object *)(v))->obj))
@@ -81,7 +92,7 @@
/* FILE * have their own internal representation */
#define PyFile_Get(v) (((v) == Py_None) ? NULL : \
- (PyFile_Check(v) ? (PyFile_AsFile(v)) : NULL))
+ (PyFile_Check(v) ? (PyFile_AsFile(v)) : stdout))
PyObject * libxml_intWrap(int val);
@@ -107,5 +118,6 @@
PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
+PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 435b5ac..adb4be3 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -18,7 +18,8 @@
xpath.py \
outbuf.py \
inbuf.py \
- resolver.py
+ resolver.py \
+ regexp.py
XMLS= \
tst.xml \
diff --git a/python/tests/regexp.py b/python/tests/regexp.py
new file mode 100644
index 0000000..4c05502
--- /dev/null
+++ b/python/tests/regexp.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python -u
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+re = libxml2.regexpCompile("a|b")
+if re.regexpExec("a") != 1:
+ print "error checking 'a'"
+ sys.exit(1)
+if re.regexpExec("b") != 1:
+ print "error checking 'b'"
+ sys.exit(1)
+if re.regexpExec("ab") != 0:
+ print "error checking 'ab'"
+ sys.exit(1)
+if re.regexpExec("") != 0:
+ print "error checking 'ab'"
+ sys.exit(1)
+if re.regexpIsDeterminist() != 1:
+ print "error checking determinism"
+ sys.exit(1)
+del re
+
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+ print "OK"
+else:
+ print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+ libxml2.dumpMemory()
diff --git a/python/types.c b/python/types.c
index 6b13092..c9adc42 100644
--- a/python/types.c
+++ b/python/types.c
@@ -505,3 +505,21 @@
(char *) "xmlParserInputBufferPtr", NULL);
return (ret);
}
+
+PyObject *
+libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
+{
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
+#endif
+ if (regexp == NULL) {
+ Py_INCREF(Py_None);
+ return (Py_None);
+ }
+ ret =
+ PyCObject_FromVoidPtrAndDesc((void *) regexp,
+ (char *) "xmlRegexpPtr", NULL);
+ return (ret);
+}