blob: cdbbfe987457e5dd41239fa50b9eabc16f3ea074 [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001/***********************************************************
2Copyright 2000 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32#include "Python.h"
33#include "xmlparse.h"
34
35/*
36** The version number should match the one in _checkversion
37*/
38#define VERSION "1.9"
39
40enum HandlerTypes{
41 StartElement,
42 EndElement,
43 ProcessingInstruction,
44 CharacterData,
45 UnparsedEntityDecl,
46 NotationDecl,
47 StartNamespaceDecl,
48 EndNamespaceDecl,
49 Comment,
50 StartCdataSection,
51 EndCdataSection,
52 Default,
53 DefaultHandlerExpand,
54 NotStandalone,
55 ExternalEntityRef
56};
57
58static PyObject *ErrorObject;
59
60/* ----------------------------------------------------- */
61
62/* Declarations for objects of type xmlparser */
63
64typedef struct {
65 PyObject_HEAD
66
67 XML_Parser itself;
68 PyObject **handlers;
69} xmlparseobject;
70
71staticforward PyTypeObject Xmlparsetype;
72
73typedef void (*xmlhandlersetter)( XML_Parser *self, void *meth );
74typedef void* xmlhandler;
75
76struct HandlerInfo{
77 const char *name;
78 xmlhandlersetter setter;
79 xmlhandler handler;
80};
81
82static struct HandlerInfo handler_info[];
83
84static PyObject *conv_atts( XML_Char **atts){
85 PyObject *attrs_obj=NULL;
86 XML_Char **attrs_p, **attrs_k;
87 int attrs_len;
88 PyObject *rv;
89
90 if( (attrs_obj = PyDict_New()) == NULL )
91 goto finally;
92 for(attrs_len=0, attrs_p = atts;
93 *attrs_p;
94 attrs_p++, attrs_len++) {
95 if (attrs_len%2) {
96 rv=PyString_FromString(*attrs_p);
97 if (! rv) {
98 Py_DECREF(attrs_obj);
99 attrs_obj=NULL;
100 goto finally;
101 }
102 if (PyDict_SetItemString(
103 attrs_obj,
104 (char*)*attrs_k, rv) < 0){
105 Py_DECREF(attrs_obj);
106 attrs_obj=NULL;
107 goto finally;
108 }
109 Py_DECREF(rv);
110 }
111 else attrs_k=attrs_p;
112 }
113 finally:
114 return attrs_obj;
115}
116
117/* Callback routines */
118
119void clear_handlers( xmlparseobject *self );
120
121void flag_error( xmlparseobject *self ){
122 clear_handlers(self);
123}
124
125#define RC_HANDLER( RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
126 RETURN, GETUSERDATA) \
127\
128static RC my_##NAME##Handler PARAMS {\
129 xmlparseobject *self = GETUSERDATA ; \
130 PyObject *args=NULL; \
131 PyObject *rv=NULL; \
132 INIT \
133\
134 if (self->handlers[NAME] \
135 && self->handlers[NAME] != Py_None) { \
136 args = Py_BuildValue PARAM_FORMAT ;\
137 if (!args) return RETURN; \
138 rv = PyEval_CallObject(self->handlers[NAME], args); \
139 Py_DECREF(args); \
140 if (rv == NULL) { \
141 flag_error( self ); \
142 return RETURN; \
143 } \
144 CONVERSION \
145 Py_DECREF(rv); \
146 } \
147 return RETURN; \
148}
149
150#define VOID_HANDLER( NAME, PARAMS, PARAM_FORMAT ) \
151 RC_HANDLER( void, NAME, PARAMS, , PARAM_FORMAT, , ,\
152 (xmlparseobject *)userData )
153
154#define INT_HANDLER( NAME, PARAMS, PARAM_FORMAT )\
155 RC_HANDLER( int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
156 rc = PyInt_AsLong( rv );, rc, \
157 (xmlparseobject *)userData )
158
159VOID_HANDLER( StartElement,
160 (void *userData, const XML_Char *name, const XML_Char **atts ),
161 ("(sO&)", name, conv_atts, atts ) )
162
163VOID_HANDLER( EndElement,
164 (void *userData, const XML_Char *name ),
165 ("(s)", name) )
166
167VOID_HANDLER( ProcessingInstruction,
168 (void *userData,
169 const XML_Char *target,
170 const XML_Char *data),
171 ("(ss)",target, data ))
172
173VOID_HANDLER( CharacterData,
174 (void *userData, const XML_Char *data, int len),
175 ("(s#)", data, len ) )
176
177VOID_HANDLER( UnparsedEntityDecl,
178 (void *userData,
179 const XML_Char *entityName,
180 const XML_Char *base,
181 const XML_Char *systemId,
182 const XML_Char *publicId,
183 const XML_Char *notationName),
184 ("(sssss)", entityName, base, systemId, publicId, notationName))
185
186VOID_HANDLER( NotationDecl,
187 (void *userData,
188 const XML_Char *notationName,
189 const XML_Char *base,
190 const XML_Char *systemId,
191 const XML_Char *publicId),
192 ("(ssss)", notationName, base, systemId, publicId))
193
194VOID_HANDLER( StartNamespaceDecl,
195 (void *userData,
196 const XML_Char *prefix,
197 const XML_Char *uri),
198 ("(ss)", prefix, uri ))
199
200VOID_HANDLER( EndNamespaceDecl,
201 (void *userData,
202 const XML_Char *prefix),
203 ("(s)", prefix ))
204
205VOID_HANDLER( Comment,
206 (void *userData, const XML_Char *prefix),
207 ("(s)", prefix))
208
209VOID_HANDLER( StartCdataSection,
210 (void *userData),
211 ("()" ))
212
213VOID_HANDLER( EndCdataSection,
214 (void *userData),
215 ("()" ))
216
217VOID_HANDLER( Default,
218 (void *userData, const XML_Char *s, int len),
219 ("(s#)",s,len))
220
221VOID_HANDLER( DefaultHandlerExpand,
222 (void *userData, const XML_Char *s, int len),
223 ("(s#)",s,len))
224
225INT_HANDLER( NotStandalone,
226 (void *userData),
227 ("()"))
228
229RC_HANDLER( int, ExternalEntityRef,
230 (XML_Parser parser,
231 const XML_Char *context,
232 const XML_Char *base,
233 const XML_Char *systemId,
234 const XML_Char *publicId),
235 int rc=0;,
236 ("(ssss)", context, base, systemId, publicId ),
237 rc = PyInt_AsLong( rv );, rc,
238 XML_GetUserData( parser ) )
239
240
241
242/* File reading copied from cPickle */
243
244#define UNLESS(E) if (!(E))
245
246/*
247static int
248read_other(xmlparseobject *self, char **s, int n) {
249 PyObject *bytes=NULL, *str=NULL, *arg=NULL;
250 int res = -1;
251
252 UNLESS(bytes = PyInt_FromLong(n)) {
253 if (!PyErr_Occurred())
254 PyErr_SetNone(PyExc_EOFError);
255
256 goto finally;
257 }
258
259 UNLESS(arg)
260 UNLESS(arg = PyTuple_New(1))
261 goto finally;
262
263 Py_INCREF(bytes);
264 if (PyTuple_SetItem(arg, 0, bytes) < 0)
265 goto finally;
266
267 UNLESS(str = PyObject_CallObject(self->read, arg))
268 goto finally;
269
270 *s = PyString_AsString(str);
271
272 res = n;
273
274finally:
275 Py_XDECREF(arg);
276 Py_XDECREF(bytes);
277
278 return res;
279}
280
281*/
282
283
284
285
286
287/* ---------------------------------------------------------------- */
288
289static char xmlparse_Parse__doc__[] =
290"(data [,isfinal]) - Parse XML data"
291;
292
293static PyObject *
294xmlparse_Parse( xmlparseobject *self, PyObject *args )
295{
296 char *s;
297 int slen;
298 int isFinal = 0;
299 int rv;
300
301 if (!PyArg_ParseTuple(args, "s#|i", &s, &slen, &isFinal))
302 return NULL;
303 rv = XML_Parse(self->itself, s, slen, isFinal);
304 if( PyErr_Occurred() ){
305 return NULL;
306 }
307 else if (rv == 0) {
308 PyErr_Format(ErrorObject, "%s: line %i, column %i",
309 XML_ErrorString( XML_GetErrorCode(self->itself) ),
310 XML_GetErrorLineNumber(self->itself),
311 XML_GetErrorColumnNumber(self->itself) );
312 return NULL;
313 }
314
315 return Py_BuildValue("i", rv);
316}
317
318#define BUF_SIZE 2048
319
320int readinst(char *buf, int buf_size, PyObject *meth){
321 PyObject *arg=NULL;
322 PyObject *bytes=NULL;
323 PyObject *str=NULL;
324 int len;
325
326 UNLESS(bytes = PyInt_FromLong(buf_size)) {
327 if (!PyErr_Occurred())
328 PyErr_SetNone(PyExc_EOFError);
329 goto finally;
330 }
331
332 UNLESS(arg)
333 UNLESS(arg = PyTuple_New(1))
334 goto finally;
335
336 Py_INCREF(bytes);
337 if (PyTuple_SetItem(arg, 0, bytes) < 0)
338 goto finally;
339
340 UNLESS(str = PyObject_CallObject(meth, arg))
341 goto finally;
342
343 UNLESS(PyString_Check( str ))
344 goto finally;
345
346 len=PyString_GET_SIZE( str );
347 strncpy( buf, PyString_AsString(str), len );
348 Py_XDECREF( str );
349finally:
350 return len;
351}
352
353static char xmlparse_ParseFile__doc__[] =
354"(file) - Parse XML data"
355;
356
357static PyObject *
358xmlparse_ParseFile( xmlparseobject *self, PyObject *args )
359{
360 int rv=1;
361 PyObject *f;
362 FILE *fp;
363 PyObject *readmethod=NULL;
364
365 if (!PyArg_ParseTuple(args, "O", &f))
366 return NULL;
367
368 if (PyFile_Check(f)) {
369 fp = PyFile_AsFile(f);
370 }else{
371 fp = NULL;
372 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
373 PyErr_Clear();
374 PyErr_SetString( PyExc_TypeError,
375 "argument must have 'read' attribute" );
376 return 0;
377 }
378 }
379
380 for (;;) {
381 int bytes_read;
382 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
383 if (buf == NULL) {
384 /* FIXME: throw exception for no memory */
385 return NULL;
386 }
387
388 if( fp ){
389 bytes_read=fread( buf, sizeof( char ), BUF_SIZE, fp);
390 }else{
391 bytes_read=readinst( buf, BUF_SIZE, readmethod );
392 }
393
394 if (bytes_read < 0) {
395 PyErr_SetFromErrno(PyExc_IOError);
396 return NULL;
397 }
398 rv=XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
399 if( PyErr_Occurred() ){
400 return NULL;
401 }
402 if (!rv || bytes_read == 0)
403 break;
404 }
405
406 return Py_BuildValue("i", rv);
407}
408
409static char xmlparse_SetBase__doc__[] =
410"(base_url) - Base URL string"
411;
412
413static PyObject *
414xmlparse_SetBase( xmlparseobject *self, PyObject *args ){
415 char *base;
416
417 if (!PyArg_ParseTuple(args, "s", &base))
418 return NULL;
419 if( !XML_SetBase( self->itself, base ) ){
420 PyErr_SetNone(PyExc_MemoryError);
421 return NULL;
422 }
423
424 Py_INCREF(Py_None);
425 return Py_None;
426}
427
428static char xmlparse_GetBase__doc__[] =
429"() - returns base URL string "
430;
431
432static PyObject *
433xmlparse_GetBase( xmlparseobject *self, PyObject *args ){
434 const XML_Char *base;
435 PyObject *rc;
436
437 if( PyTuple_Size( args )!=0 ){
438 PyArg_ParseTuple(args, "()" ); /* get good error reporting */
439 return NULL;
440 }
441 base=XML_GetBase( self->itself );
442 if( base ){
443 rc=Py_BuildValue("s", base);
444 }else{
445 Py_INCREF(Py_None);
446 rc=Py_None;
447 }
448 return rc;
449
450}
451
452static struct PyMethodDef xmlparse_methods[] = {
453 {"Parse", (PyCFunction)xmlparse_Parse,
454 METH_VARARGS, xmlparse_Parse__doc__},
455 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
456 METH_VARARGS, xmlparse_ParseFile__doc__},
457 {"SetBase", (PyCFunction)xmlparse_SetBase,
458 METH_VARARGS, xmlparse_SetBase__doc__},
459 {"GetBase", (PyCFunction)xmlparse_GetBase,
460 METH_VARARGS, xmlparse_GetBase__doc__},
461 {NULL, NULL} /* sentinel */
462};
463
464/* ---------- */
465
466
467static xmlparseobject *
468newxmlparseobject( char *encoding, char *namespace_separator){
469 int i;
470 xmlparseobject *self;
471
472 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
473 if (self == NULL)
474 return NULL;
475
476 if (namespace_separator) {
477 self->itself = XML_ParserCreateNS(encoding,
478 *namespace_separator);
479 }else{
480 self->itself = XML_ParserCreate(encoding);
481 }
482
483 if( self->itself==NULL ){
484 PyErr_SetString(PyExc_RuntimeError,
485 "XML_ParserCreate failed");
486 Py_DECREF(self);
487 return NULL;
488 }
489
490 XML_SetUserData(self->itself, (void *)self);
491
492 for( i=0; handler_info[i].name!=NULL;i++);
493
494 self->handlers=malloc( sizeof( PyObject *)*i );
495
496 clear_handlers( self );
497
498 return self;
499}
500
501
502static void
503xmlparse_dealloc( xmlparseobject *self )
504{
505 int i;
506 if (self->itself)
507 XML_ParserFree(self->itself);
508 self->itself = NULL;
509
510 for( i=0; handler_info[i].name!=NULL; i++ ){
511 Py_XDECREF( self->handlers[i] );
512 }
513 PyMem_DEL(self);
514}
515
516static int handlername2int( const char *name ){
517 int i;
518 for( i=0;handler_info[i].name!=NULL;i++){
519 if( strcmp( name, handler_info[i].name )==0 ){
520 return i;
521 }
522 }
523 return -1;
524}
525
526static PyObject *
527xmlparse_getattr(xmlparseobject *self, char *name)
528{
529 int handlernum;
530 if (strcmp(name, "ErrorCode") == 0)
531 return Py_BuildValue("l",
532 (long)XML_GetErrorCode(self->itself));
533 if (strcmp(name, "ErrorLineNumber") == 0)
534 return Py_BuildValue("l",
535 (long)XML_GetErrorLineNumber(self->itself));
536 if (strcmp(name, "ErrorColumnNumber") == 0)
537 return Py_BuildValue("l",
538 (long)XML_GetErrorColumnNumber(self->itself));
539 if (strcmp(name, "ErrorByteIndex") == 0)
540 return Py_BuildValue("l",
541 XML_GetErrorByteIndex(self->itself));
542
543 handlernum=handlername2int( name );
544
545 if( handlernum!=-1 && self->handlers[handlernum]!=NULL){
546 Py_INCREF( self->handlers[handlernum] );
547 return self->handlers[handlernum];
548 }
549
550 if (strcmp(name, "__members__") == 0){
551 int i;
552 PyObject *rc=PyList_New(0);
553 for(i=0; handler_info[i].name!=NULL;i++ ){
554 PyList_Append( rc,
555 PyString_FromString( handler_info[i].name ) );
556 }
557 PyList_Append( rc, PyString_FromString( "ErrorCode" ));
558 PyList_Append( rc, PyString_FromString( "ErrorLineNumber" ));
559 PyList_Append( rc, PyString_FromString( "ErrorColumnNumber"));
560 PyList_Append( rc, PyString_FromString( "ErrorByteIndex" ));
561
562 return rc;
563 }
564
565 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
566}
567
568static int sethandler( xmlparseobject *self, const char *name, PyObject* v ){
569 int handlernum = handlername2int( name );
570 if( handlernum!=-1 ){
571 Py_INCREF( v );
572 Py_XDECREF( self->handlers[handlernum] );
573 self->handlers[handlernum]=v;
574 handler_info[handlernum].setter( self->itself,
575 handler_info[handlernum].handler );
576 return 1;
577 }
578
579 return 0;
580}
581
582static int
583xmlparse_setattr( xmlparseobject *self, char *name, PyObject *v)
584{
585 /* Set attribute 'name' to value 'v'. v==NULL means delete */
586 if (v==NULL) {
587 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
588 return -1;
589 }
590
591 if( sethandler( self, name, v ) ){
592 return 0;
593 }
594
595 PyErr_SetString( PyExc_AttributeError, name );
596 return -1;
597}
598
599static char Xmlparsetype__doc__[] =
600"XML parser"
601;
602
603static PyTypeObject Xmlparsetype = {
604 PyObject_HEAD_INIT(NULL)
605 0, /*ob_size*/
606 "xmlparser", /*tp_name*/
607 sizeof(xmlparseobject), /*tp_basicsize*/
608 0, /*tp_itemsize*/
609 /* methods */
610 (destructor)xmlparse_dealloc, /*tp_dealloc*/
611 (printfunc)0, /*tp_print*/
612 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
613 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
614 (cmpfunc)0, /*tp_compare*/
615 (reprfunc)0, /*tp_repr*/
616 0, /*tp_as_number*/
617 0, /*tp_as_sequence*/
618 0, /*tp_as_mapping*/
619 (hashfunc)0, /*tp_hash*/
620 (ternaryfunc)0, /*tp_call*/
621 (reprfunc)0, /*tp_str*/
622
623 /* Space for future expansion */
624 0L,0L,0L,0L,
625 Xmlparsetype__doc__ /* Documentation string */
626};
627
628/* End of code for xmlparser objects */
629/* -------------------------------------------------------- */
630
631
632static char pyexpat_ParserCreate__doc__[] =
633"([encoding, namespace_separator]) - Return a new XML parser object"
634;
635
636static PyObject *
637pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) {
638 char *encoding = NULL, *namespace_separator=NULL;
639 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
640
641 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz", kwlist,
642 &encoding, &namespace_separator))
643 return NULL;
644 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
645}
646
647static char pyexpat_ErrorString__doc__[] =
648"(errno) Returns string error for given number"
649;
650
651static PyObject *
652pyexpat_ErrorString(self, args)
653 PyObject *self; /* Not used */
654 PyObject *args;
655{
656 long code;
657
658 if (!PyArg_ParseTuple(args, "l", &code))
659 return NULL;
660 return Py_BuildValue("z", XML_ErrorString((int)code));
661}
662
663/* List of methods defined in the module */
664
665static struct PyMethodDef pyexpat_methods[] = {
666 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
667 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
668 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
669 METH_VARARGS, pyexpat_ErrorString__doc__},
670
671 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
672};
673
674
675/* Initialization function for the module (*must* be called initpyexpat) */
676
677static char pyexpat_module_documentation[] =
678"Python wrapper for Expat parser."
679;
680
681void
682initpyexpat(){
683 PyObject *m, *d;
684 char *rev="$Revision$";
685 PyObject *errors_module, *errors_dict;
686
687 Xmlparsetype.ob_type = &PyType_Type;
688
689 /* Create the module and add the functions */
690 m = Py_InitModule4("pyexpat", pyexpat_methods,
691 pyexpat_module_documentation,
692 (PyObject*)NULL,PYTHON_API_VERSION);
693
694 /* Add some symbolic constants to the module */
695 d = PyModule_GetDict(m);
696 ErrorObject = PyString_FromString("pyexpat.error");
697 PyDict_SetItemString(d, "error", ErrorObject);
698
699 PyDict_SetItemString(d,"__version__",
700 PyString_FromStringAndSize(rev+11,
701 strlen(rev+11)-2));
702
703 errors_module=PyModule_New( "errors" );
704 PyDict_SetItemString(d,"errors", errors_module );
705
706 errors_dict=PyModule_GetDict( errors_module );
707
708#define MYCONST(name) \
709 PyDict_SetItemString(errors_dict, #name, \
710 PyString_FromString( XML_ErrorString(name)))
711
712 MYCONST(XML_ERROR_NO_MEMORY);
713 MYCONST(XML_ERROR_SYNTAX);
714 MYCONST(XML_ERROR_NO_ELEMENTS);
715 MYCONST(XML_ERROR_INVALID_TOKEN);
716 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
717 MYCONST(XML_ERROR_PARTIAL_CHAR);
718 MYCONST(XML_ERROR_TAG_MISMATCH);
719 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
720 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
721 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
722 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
723 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
724 MYCONST(XML_ERROR_ASYNC_ENTITY);
725 MYCONST(XML_ERROR_BAD_CHAR_REF);
726 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
727 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
728 MYCONST(XML_ERROR_MISPLACED_XML_PI);
729 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
730 MYCONST(XML_ERROR_INCORRECT_ENCODING);
731
732 /* Check for errors */
733 if (PyErr_Occurred())
734 Py_FatalError("can't initialize module pyexpat");
735}
736
737void clear_handlers( xmlparseobject *self ){
738 int i=0;
739
740 for( i=0;handler_info[i].name!=NULL;i++ ){
741 self->handlers[i]=NULL;
742 handler_info[i].setter( self->itself, NULL );
743 }
744}
745
746typedef void (*pairsetter)( XML_Parser, void *handler1, void *handler2 );
747
748void pyxml_UpdatePairedHandlers( xmlparseobject *self,
749 int startHandler,
750 int endHandler,
751 pairsetter setter){
752 void *start_handler=NULL;
753 void *end_handler=NULL;
754
755 if( self->handlers[startHandler] &&
756 self->handlers[endHandler]!=Py_None ){
757 start_handler=handler_info[startHandler].handler;
758 }
759 if( self->handlers[EndElement] &&
760 self->handlers[EndElement] !=Py_None ){
761 end_handler=handler_info[endHandler].handler;
762 }
763
764 setter(self->itself,
765 start_handler,
766 end_handler);
767}
768
769void pyxml_SetStartElementHandler( XML_Parser *parser,
770 void *junk){
771 pyxml_UpdatePairedHandlers(
772 (xmlparseobject *)XML_GetUserData( parser ),
773 StartElement, EndElement,
774 (pairsetter)XML_SetElementHandler);
775}
776
777void pyxml_SetEndElementHandler( XML_Parser *parser,
778 void *junk){
779 pyxml_UpdatePairedHandlers(
780 (xmlparseobject *)XML_GetUserData( parser ),
781 StartElement, EndElement,
782 (pairsetter)XML_SetElementHandler);
783}
784
785void pyxml_SetStartNamespaceDeclHandler( XML_Parser *parser,
786 void *junk){
787 pyxml_UpdatePairedHandlers(
788 (xmlparseobject *)XML_GetUserData( parser ),
789 StartNamespaceDecl, EndNamespaceDecl,
790 (pairsetter)XML_SetNamespaceDeclHandler);
791}
792
793void pyxml_SetEndNamespaceDeclHandler( XML_Parser *parser,
794 void *junk){
795 pyxml_UpdatePairedHandlers(
796 (xmlparseobject *)XML_GetUserData( parser ),
797 StartNamespaceDecl, EndNamespaceDecl,
798 (pairsetter)XML_SetNamespaceDeclHandler);
799}
800
801void pyxml_SetStartCdataSection( XML_Parser *parser,
802 void *junk){
803
804 pyxml_UpdatePairedHandlers(
805 (xmlparseobject *)XML_GetUserData( parser ),
806 StartCdataSection, EndCdataSection,
807 (pairsetter)XML_SetCdataSectionHandler);
808}
809
810void pyxml_SetEndCdataSection( XML_Parser *parser,
811 void *junk){
812 pyxml_UpdatePairedHandlers(
813 (xmlparseobject *)XML_GetUserData( parser ),
814 StartCdataSection, EndCdataSection,
815 (pairsetter)XML_SetCdataSectionHandler);
816}
817
818static struct HandlerInfo handler_info[]=
819{{"StartElementHandler",
820 pyxml_SetStartElementHandler,
821 my_StartElementHandler},
822{"EndElementHandler",
823 pyxml_SetEndElementHandler,
824 my_EndElementHandler},
825{"ProcessingInstructionHandler",
826 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
827 my_ProcessingInstructionHandler},
828{"CharacterDataHandler",
829 (xmlhandlersetter)XML_SetCharacterDataHandler,
830 my_CharacterDataHandler},
831{"UnparsedEntityDeclHandler",
832 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
833 my_UnparsedEntityDeclHandler },
834{"NotationDeclHandler",
835 (xmlhandlersetter)XML_SetNotationDeclHandler,
836 my_NotationDeclHandler },
837{"StartNamespaceDeclHandler",
838 pyxml_SetStartNamespaceDeclHandler,
839 my_StartNamespaceDeclHandler },
840{"EndNamespaceDeclHandler",
841 pyxml_SetEndNamespaceDeclHandler,
842 my_EndNamespaceDeclHandler },
843{"CommentHandler",
844 (xmlhandlersetter)XML_SetCommentHandler,
845 my_CommentHandler},
846{"StartCdataSectionHandler",
847 pyxml_SetStartCdataSection,
848 my_StartCdataSectionHandler},
849{"EndCdataSectionHandler",
850 pyxml_SetEndCdataSection,
851 my_EndCdataSectionHandler},
852{"DefaultHandler",
853 (xmlhandlersetter)XML_SetDefaultHandler,
854 my_DefaultHandler},
855{"DefaultHandlerExpand",
856 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
857 my_DefaultHandlerExpandHandler},
858{"NotStandaloneHandler",
859 (xmlhandlersetter)XML_SetNotStandaloneHandler,
860 my_NotStandaloneHandler},
861{"ExternalEntityRefHandler",
862 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
863 my_ExternalEntityRefHandler },
864
865{NULL, NULL, NULL } /* sentinel */
866};
867
868