1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

cleanup added class for parser context, added first cut for push mode

* python/Makefile.am python/types.c: cleanup
* python/libxml.c python/libxml.py python/libxml_wrap.h
  python/generator.py python/libxml2-python-api.xml
  python/libxml2class.txt: added class for parser context, added
  first cut for push mode support. Added a framework to generate
  accessors functions.
* python/tests/Makefile.am python/tests/push.py: added a push
  test
Daniel
This commit is contained in:
Daniel Veillard
2002-02-03 15:08:05 +00:00
parent cfb0546244
commit 3ce5257b29
11 changed files with 528 additions and 423 deletions

View File

@ -10,6 +10,7 @@ DOCS = TODO libxml2class.txt
EXTRA_DIST = \
libxml.c \
types.c \
generator.py \
libxml_wrap.h \
libxml.py \
@ -22,8 +23,8 @@ all: _libxml.so libxml2.py
libxml2.py: $(srcdir)/libxml.py libxml2class.py
cat $(srcdir)/libxml.py libxml2class.py > libxml2.py
_libxml.so: libxml.o libxml2-py.o
$(CC) $(LINK_FLAGS) libxml2-py.o libxml.o $(LIBS) -o _libxml.so
_libxml.so: libxml.o libxml2-py.o types.o
$(CC) $(LINK_FLAGS) libxml.o libxml2-py.o types.o $(LIBS) -o _libxml.so
else
all:
endif
@ -31,6 +32,9 @@ endif
libxml.o: libxml.c libxml2-export.c libxml_wrap.h
$(CC) $(SHCFLAGS) -c -o libxml.o $(srcdir)/libxml.c
types.o: types.c libxml_wrap.h
$(CC) $(SHCFLAGS) -c -o types.o $(srcdir)/types.c
libxml2-py.o: libxml2-py.c libxml2-py.h libxml_wrap.h
$(CC) $(SHCFLAGS) -c -o libxml2-py.o $(srcdir)/libxml2-py.c
@ -44,9 +48,7 @@ GENERATED= $(srcdir)/libxml2class.py \
$(GENERATED): $(srcdir)/$(GENERATE) $(API_DESC)
cd $(srcdir) && $(PYTHON) $(GENERATE)
dummy:
tests: dummy
tests: all
cd tests && $(MAKE) tests
clean:

View File

@ -129,10 +129,13 @@ class docParser:
if self.in_function == 1:
self.function_return_type = None
self.function_return_info = None
self.function_return_field = None
if attrs.has_key('type'):
self.function_return_type = attrs['type']
if attrs.has_key('info'):
self.function_return_info = attrs['info']
if attrs.has_key('field'):
self.function_return_field = attrs['field']
def end(self, tag):
@ -152,7 +155,8 @@ class docParser:
elif tag == 'return':
if self.in_function == 1:
self.function_return = [self.function_return_type,
self.function_return_info]
self.function_return_info,
self.function_return_field]
elif tag == 'info':
str = ''
for c in self._data:
@ -186,8 +190,6 @@ skipped_types = {
'int *': "usually a return type",
'xmlSAXHandlerPtr': "not the proper interface for SAX",
'htmlSAXHandlerPtr': "not the proper interface for SAX",
'xmlParserCtxtPtr': "not the proper interface for the parser",
'htmlParserCtxtPtr': "not the proper interface for the parser",
'xmlRMutexPtr': "thread specific, skipped",
'xmlMutexPtr': "thread specific, skipped",
'xmlGlobalStatePtr': "thread specific, skipped",
@ -257,6 +259,10 @@ py_types = {
'const htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
'xmlXPathContextPtr': ('O', "xmlXPathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
'xmlXPathContext *': ('O', "xpathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
'xmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
}
py_return_types = {
@ -340,7 +346,10 @@ def print_function_wrapper(name, output, export, include):
elif py_types.has_key(ret[0]):
(f, t, n, c) = py_types[ret[0]]
c_return = " %s c_retval;\n" % (ret[0])
c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
if file == "python_accessor":
c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
else:
c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
ret_convert = ret_convert + " return(py_retval);\n"
elif py_return_types.has_key(ret[0]):
@ -476,6 +485,8 @@ classes_type = {
"xmlAttributePtr": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
"xmlAttribute *": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
"xmlXPathContextPtr": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
"xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
"xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
}
converter_type = {
@ -496,6 +507,7 @@ classes_ancestor = {
}
classes_destructors = {
"xpathContext": "xmlXPathFreeContext",
"parserCtxt": "xmlFreeParserCtxt",
}
function_classes = {}
@ -530,13 +542,16 @@ for type in classes_type.keys():
ctypes.append(type)
ctypes_processed[type] = ()
def nameFixup(function, classe, type):
def nameFixup(function, classe, type, file):
listname = classe + "List"
ll = len(listname)
l = len(classe)
if name[0:l] == listname:
func = name[l:]
func = string.lower(func[0:1]) + func[1:]
elif name[0:12] == "xmlParserGet" and file == "python_accessor":
func = name[12:]
func = string.lower(func[0:1]) + func[1:]
elif name[0:l] == classe:
func = name[l:]
func = string.lower(func[0:1]) + func[1:]
@ -573,22 +588,22 @@ for name in functions.keys():
if name[0:3] == "xml" and len(args) >= 1 and args[0][1] == type:
found = 1
func = nameFixup(name, classe, type)
func = nameFixup(name, classe, type, file)
info = (0, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:3] == "xml" and len(args) >= 2 and args[1][1] == type:
found = 1
func = nameFixup(name, classe, type)
func = nameFixup(name, classe, type, file)
info = (1, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:4] == "html" and len(args) >= 1 and args[0][1] == type:
found = 1
func = nameFixup(name, classe, type)
func = nameFixup(name, classe, type, file)
info = (0, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:4] == "html" and len(args) >= 2 and args[1][1] == type:
found = 1
func = nameFixup(name, classe, type)
func = nameFixup(name, classe, type, file)
info = (1, func, name, ret, args, file)
function_classes[classe].append(info)
if found == 1:
@ -601,7 +616,7 @@ for name in functions.keys():
continue
if name[0:10] == "xmlCharStr":
continue
func = nameFixup(name, "None", file)
func = nameFixup(name, "None", file, file)
info = (0, func, name, ret, args, file)
function_classes['None'].append(info)
@ -612,6 +627,10 @@ txt.write(" Generated Classes for libxml2-python\n\n")
def functionCompare(info1, info2):
(index1, func1, name1, ret1, args1, file1) = info1
(index2, func2, name2, ret2, args2, file2) = info2
if file1 == "python_accessor":
return -1
if file2 == "python_accessor":
return 1
if file1 < file2:
return -1
if file1 > file2:
@ -701,6 +720,12 @@ for classname in classes_list:
classes.write(" self._o = None\n")
classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
classes_ancestor[classname]))
if classes_ancestor[classname] == "xmlCore" or \
classes_ancestor[classname] == "xmlNode":
classes.write(" def __repr__(self):\n")
format = "%s:%%s" % (classname)
classes.write(" return \"%s\" %% (self.name)\n\n" % (
format))
else:
txt.write("Class %s()\n" % (classname))
classes.write("class %s:\n" % (classname))
@ -713,21 +738,21 @@ for classname in classes_list:
classes.write(" _libxml.%s(self._o)\n" %
classes_destructors[classname]);
classes.write(" self._o = None\n\n");
classes.write(" def __repr__(self):\n")
format = "%s:%%s" % (classname)
classes.write(" return \"%s\" %% (self.name)\n\n" % (
format))
flist = function_classes[classname]
flist.sort(functionCompare)
oldfile = ""
for info in flist:
(index, func, name, ret, args, file) = info
if file != oldfile:
classes.write(" #\n")
classes.write(" # %s functions from module %s\n" % (
classname, file))
txt.write("\n # functions from module %s\n" % file)
classes.write(" #\n\n")
if file == "python_accessor":
classes.write(" # accessors for %s\n" % (classname))
txt.write(" # accessors\n")
else:
classes.write(" #\n")
classes.write(" # %s functions from module %s\n" % (
classname, file))
txt.write("\n # functions from module %s\n" % file)
classes.write(" #\n\n")
oldfile = file
classes.write(" def %s(self" % func)
txt.write(" %s()\n" % func);

View File

@ -1,5 +1,14 @@
/*
* libxml.c: this modules implements the main part of the glue of the
* libxml2 library and the Python interpreter. It provides the
* entry points where an automatically generated stub is either
* unpractical or would not match cleanly the Python model.
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#include <Python.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@ -15,277 +24,48 @@
/************************************************************************
* *
* Per type specific glue *
* Handling SAX/xmllib/sgmlop callback interfaces *
* *
************************************************************************/
PyObject *
libxml_intWrap(int val) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_intWrap: val = %d\n", val);
#endif
ret = PyInt_FromLong((long) val);
return(ret);
}
typedef struct pySAXhandler {
PyObject *startDocument;
/* TODO !!! */
} pySAXhandler, *pySAXhandlerPtr;
/************************************************************************
* *
* Handling of specific parser context *
* *
************************************************************************/
PyObject *
libxml_doubleWrap(double val) {
PyObject *ret;
libxml_xmlCreatePushParser(PyObject *self, PyObject *args) {
xmlChar *chunk;
int size;
xmlChar *URI;
PyObject *pyobj_SAX;
xmlSAXHandlerPtr SAX = NULL;
pySAXhandlerPtr SAXdata = NULL;
xmlParserCtxtPtr ret;
PyObject *pyret;
#ifdef DEBUG
printf("libxml_doubleWrap: val = %f\n", val);
if (!PyArg_ParseTuple(args, "Oziz:xmlCreatePushParser", &pyobj_SAX,
&chunk, &size, &URI))
return(NULL);
#ifdef DEBUG_ERROR
printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
pyobj_SAX, chunk, size, URI);
#endif
ret = PyFloat_FromDouble((double) val);
return(ret);
}
PyObject *
libxml_charPtrWrap(char *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
if (pyobj_SAX != Py_None) {
printf("xmlCreatePushParser: event interface not supported yet !\n");
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
xmlFree(str);
return(ret);
}
PyObject *
libxml_xmlCharPtrWrap(xmlChar *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
xmlFree(str);
return(ret);
}
PyObject *
libxml_constcharPtrWrap(const char *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
return(ret);
}
PyObject *
libxml_constxmlCharPtrWrap(const xmlChar *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
return(ret);
}
PyObject *
libxml_xmlDocPtrWrap(xmlDocPtr doc) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
#endif
if (doc == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyCObject_FromVoidPtrAndDesc((void *) doc, "xmlDocPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlNodePtrWrap(xmlNodePtr node) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlNodePtrWrap: node = %p\n", node);
#endif
if (node == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) node, "xmlNodePtr", NULL);
return(ret);
}
PyObject *
libxml_xmlNsPtrWrap(xmlNsPtr ns) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
#endif
if (ns == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) ns, "xmlNsPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlAttrPtrWrap(xmlAttrPtr attr) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
#endif
if (attr == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlAttributePtrWrap(xmlAttributePtr attr) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
#endif
if (attr == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttributePtr", NULL);
return(ret);
}
PyObject *
libxml_xmlElementPtrWrap(xmlElementPtr elem) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
#endif
if (elem == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) elem, "xmlElementPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
#endif
if (ctxt == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlXPathContextPtr",
NULL);
return(ret);
}
PyObject *
libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
#endif
if (obj == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
switch(obj->type) {
case XPATH_XSLT_TREE:
/* TODO !!!! Allocation problems */
case XPATH_NODESET:
if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
ret = PyList_New(0);
else {
int i;
xmlNodePtr node;
ret = PyList_New(obj->nodesetval->nodeNr);
for (i = 0;i < obj->nodesetval->nodeNr;i++) {
node = obj->nodesetval->nodeTab[i];
/* TODO: try to cast directly to the proper node type */
PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
}
}
break;
case XPATH_BOOLEAN:
ret = PyInt_FromLong((long) obj->boolval);
break;
case XPATH_NUMBER:
ret = PyFloat_FromDouble(obj->floatval);
break;
case XPATH_STRING:
ret = PyString_FromString(obj->stringval);
break;
case XPATH_POINT:
case XPATH_RANGE:
case XPATH_LOCATIONSET:
default:
printf("Unable to convert XPath object type %d\n", obj->type);
Py_INCREF(Py_None);
ret = Py_None;
}
xmlXPathFreeObject(obj);
return(ret);
}
xmlXPathObjectPtr
libxml_xmlXPathObjectPtrConvert(PyObject * obj) {
xmlXPathObjectPtr ret;
#ifdef DEBUG
printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
#endif
if (obj == NULL) {
return(NULL);
}
if PyFloat_Check(obj) {
ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
} else if PyString_Check(obj) {
xmlChar *str;
str = xmlStrndup((const xmlChar *)PyString_AS_STRING(obj),
PyString_GET_SIZE(obj));
ret = xmlXPathWrapString(str);
} else {
printf("Unable to convert Python Object to XPath");
}
Py_DECREF(obj);
return(ret);
ret = xmlCreatePushParserCtxt(SAX, SAXdata, chunk, size, URI);
pyret = libxml_xmlParserCtxtPtrWrap(ret);
return(pyret);
}
/************************************************************************
@ -532,131 +312,6 @@ done:
return(py_retval);
}
/************************************************************************
* *
* The PyxmlNode type *
* *
************************************************************************/
static void
PyxmlNode_dealloc(PyxmlNode_Object * self)
{
printf("TODO PyxmlNode_dealloc\n");
PyMem_DEL(self);
}
static int
PyxmlNode_compare(PyxmlNode_Object * self, PyxmlNode_Object * v)
{
if (self->obj == v->obj)
return 0;
if (self->obj > v->obj)
return -1;
return 1;
}
static long
PyxmlNode_hash(PyxmlNode_Object * self)
{
return (long) self->obj;
}
static PyObject *
PyxmlNode_repr(PyxmlNode_Object * self)
{
char buf[100];
sprintf(buf, "<xmlNode of type %d at %lx>",
PyxmlNode_Get(self)->type,
(long) PyxmlNode_Get(self));
return PyString_FromString(buf);
}
static char PyxmlNode_Type__doc__[] = "This is the type of libxml Nodes";
static PyTypeObject PyxmlNode_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size */
"xmlNode", /*tp_name */
sizeof(PyxmlNode_Object), /*tp_basicsize */
0, /*tp_itemsize */
(destructor) PyxmlNode_dealloc,/*tp_dealloc */
(printfunc) 0, /*tp_print */
(getattrfunc) 0, /*tp_getattr */
(setattrfunc) 0, /*tp_setattr */
(cmpfunc) PyxmlNode_compare,/*tp_compare */
(reprfunc) PyxmlNode_repr, /*tp_repr */
0, /*tp_as_number */
0, /*tp_as_sequence */
0, /*tp_as_mapping */
(hashfunc) PyxmlNode_hash, /*tp_hash */
(ternaryfunc) 0, /*tp_call */
(reprfunc) 0, /*tp_str */
0L, 0L, 0L, 0L,
PyxmlNode_Type__doc__
};
/************************************************************************
* *
* The PyxmlXPathContext type *
* *
************************************************************************/
static void
PyxmlXPathContext_dealloc(PyxmlXPathContext_Object * self)
{
printf("TODO PyxmlXPathContext_dealloc\n");
PyMem_DEL(self);
}
static int
PyxmlXPathContext_compare(PyxmlXPathContext_Object * self, PyxmlXPathContext_Object * v)
{
if (self->obj == v->obj)
return 0;
if (self->obj > v->obj)
return -1;
return 1;
}
static long
PyxmlXPathContext_hash(PyxmlXPathContext_Object * self)
{
return (long) self->obj;
}
static PyObject *
PyxmlXPathContext_repr(PyxmlXPathContext_Object * self)
{
char buf[100];
sprintf(buf, "<xmlXPathContext at %lx>",
(long) PyxmlXPathContext_Get(self));
return PyString_FromString(buf);
}
static char PyxmlXPathContext_Type__doc__[] = "This is the type of XPath evaluation contexts";
PyTypeObject PyxmlXPathContext_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size */
"xmlXPathContext", /*tp_name */
sizeof(PyxmlXPathContext_Object), /*tp_basicsize */
0, /*tp_itemsize */
(destructor) PyxmlXPathContext_dealloc,/*tp_dealloc */
(printfunc) 0, /*tp_print */
(getattrfunc) 0, /*tp_getattr */
(setattrfunc) 0, /*tp_setattr */
(cmpfunc) PyxmlXPathContext_compare,/*tp_compare */
(reprfunc) PyxmlXPathContext_repr, /*tp_repr */
0, /*tp_as_number */
0, /*tp_as_sequence */
0, /*tp_as_mapping */
(hashfunc) PyxmlXPathContext_hash, /*tp_hash */
(ternaryfunc) 0, /*tp_call */
(reprfunc) 0, /*tp_str */
0L, 0L, 0L, 0L,
PyxmlXPathContext_Type__doc__
};
/************************************************************************
* *
* Global properties access *
@ -1055,11 +710,8 @@ static PyMethodDef libxmlMethods[] = {
};
void init_libxml(void) {
PyObject *m, *d;
PyObject *m;
m = Py_InitModule("_libxml", libxmlMethods);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "xmlNodeType", (PyObject *)&PyxmlNode_Type);
PyDict_SetItemString(d, "xmlXPathContextType", (PyObject *)&PyxmlXPathContext_Type);
libxml_xmlErrorInitialize();
}

View File

@ -147,14 +147,6 @@ def xpathObjectRet(o):
def registerXPathFunction(ctxt, name, ns_uri, f):
ret = _libxml.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
#
# A parser context
#
class parserCtxt:
def __init__(self, _obj=None):
self._o = _obj
#
# Everything below this point is automatically generated
#

View File

@ -20,5 +20,18 @@
<arg name='f' type='pythonObject' info='the python function'/>
<arg name='ctx' type='pythonObject' info='a context for the callback'/>
</function>
<function name='xmlCreatePushParser' file='python'>
<info>Create a progressive parser context to build either an event flow if the SAX object is not None, or a DOM tree otherwise.</info>
<return type='xmlParserCtxtPtr' info="the parser context or None in case of error"/>
<arg name='SAX' type='pythonObject' info='the SAX callback object or None'/>
<arg name='chunk' type='xmlChar *' info='the initial data'/>
<arg name='size' type='int' info='the size of the initial data'/>
<arg name='URI' type='xmlChar *' info='The URI used for base computations'/>
</function>
<function name='xmlParserGetDoc' file='python_accessor'>
<info>Get the document tree from a parser context.</info>
<return type='xmlDocPtr' info="the document tree" field="myDoc"/>
<arg name='ctxt' type='xmlParserCtxtPtr' info='the SAX callback object or None'/>
</function>
</symbols>
</api>

View File

@ -6,9 +6,13 @@
# functions from module HTMLparser
htmlFreeParserCtxt()
htmlHandleOmittedElem()
htmlIsScriptAttribute()
htmlParseCharRef()
htmlParseChunk()
htmlParseDoc()
htmlParseElement()
htmlParseFile()
# functions from module HTMLtree
@ -68,6 +72,7 @@ nanoHTTPScanProxy()
# functions from module parser
cleanupParser()
createDocParserCtxt()
defaultSAXHandlerInit()
htmlDefaultSAXHandlerInit()
initParser()
@ -88,6 +93,10 @@ substituteEntitiesDefault()
checkLanguageID()
copyChar()
copyCharMultiByte()
createEntityParserCtxt()
createFileParserCtxt()
createMemoryParserCtxt()
htmlCreateFileParserCtxt()
htmlInitAutoClose()
isBaseChar()
isBlank()
@ -98,8 +107,14 @@ isExtender()
isIdeographic()
isLetter()
isPubidChar()
namePop()
namePush()
newParserCtxt()
nodePop()
nodePush()
# functions from module python
createPushParser()
registerErrorHandler()
# functions from module tree
@ -315,6 +330,66 @@ Class xmlDtd(xmlNode)
Class xmlElement(xmlNode)
Class parserCtxt()
# accessors
doc()
# functions from module parser
clearParserCtxt()
initParserCtxt()
parseChunk()
parseDocument()
parseExtParsedEnt()
stopParser()
# functions from module parserInternals
decodeEntities()
freeParserCtxt()
handleEntity()
namespaceParseNCName()
namespaceParseNSDef()
nextChar()
parseAttValue()
parseAttributeListDecl()
parseCDSect()
parseCharData()
parseCharRef()
parseComment()
parseContent()
parseDocTypeDecl()
parseElement()
parseElementDecl()
parseEncName()
parseEncodingDecl()
parseEndTag()
parseEntityDecl()
parseEntityRef()
parseExternalSubset()
parseMarkupDecl()
parseMisc()
parseName()
parseNamespace()
parseNmtoken()
parseNotationDecl()
parsePEReference()
parsePI()
parsePITarget()
parsePubidLiteral()
parseQuotedString()
parseReference()
parseSDDecl()
parseStartTag()
parseSystemLiteral()
parseTextDecl()
parseVersionInfo()
parseVersionNum()
parseXMLDecl()
parserHandlePEReference()
parserHandleReference()
popInput()
scanName()
skipBlankChars()
stringDecodeEntities()
Class xpathContext()
# functions from module python

View File

@ -1,3 +1,4 @@
#include <Python.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
@ -27,6 +28,12 @@ typedef struct {
xmlXPathContextPtr obj;
} PyxmlXPathContext_Object;
#define PyparserCtxt_Get(v) (((PyparserCtxt_Object *)(v))->obj)
typedef struct {
PyObject_HEAD
xmlParserCtxtPtr obj;
} PyparserCtxt_Object;
PyObject * libxml_intWrap(int val);
PyObject * libxml_xmlCharPtrWrap(xmlChar *str);
PyObject * libxml_constxmlCharPtrWrap(const xmlChar *str);
@ -40,5 +47,7 @@ PyObject * libxml_xmlAttributePtrWrap(xmlAttributePtr ns);
PyObject * libxml_xmlElementPtrWrap(xmlElementPtr ns);
PyObject * libxml_doubleWrap(double val);
PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);

View File

@ -4,6 +4,7 @@ TESTS= \
tst.py \
tstxpath.py \
xpathext.py \
push.py \
error.py \
xpath.py
@ -20,6 +21,9 @@ else
tests:
endif
clean:
rm -f *.pyc core
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(EXAMPLE_DIR)
-(for test in $(TESTS) $(XMLS); \

25
python/tests/push.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/python -u
import sys
import libxml2
ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
ctxt.parseChunk("/>", 2, 1)
doc = ctxt.doc()
ctxt=None
if doc.name != "test.xml":
print "document name error"
sys.exit(1)
root = doc.children
if root.name != "foo":
print "root element name error"
sys.exit(1)
doc.freeDoc()
i = 10000
while i > 0:
ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
ctxt.parseChunk("/>", 2, 1)
doc = ctxt.doc()
doc.freeDoc()
i = i -1
ctxt=None
print "OK"

297
python/types.c Normal file
View File

@ -0,0 +1,297 @@
/*
* types.c: converter functions between the internal representation
* and the Python objects
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#include "libxml_wrap.h"
PyObject *
libxml_intWrap(int val) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_intWrap: val = %d\n", val);
#endif
ret = PyInt_FromLong((long) val);
return(ret);
}
PyObject *
libxml_doubleWrap(double val) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_doubleWrap: val = %f\n", val);
#endif
ret = PyFloat_FromDouble((double) val);
return(ret);
}
PyObject *
libxml_charPtrWrap(char *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
xmlFree(str);
return(ret);
}
PyObject *
libxml_xmlCharPtrWrap(xmlChar *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
xmlFree(str);
return(ret);
}
PyObject *
libxml_constcharPtrWrap(const char *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlcharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
return(ret);
}
PyObject *
libxml_constxmlCharPtrWrap(const xmlChar *str) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlCharPtrWrap: str = %s\n", str);
#endif
if (str == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyString_FromString(str);
return(ret);
}
PyObject *
libxml_xmlDocPtrWrap(xmlDocPtr doc) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
#endif
if (doc == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
/* TODO: look at deallocation */
ret = PyCObject_FromVoidPtrAndDesc((void *) doc, "xmlDocPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlNodePtrWrap(xmlNodePtr node) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlNodePtrWrap: node = %p\n", node);
#endif
if (node == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) node, "xmlNodePtr", NULL);
return(ret);
}
PyObject *
libxml_xmlNsPtrWrap(xmlNsPtr ns) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
#endif
if (ns == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) ns, "xmlNsPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlAttrPtrWrap(xmlAttrPtr attr) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
#endif
if (attr == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlAttributePtrWrap(xmlAttributePtr attr) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
#endif
if (attr == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttributePtr", NULL);
return(ret);
}
PyObject *
libxml_xmlElementPtrWrap(xmlElementPtr elem) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
#endif
if (elem == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) elem, "xmlElementPtr", NULL);
return(ret);
}
PyObject *
libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
#endif
if (ctxt == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlXPathContextPtr",
NULL);
return(ret);
}
PyObject *
libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
#endif
if (ctxt == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlParserCtxtPtr",
NULL);
return(ret);
}
PyObject *
libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) {
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
#endif
if (obj == NULL) {
Py_INCREF(Py_None);
return(Py_None);
}
switch(obj->type) {
case XPATH_XSLT_TREE:
/* TODO !!!! Allocation problems */
case XPATH_NODESET:
if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
ret = PyList_New(0);
else {
int i;
xmlNodePtr node;
ret = PyList_New(obj->nodesetval->nodeNr);
for (i = 0;i < obj->nodesetval->nodeNr;i++) {
node = obj->nodesetval->nodeTab[i];
/* TODO: try to cast directly to the proper node type */
PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
}
}
break;
case XPATH_BOOLEAN:
ret = PyInt_FromLong((long) obj->boolval);
break;
case XPATH_NUMBER:
ret = PyFloat_FromDouble(obj->floatval);
break;
case XPATH_STRING:
ret = PyString_FromString(obj->stringval);
break;
case XPATH_POINT:
case XPATH_RANGE:
case XPATH_LOCATIONSET:
default:
printf("Unable to convert XPath object type %d\n", obj->type);
Py_INCREF(Py_None);
ret = Py_None;
}
xmlXPathFreeObject(obj);
return(ret);
}
xmlXPathObjectPtr
libxml_xmlXPathObjectPtrConvert(PyObject * obj) {
xmlXPathObjectPtr ret;
#ifdef DEBUG
printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
#endif
if (obj == NULL) {
return(NULL);
}
if PyFloat_Check(obj) {
ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
} else if PyString_Check(obj) {
xmlChar *str;
str = xmlStrndup((const xmlChar *)PyString_AS_STRING(obj),
PyString_GET_SIZE(obj));
ret = xmlXPathWrapString(str);
} else {
printf("Unable to convert Python Object to XPath");
}
Py_DECREF(obj);
return(ret);
}