blob: db0ae85800121ceb4e389e477fe18246bf930472 [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
Guido van Rossum5961f5a2000-03-31 16:18:11 +000082staticforward struct HandlerInfo handler_info[];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000083
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
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000150#define NOTHING /**/
151
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000152#define VOID_HANDLER( NAME, PARAMS, PARAM_FORMAT ) \
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000153 RC_HANDLER( void, NAME, PARAMS, NOTHING, PARAM_FORMAT, NOTHING, NOTHING,\
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000154 (xmlparseobject *)userData )
155
156#define INT_HANDLER( NAME, PARAMS, PARAM_FORMAT )\
157 RC_HANDLER( int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
158 rc = PyInt_AsLong( rv );, rc, \
159 (xmlparseobject *)userData )
160
161VOID_HANDLER( StartElement,
162 (void *userData, const XML_Char *name, const XML_Char **atts ),
163 ("(sO&)", name, conv_atts, atts ) )
164
165VOID_HANDLER( EndElement,
166 (void *userData, const XML_Char *name ),
167 ("(s)", name) )
168
169VOID_HANDLER( ProcessingInstruction,
170 (void *userData,
171 const XML_Char *target,
172 const XML_Char *data),
173 ("(ss)",target, data ))
174
175VOID_HANDLER( CharacterData,
176 (void *userData, const XML_Char *data, int len),
177 ("(s#)", data, len ) )
178
179VOID_HANDLER( UnparsedEntityDecl,
180 (void *userData,
181 const XML_Char *entityName,
182 const XML_Char *base,
183 const XML_Char *systemId,
184 const XML_Char *publicId,
185 const XML_Char *notationName),
186 ("(sssss)", entityName, base, systemId, publicId, notationName))
187
188VOID_HANDLER( NotationDecl,
189 (void *userData,
190 const XML_Char *notationName,
191 const XML_Char *base,
192 const XML_Char *systemId,
193 const XML_Char *publicId),
194 ("(ssss)", notationName, base, systemId, publicId))
195
196VOID_HANDLER( StartNamespaceDecl,
197 (void *userData,
198 const XML_Char *prefix,
199 const XML_Char *uri),
200 ("(ss)", prefix, uri ))
201
202VOID_HANDLER( EndNamespaceDecl,
203 (void *userData,
204 const XML_Char *prefix),
205 ("(s)", prefix ))
206
207VOID_HANDLER( Comment,
208 (void *userData, const XML_Char *prefix),
209 ("(s)", prefix))
210
211VOID_HANDLER( StartCdataSection,
212 (void *userData),
213 ("()" ))
214
215VOID_HANDLER( EndCdataSection,
216 (void *userData),
217 ("()" ))
218
219VOID_HANDLER( Default,
220 (void *userData, const XML_Char *s, int len),
221 ("(s#)",s,len))
222
223VOID_HANDLER( DefaultHandlerExpand,
224 (void *userData, const XML_Char *s, int len),
225 ("(s#)",s,len))
226
227INT_HANDLER( NotStandalone,
228 (void *userData),
229 ("()"))
230
231RC_HANDLER( int, ExternalEntityRef,
232 (XML_Parser parser,
233 const XML_Char *context,
234 const XML_Char *base,
235 const XML_Char *systemId,
236 const XML_Char *publicId),
237 int rc=0;,
238 ("(ssss)", context, base, systemId, publicId ),
239 rc = PyInt_AsLong( rv );, rc,
240 XML_GetUserData( parser ) )
241
242
243
244/* File reading copied from cPickle */
245
246#define UNLESS(E) if (!(E))
247
248/*
249static int
250read_other(xmlparseobject *self, char **s, int n) {
251 PyObject *bytes=NULL, *str=NULL, *arg=NULL;
252 int res = -1;
253
254 UNLESS(bytes = PyInt_FromLong(n)) {
255 if (!PyErr_Occurred())
256 PyErr_SetNone(PyExc_EOFError);
257
258 goto finally;
259 }
260
261 UNLESS(arg)
262 UNLESS(arg = PyTuple_New(1))
263 goto finally;
264
265 Py_INCREF(bytes);
266 if (PyTuple_SetItem(arg, 0, bytes) < 0)
267 goto finally;
268
269 UNLESS(str = PyObject_CallObject(self->read, arg))
270 goto finally;
271
272 *s = PyString_AsString(str);
273
274 res = n;
275
276finally:
277 Py_XDECREF(arg);
278 Py_XDECREF(bytes);
279
280 return res;
281}
282
283*/
284
285
286
287
288
289/* ---------------------------------------------------------------- */
290
291static char xmlparse_Parse__doc__[] =
292"(data [,isfinal]) - Parse XML data"
293;
294
295static PyObject *
296xmlparse_Parse( xmlparseobject *self, PyObject *args )
297{
298 char *s;
299 int slen;
300 int isFinal = 0;
301 int rv;
302
303 if (!PyArg_ParseTuple(args, "s#|i", &s, &slen, &isFinal))
304 return NULL;
305 rv = XML_Parse(self->itself, s, slen, isFinal);
306 if( PyErr_Occurred() ){
307 return NULL;
308 }
309 else if (rv == 0) {
310 PyErr_Format(ErrorObject, "%s: line %i, column %i",
311 XML_ErrorString( XML_GetErrorCode(self->itself) ),
312 XML_GetErrorLineNumber(self->itself),
313 XML_GetErrorColumnNumber(self->itself) );
314 return NULL;
315 }
316
317 return Py_BuildValue("i", rv);
318}
319
320#define BUF_SIZE 2048
321
322int readinst(char *buf, int buf_size, PyObject *meth){
323 PyObject *arg=NULL;
324 PyObject *bytes=NULL;
325 PyObject *str=NULL;
326 int len;
327
328 UNLESS(bytes = PyInt_FromLong(buf_size)) {
329 if (!PyErr_Occurred())
330 PyErr_SetNone(PyExc_EOFError);
331 goto finally;
332 }
333
334 UNLESS(arg)
335 UNLESS(arg = PyTuple_New(1))
336 goto finally;
337
338 Py_INCREF(bytes);
339 if (PyTuple_SetItem(arg, 0, bytes) < 0)
340 goto finally;
341
342 UNLESS(str = PyObject_CallObject(meth, arg))
343 goto finally;
344
345 UNLESS(PyString_Check( str ))
346 goto finally;
347
348 len=PyString_GET_SIZE( str );
349 strncpy( buf, PyString_AsString(str), len );
350 Py_XDECREF( str );
351finally:
352 return len;
353}
354
355static char xmlparse_ParseFile__doc__[] =
356"(file) - Parse XML data"
357;
358
359static PyObject *
360xmlparse_ParseFile( xmlparseobject *self, PyObject *args )
361{
362 int rv=1;
363 PyObject *f;
364 FILE *fp;
365 PyObject *readmethod=NULL;
366
367 if (!PyArg_ParseTuple(args, "O", &f))
368 return NULL;
369
370 if (PyFile_Check(f)) {
371 fp = PyFile_AsFile(f);
372 }else{
373 fp = NULL;
374 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
375 PyErr_Clear();
376 PyErr_SetString( PyExc_TypeError,
377 "argument must have 'read' attribute" );
378 return 0;
379 }
380 }
381
382 for (;;) {
383 int bytes_read;
384 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
385 if (buf == NULL) {
386 /* FIXME: throw exception for no memory */
387 return NULL;
388 }
389
390 if( fp ){
391 bytes_read=fread( buf, sizeof( char ), BUF_SIZE, fp);
392 }else{
393 bytes_read=readinst( buf, BUF_SIZE, readmethod );
394 }
395
396 if (bytes_read < 0) {
397 PyErr_SetFromErrno(PyExc_IOError);
398 return NULL;
399 }
400 rv=XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
401 if( PyErr_Occurred() ){
402 return NULL;
403 }
404 if (!rv || bytes_read == 0)
405 break;
406 }
407
408 return Py_BuildValue("i", rv);
409}
410
411static char xmlparse_SetBase__doc__[] =
412"(base_url) - Base URL string"
413;
414
415static PyObject *
416xmlparse_SetBase( xmlparseobject *self, PyObject *args ){
417 char *base;
418
419 if (!PyArg_ParseTuple(args, "s", &base))
420 return NULL;
421 if( !XML_SetBase( self->itself, base ) ){
422 PyErr_SetNone(PyExc_MemoryError);
423 return NULL;
424 }
425
426 Py_INCREF(Py_None);
427 return Py_None;
428}
429
430static char xmlparse_GetBase__doc__[] =
431"() - returns base URL string "
432;
433
434static PyObject *
435xmlparse_GetBase( xmlparseobject *self, PyObject *args ){
436 const XML_Char *base;
437 PyObject *rc;
438
439 if( PyTuple_Size( args )!=0 ){
440 PyArg_ParseTuple(args, "()" ); /* get good error reporting */
441 return NULL;
442 }
443 base=XML_GetBase( self->itself );
444 if( base ){
445 rc=Py_BuildValue("s", base);
446 }else{
447 Py_INCREF(Py_None);
448 rc=Py_None;
449 }
450 return rc;
451
452}
453
454static struct PyMethodDef xmlparse_methods[] = {
455 {"Parse", (PyCFunction)xmlparse_Parse,
456 METH_VARARGS, xmlparse_Parse__doc__},
457 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
458 METH_VARARGS, xmlparse_ParseFile__doc__},
459 {"SetBase", (PyCFunction)xmlparse_SetBase,
460 METH_VARARGS, xmlparse_SetBase__doc__},
461 {"GetBase", (PyCFunction)xmlparse_GetBase,
462 METH_VARARGS, xmlparse_GetBase__doc__},
463 {NULL, NULL} /* sentinel */
464};
465
466/* ---------- */
467
468
469static xmlparseobject *
470newxmlparseobject( char *encoding, char *namespace_separator){
471 int i;
472 xmlparseobject *self;
473
474 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
475 if (self == NULL)
476 return NULL;
477
478 if (namespace_separator) {
479 self->itself = XML_ParserCreateNS(encoding,
480 *namespace_separator);
481 }else{
482 self->itself = XML_ParserCreate(encoding);
483 }
484
485 if( self->itself==NULL ){
486 PyErr_SetString(PyExc_RuntimeError,
487 "XML_ParserCreate failed");
488 Py_DECREF(self);
489 return NULL;
490 }
491
492 XML_SetUserData(self->itself, (void *)self);
493
494 for( i=0; handler_info[i].name!=NULL;i++);
495
496 self->handlers=malloc( sizeof( PyObject *)*i );
497
498 clear_handlers( self );
499
500 return self;
501}
502
503
504static void
505xmlparse_dealloc( xmlparseobject *self )
506{
507 int i;
508 if (self->itself)
509 XML_ParserFree(self->itself);
510 self->itself = NULL;
511
512 for( i=0; handler_info[i].name!=NULL; i++ ){
513 Py_XDECREF( self->handlers[i] );
514 }
515 PyMem_DEL(self);
516}
517
518static int handlername2int( const char *name ){
519 int i;
520 for( i=0;handler_info[i].name!=NULL;i++){
521 if( strcmp( name, handler_info[i].name )==0 ){
522 return i;
523 }
524 }
525 return -1;
526}
527
528static PyObject *
529xmlparse_getattr(xmlparseobject *self, char *name)
530{
531 int handlernum;
532 if (strcmp(name, "ErrorCode") == 0)
533 return Py_BuildValue("l",
534 (long)XML_GetErrorCode(self->itself));
535 if (strcmp(name, "ErrorLineNumber") == 0)
536 return Py_BuildValue("l",
537 (long)XML_GetErrorLineNumber(self->itself));
538 if (strcmp(name, "ErrorColumnNumber") == 0)
539 return Py_BuildValue("l",
540 (long)XML_GetErrorColumnNumber(self->itself));
541 if (strcmp(name, "ErrorByteIndex") == 0)
542 return Py_BuildValue("l",
543 XML_GetErrorByteIndex(self->itself));
544
545 handlernum=handlername2int( name );
546
547 if( handlernum!=-1 && self->handlers[handlernum]!=NULL){
548 Py_INCREF( self->handlers[handlernum] );
549 return self->handlers[handlernum];
550 }
551
552 if (strcmp(name, "__members__") == 0){
553 int i;
554 PyObject *rc=PyList_New(0);
555 for(i=0; handler_info[i].name!=NULL;i++ ){
556 PyList_Append( rc,
557 PyString_FromString( handler_info[i].name ) );
558 }
559 PyList_Append( rc, PyString_FromString( "ErrorCode" ));
560 PyList_Append( rc, PyString_FromString( "ErrorLineNumber" ));
561 PyList_Append( rc, PyString_FromString( "ErrorColumnNumber"));
562 PyList_Append( rc, PyString_FromString( "ErrorByteIndex" ));
563
564 return rc;
565 }
566
567 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
568}
569
570static int sethandler( xmlparseobject *self, const char *name, PyObject* v ){
571 int handlernum = handlername2int( name );
572 if( handlernum!=-1 ){
573 Py_INCREF( v );
574 Py_XDECREF( self->handlers[handlernum] );
575 self->handlers[handlernum]=v;
576 handler_info[handlernum].setter( self->itself,
577 handler_info[handlernum].handler );
578 return 1;
579 }
580
581 return 0;
582}
583
584static int
585xmlparse_setattr( xmlparseobject *self, char *name, PyObject *v)
586{
587 /* Set attribute 'name' to value 'v'. v==NULL means delete */
588 if (v==NULL) {
589 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
590 return -1;
591 }
592
593 if( sethandler( self, name, v ) ){
594 return 0;
595 }
596
597 PyErr_SetString( PyExc_AttributeError, name );
598 return -1;
599}
600
601static char Xmlparsetype__doc__[] =
602"XML parser"
603;
604
605static PyTypeObject Xmlparsetype = {
606 PyObject_HEAD_INIT(NULL)
607 0, /*ob_size*/
608 "xmlparser", /*tp_name*/
609 sizeof(xmlparseobject), /*tp_basicsize*/
610 0, /*tp_itemsize*/
611 /* methods */
612 (destructor)xmlparse_dealloc, /*tp_dealloc*/
613 (printfunc)0, /*tp_print*/
614 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
615 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
616 (cmpfunc)0, /*tp_compare*/
617 (reprfunc)0, /*tp_repr*/
618 0, /*tp_as_number*/
619 0, /*tp_as_sequence*/
620 0, /*tp_as_mapping*/
621 (hashfunc)0, /*tp_hash*/
622 (ternaryfunc)0, /*tp_call*/
623 (reprfunc)0, /*tp_str*/
624
625 /* Space for future expansion */
626 0L,0L,0L,0L,
627 Xmlparsetype__doc__ /* Documentation string */
628};
629
630/* End of code for xmlparser objects */
631/* -------------------------------------------------------- */
632
633
634static char pyexpat_ParserCreate__doc__[] =
635"([encoding, namespace_separator]) - Return a new XML parser object"
636;
637
638static PyObject *
639pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) {
640 char *encoding = NULL, *namespace_separator=NULL;
641 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
642
643 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz", kwlist,
644 &encoding, &namespace_separator))
645 return NULL;
646 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
647}
648
649static char pyexpat_ErrorString__doc__[] =
650"(errno) Returns string error for given number"
651;
652
653static PyObject *
654pyexpat_ErrorString(self, args)
655 PyObject *self; /* Not used */
656 PyObject *args;
657{
658 long code;
659
660 if (!PyArg_ParseTuple(args, "l", &code))
661 return NULL;
662 return Py_BuildValue("z", XML_ErrorString((int)code));
663}
664
665/* List of methods defined in the module */
666
667static struct PyMethodDef pyexpat_methods[] = {
668 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
669 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
670 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
671 METH_VARARGS, pyexpat_ErrorString__doc__},
672
673 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
674};
675
676
677/* Initialization function for the module (*must* be called initpyexpat) */
678
679static char pyexpat_module_documentation[] =
680"Python wrapper for Expat parser."
681;
682
683void
684initpyexpat(){
685 PyObject *m, *d;
686 char *rev="$Revision$";
687 PyObject *errors_module, *errors_dict;
688
689 Xmlparsetype.ob_type = &PyType_Type;
690
691 /* Create the module and add the functions */
692 m = Py_InitModule4("pyexpat", pyexpat_methods,
693 pyexpat_module_documentation,
694 (PyObject*)NULL,PYTHON_API_VERSION);
695
696 /* Add some symbolic constants to the module */
697 d = PyModule_GetDict(m);
698 ErrorObject = PyString_FromString("pyexpat.error");
699 PyDict_SetItemString(d, "error", ErrorObject);
700
701 PyDict_SetItemString(d,"__version__",
702 PyString_FromStringAndSize(rev+11,
703 strlen(rev+11)-2));
704
705 errors_module=PyModule_New( "errors" );
706 PyDict_SetItemString(d,"errors", errors_module );
707
708 errors_dict=PyModule_GetDict( errors_module );
709
710#define MYCONST(name) \
711 PyDict_SetItemString(errors_dict, #name, \
712 PyString_FromString( XML_ErrorString(name)))
713
714 MYCONST(XML_ERROR_NO_MEMORY);
715 MYCONST(XML_ERROR_SYNTAX);
716 MYCONST(XML_ERROR_NO_ELEMENTS);
717 MYCONST(XML_ERROR_INVALID_TOKEN);
718 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
719 MYCONST(XML_ERROR_PARTIAL_CHAR);
720 MYCONST(XML_ERROR_TAG_MISMATCH);
721 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
722 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
723 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
724 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
725 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
726 MYCONST(XML_ERROR_ASYNC_ENTITY);
727 MYCONST(XML_ERROR_BAD_CHAR_REF);
728 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
729 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
730 MYCONST(XML_ERROR_MISPLACED_XML_PI);
731 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
732 MYCONST(XML_ERROR_INCORRECT_ENCODING);
733
734 /* Check for errors */
735 if (PyErr_Occurred())
736 Py_FatalError("can't initialize module pyexpat");
737}
738
739void clear_handlers( xmlparseobject *self ){
740 int i=0;
741
742 for( i=0;handler_info[i].name!=NULL;i++ ){
743 self->handlers[i]=NULL;
744 handler_info[i].setter( self->itself, NULL );
745 }
746}
747
748typedef void (*pairsetter)( XML_Parser, void *handler1, void *handler2 );
749
750void pyxml_UpdatePairedHandlers( xmlparseobject *self,
751 int startHandler,
752 int endHandler,
753 pairsetter setter){
754 void *start_handler=NULL;
755 void *end_handler=NULL;
756
757 if( self->handlers[startHandler] &&
758 self->handlers[endHandler]!=Py_None ){
759 start_handler=handler_info[startHandler].handler;
760 }
761 if( self->handlers[EndElement] &&
762 self->handlers[EndElement] !=Py_None ){
763 end_handler=handler_info[endHandler].handler;
764 }
765
766 setter(self->itself,
767 start_handler,
768 end_handler);
769}
770
771void pyxml_SetStartElementHandler( XML_Parser *parser,
772 void *junk){
773 pyxml_UpdatePairedHandlers(
774 (xmlparseobject *)XML_GetUserData( parser ),
775 StartElement, EndElement,
776 (pairsetter)XML_SetElementHandler);
777}
778
779void pyxml_SetEndElementHandler( XML_Parser *parser,
780 void *junk){
781 pyxml_UpdatePairedHandlers(
782 (xmlparseobject *)XML_GetUserData( parser ),
783 StartElement, EndElement,
784 (pairsetter)XML_SetElementHandler);
785}
786
787void pyxml_SetStartNamespaceDeclHandler( XML_Parser *parser,
788 void *junk){
789 pyxml_UpdatePairedHandlers(
790 (xmlparseobject *)XML_GetUserData( parser ),
791 StartNamespaceDecl, EndNamespaceDecl,
792 (pairsetter)XML_SetNamespaceDeclHandler);
793}
794
795void pyxml_SetEndNamespaceDeclHandler( XML_Parser *parser,
796 void *junk){
797 pyxml_UpdatePairedHandlers(
798 (xmlparseobject *)XML_GetUserData( parser ),
799 StartNamespaceDecl, EndNamespaceDecl,
800 (pairsetter)XML_SetNamespaceDeclHandler);
801}
802
803void pyxml_SetStartCdataSection( XML_Parser *parser,
804 void *junk){
805
806 pyxml_UpdatePairedHandlers(
807 (xmlparseobject *)XML_GetUserData( parser ),
808 StartCdataSection, EndCdataSection,
809 (pairsetter)XML_SetCdataSectionHandler);
810}
811
812void pyxml_SetEndCdataSection( XML_Parser *parser,
813 void *junk){
814 pyxml_UpdatePairedHandlers(
815 (xmlparseobject *)XML_GetUserData( parser ),
816 StartCdataSection, EndCdataSection,
817 (pairsetter)XML_SetCdataSectionHandler);
818}
819
820static struct HandlerInfo handler_info[]=
821{{"StartElementHandler",
822 pyxml_SetStartElementHandler,
823 my_StartElementHandler},
824{"EndElementHandler",
825 pyxml_SetEndElementHandler,
826 my_EndElementHandler},
827{"ProcessingInstructionHandler",
828 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
829 my_ProcessingInstructionHandler},
830{"CharacterDataHandler",
831 (xmlhandlersetter)XML_SetCharacterDataHandler,
832 my_CharacterDataHandler},
833{"UnparsedEntityDeclHandler",
834 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
835 my_UnparsedEntityDeclHandler },
836{"NotationDeclHandler",
837 (xmlhandlersetter)XML_SetNotationDeclHandler,
838 my_NotationDeclHandler },
839{"StartNamespaceDeclHandler",
840 pyxml_SetStartNamespaceDeclHandler,
841 my_StartNamespaceDeclHandler },
842{"EndNamespaceDeclHandler",
843 pyxml_SetEndNamespaceDeclHandler,
844 my_EndNamespaceDeclHandler },
845{"CommentHandler",
846 (xmlhandlersetter)XML_SetCommentHandler,
847 my_CommentHandler},
848{"StartCdataSectionHandler",
849 pyxml_SetStartCdataSection,
850 my_StartCdataSectionHandler},
851{"EndCdataSectionHandler",
852 pyxml_SetEndCdataSection,
853 my_EndCdataSectionHandler},
854{"DefaultHandler",
855 (xmlhandlersetter)XML_SetDefaultHandler,
856 my_DefaultHandler},
857{"DefaultHandlerExpand",
858 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
859 my_DefaultHandlerExpandHandler},
860{"NotStandaloneHandler",
861 (xmlhandlersetter)XML_SetNotStandaloneHandler,
862 my_NotStandaloneHandler},
863{"ExternalEntityRefHandler",
864 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
865 my_ExternalEntityRefHandler },
866
867{NULL, NULL, NULL } /* sentinel */
868};
869
870