blob: c72b7384c76ea4de6a7d675e60cf3c4f9bc78805 [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
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000014
15******************************************************************/
16
17#include "Python.h"
18#include "xmlparse.h"
19
20/*
21** The version number should match the one in _checkversion
22*/
23#define VERSION "1.9"
24
Fred Drake0582df92000-07-12 04:49:00 +000025enum HandlerTypes {
26 StartElement,
27 EndElement,
28 ProcessingInstruction,
29 CharacterData,
30 UnparsedEntityDecl,
31 NotationDecl,
32 StartNamespaceDecl,
33 EndNamespaceDecl,
34 Comment,
35 StartCdataSection,
36 EndCdataSection,
37 Default,
38 DefaultHandlerExpand,
39 NotStandalone,
40 ExternalEntityRef
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000041};
42
43static PyObject *ErrorObject;
44
45/* ----------------------------------------------------- */
46
47/* Declarations for objects of type xmlparser */
48
49typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000050 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000051
Fred Drake0582df92000-07-12 04:49:00 +000052 XML_Parser itself;
53 int returns_unicode; /* True if Unicode strings are returned;
54 if false, UTF-8 strings are returned */
55 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000056} xmlparseobject;
57
58staticforward PyTypeObject Xmlparsetype;
59
60typedef void (*xmlhandlersetter)( XML_Parser *self, void *meth );
61typedef void* xmlhandler;
62
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000063struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000064 const char *name;
65 xmlhandlersetter setter;
66 xmlhandler handler;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000067};
68
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000069staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000070
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000071/* Convert an array of attributes and their values into a Python dict */
72
Fred Drake0582df92000-07-12 04:49:00 +000073static PyObject *
74conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000075{
Fred Drake0582df92000-07-12 04:49:00 +000076 PyObject *attrs_obj = NULL;
77 XML_Char **attrs_p, **attrs_k = NULL;
78 int attrs_len;
79 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000080
Fred Drake0582df92000-07-12 04:49:00 +000081 if ((attrs_obj = PyDict_New()) == NULL)
82 goto finally;
83 for (attrs_len = 0, attrs_p = atts;
84 *attrs_p;
85 attrs_p++, attrs_len++) {
86 if (attrs_len % 2) {
87 rv = PyString_FromString(*attrs_p);
88 if (!rv) {
89 Py_DECREF(attrs_obj);
90 attrs_obj = NULL;
91 goto finally;
92 }
93 if (PyDict_SetItemString(attrs_obj,
94 (char*)*attrs_k, rv) < 0) {
95 Py_DECREF(attrs_obj);
96 attrs_obj = NULL;
97 goto finally;
98 }
99 Py_DECREF(rv);
100 }
101 else
102 attrs_k = attrs_p;
103 }
104 finally:
105 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000106}
107
108#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +0000109static PyObject *
110conv_atts_using_unicode(XML_Char **atts)
111{
112 PyObject *attrs_obj = NULL;
113 XML_Char **attrs_p, **attrs_k = NULL;
114 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000115
Fred Drake0582df92000-07-12 04:49:00 +0000116 if ((attrs_obj = PyDict_New()) == NULL)
117 goto finally;
118 for (attrs_len = 0, attrs_p = atts;
119 *attrs_p;
120 attrs_p++, attrs_len++) {
121 if (attrs_len % 2) {
122 PyObject *attr_str, *value_str;
123 const char *p = (const char *) (*attrs_k);
124 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
125 if (!attr_str) {
126 Py_DECREF(attrs_obj);
127 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000128 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000129 }
130 p = (const char *) *attrs_p;
131 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
132 if (!value_str) {
133 Py_DECREF(attrs_obj);
134 Py_DECREF(attr_str);
135 attrs_obj = NULL;
136 goto finally;
137 }
138 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
139 Py_DECREF(attrs_obj);
140 attrs_obj = NULL;
141 goto finally;
142 }
143 Py_DECREF(attr_str);
144 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000145 }
Fred Drake0582df92000-07-12 04:49:00 +0000146 else
147 attrs_k = attrs_p;
148 }
149 finally:
150 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000151}
152
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000153/* Convert a string of XML_Chars into a Unicode string.
154 Returns None if str is a null pointer. */
155
Fred Drake0582df92000-07-12 04:49:00 +0000156static PyObject *
157conv_string_to_unicode(XML_Char *str)
158{
159 /* XXX currently this code assumes that XML_Char is 8-bit,
160 and hence in UTF-8. */
161 /* UTF-8 from Expat, Unicode desired */
162 if (str == NULL) {
163 Py_INCREF(Py_None);
164 return Py_None;
165 }
166 return PyUnicode_DecodeUTF8((const char *)str,
167 strlen((const char *)str),
168 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000169}
170
Fred Drake0582df92000-07-12 04:49:00 +0000171static PyObject *
172conv_string_len_to_unicode(const XML_Char *str, int len)
173{
174 /* XXX currently this code assumes that XML_Char is 8-bit,
175 and hence in UTF-8. */
176 /* UTF-8 from Expat, Unicode desired */
177 if (str == NULL) {
178 Py_INCREF(Py_None);
179 return Py_None;
180 }
181 return PyUnicode_DecodeUTF8((const char *)str,
182 len,
183 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000184}
185#endif
186
187/* Convert a string of XML_Chars into an 8-bit Python string.
188 Returns None if str is a null pointer. */
189
190static PyObject *conv_string_to_utf8( XML_Char *str ) {
191 /* XXX currently this code assumes that XML_Char is 8-bit,
192 and hence in UTF-8. */
193 /* UTF-8 from Expat, UTF-8 desired */
194 if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
195 return PyString_FromString( (const char *)str );
196}
197
198static PyObject *conv_string_len_to_utf8( const XML_Char *str,
199 int len )
200{
201 /* XXX currently this code assumes that XML_Char is 8-bit,
202 and hence in UTF-8. */
203 /* UTF-8 from Expat, UTF-8 desired */
204 if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
205 return PyString_FromStringAndSize( (const char *)str, len );
206}
207
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000208/* Callback routines */
209
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000210static void clear_handlers( xmlparseobject *self );
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000211
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000212static void flag_error( xmlparseobject *self ){
213 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000214}
215
216#define RC_HANDLER( RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000217 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000218\
219static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000220 xmlparseobject *self = GETUSERDATA ; \
221 PyObject *args=NULL; \
222 PyObject *rv=NULL; \
223 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000224\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000225 if (self->handlers[NAME] \
226 && self->handlers[NAME] != Py_None) { \
227 args = Py_BuildValue PARAM_FORMAT ;\
228 if (!args) return RETURN; \
229 rv = PyEval_CallObject(self->handlers[NAME], args); \
230 Py_DECREF(args); \
231 if (rv == NULL) { \
232 flag_error( self ); \
233 return RETURN; \
234 } \
235 CONVERSION \
236 Py_DECREF(rv); \
237 } \
238 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000239}
240
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000241#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
242#define STRING_CONV_FUNC conv_string_to_utf8
243#else
244/* Python 1.6 and later versions */
245#define STRING_CONV_FUNC (self->returns_unicode \
246 ? conv_string_to_unicode : conv_string_to_utf8)
247#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000248
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000249#define VOID_HANDLER( NAME, PARAMS, PARAM_FORMAT ) \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000250 RC_HANDLER( void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
251 (xmlparseobject *)userData )
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000252
253#define INT_HANDLER( NAME, PARAMS, PARAM_FORMAT )\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000254 RC_HANDLER( int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
255 rc = PyInt_AsLong( rv );, rc, \
256 (xmlparseobject *)userData )
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000257
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000258#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000259VOID_HANDLER( StartElement,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000260 (void *userData, const XML_Char *name, const XML_Char **atts ),
261 ("(O&O&)", STRING_CONV_FUNC, name,
262 conv_atts_using_string, atts ) )
263#else
264/* Python 1.6 and later */
265VOID_HANDLER( StartElement,
266 (void *userData, const XML_Char *name, const XML_Char **atts ),
267 ("(O&O&)", STRING_CONV_FUNC, name,
268 (self->returns_unicode
269 ? conv_atts_using_unicode
270 : conv_atts_using_string), atts ) )
271#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000272
273VOID_HANDLER( EndElement,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000274 (void *userData, const XML_Char *name ),
275 ("(O&)", STRING_CONV_FUNC, name) )
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000276
277VOID_HANDLER( ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000278 (void *userData,
279 const XML_Char *target,
280 const XML_Char *data),
281 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data ))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000282
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000283#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000284VOID_HANDLER( CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000285 (void *userData, const XML_Char *data, int len),
286 ("(O)", conv_string_len_to_utf8(data,len) ) )
287#else
288VOID_HANDLER( CharacterData,
289 (void *userData, const XML_Char *data, int len),
290 ("(O)", (self->returns_unicode
291 ? conv_string_len_to_unicode(data,len)
292 : conv_string_len_to_utf8(data,len) ) ) )
293#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000294
295VOID_HANDLER( UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000296 (void *userData,
297 const XML_Char *entityName,
298 const XML_Char *base,
299 const XML_Char *systemId,
300 const XML_Char *publicId,
301 const XML_Char *notationName),
302 ("(O&O&O&O&O&)",
303 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
304 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
305 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000306
307VOID_HANDLER( NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000308 (void *userData,
309 const XML_Char *notationName,
310 const XML_Char *base,
311 const XML_Char *systemId,
312 const XML_Char *publicId),
313 ("(O&O&O&O&)",
314 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
315 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000316
317VOID_HANDLER( StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000318 (void *userData,
319 const XML_Char *prefix,
320 const XML_Char *uri),
321 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri ))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000322
323VOID_HANDLER( EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000324 (void *userData,
325 const XML_Char *prefix),
326 ("(O&)", STRING_CONV_FUNC,prefix ))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000327
328VOID_HANDLER( Comment,
329 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000330 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000331
332VOID_HANDLER( StartCdataSection,
333 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000334 ("()" ))
335
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000336VOID_HANDLER( EndCdataSection,
337 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000338 ("()" ))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000339
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000340#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000341VOID_HANDLER( Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000342 (void *userData, const XML_Char *s, int len),
343 ("(O)", conv_string_len_to_utf8(s,len) ) )
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000344
345VOID_HANDLER( DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000346 (void *userData, const XML_Char *s, int len),
347 ("(O)", conv_string_len_to_utf8(s,len) ) )
348#else
349VOID_HANDLER( Default,
350 (void *userData, const XML_Char *s, int len),
351 ("(O)", (self->returns_unicode
352 ? conv_string_len_to_unicode(s,len)
353 : conv_string_len_to_utf8(s,len) ) ) )
354
355VOID_HANDLER( DefaultHandlerExpand,
356 (void *userData, const XML_Char *s, int len),
357 ("(O)", (self->returns_unicode
358 ? conv_string_len_to_unicode(s,len)
359 : conv_string_len_to_utf8(s,len) ) ) )
360#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000361
362INT_HANDLER( NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000363 (void *userData),
364 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000365
366RC_HANDLER( int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000367 (XML_Parser parser,
368 const XML_Char *context,
369 const XML_Char *base,
370 const XML_Char *systemId,
371 const XML_Char *publicId),
372 int rc=0;,
373 ("(O&O&O&O&)",
374 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
375 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId ),
376 rc = PyInt_AsLong( rv );, rc,
377 XML_GetUserData( parser ) )
378
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000379
380
381/* File reading copied from cPickle */
382
383#define UNLESS(E) if (!(E))
384
385/*
386static int
387read_other(xmlparseobject *self, char **s, int n) {
388 PyObject *bytes=NULL, *str=NULL, *arg=NULL;
389 int res = -1;
390
391 UNLESS(bytes = PyInt_FromLong(n)) {
392 if (!PyErr_Occurred())
393 PyErr_SetNone(PyExc_EOFError);
394
395 goto finally;
396 }
397
398 UNLESS(arg)
399 UNLESS(arg = PyTuple_New(1))
400 goto finally;
401
402 Py_INCREF(bytes);
403 if (PyTuple_SetItem(arg, 0, bytes) < 0)
404 goto finally;
405
406 UNLESS(str = PyObject_CallObject(self->read, arg))
407 goto finally;
408
409 *s = PyString_AsString(str);
410
411 res = n;
412
413finally:
414 Py_XDECREF(arg);
415 Py_XDECREF(bytes);
416
417 return res;
418}
419
420*/
421
422
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000423
424/* ---------------------------------------------------------------- */
425
426static char xmlparse_Parse__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000427"Parse(data[, isfinal])
428Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000429
430static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000431xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000432{
Fred Drake0582df92000-07-12 04:49:00 +0000433 char *s;
434 int slen;
435 int isFinal = 0;
436 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000437
Fred Drake0582df92000-07-12 04:49:00 +0000438 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
439 return NULL;
440 rv = XML_Parse(self->itself, s, slen, isFinal);
441 if (PyErr_Occurred()) {
442 return NULL;
443 }
444 else if (rv == 0) {
445 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
446 XML_ErrorString(XML_GetErrorCode(self->itself)),
447 XML_GetErrorLineNumber(self->itself),
448 XML_GetErrorColumnNumber(self->itself));
449 return NULL;
450 }
451 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000452}
453
454#define BUF_SIZE 2048
455
Fred Drake0582df92000-07-12 04:49:00 +0000456static int
457readinst(char *buf, int buf_size, PyObject *meth)
458{
459 PyObject *arg = NULL;
460 PyObject *bytes = NULL;
461 PyObject *str = NULL;
462 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000463
Fred Drake0582df92000-07-12 04:49:00 +0000464 UNLESS(bytes = PyInt_FromLong(buf_size)) {
465 if (!PyErr_Occurred())
466 PyErr_SetNone(PyExc_EOFError);
467 goto finally;
468 }
469 UNLESS(arg)
470 UNLESS(arg = PyTuple_New(1))
471 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000472
Fred Drake0582df92000-07-12 04:49:00 +0000473 if (PyTuple_SetItem(arg, 0, bytes) < 0)
474 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000475
Fred Drake0582df92000-07-12 04:49:00 +0000476 UNLESS(str = PyObject_CallObject(meth, arg))
477 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000478
Fred Drake0582df92000-07-12 04:49:00 +0000479 /* XXX what to do if it returns a Unicode string? */
480 UNLESS(PyString_Check( str )) {
481 PyErr_Format(PyExc_TypeError,
482 "read() did not return a string object (type=%.400s)",
483 str->ob_type->tp_name);
484 goto finally;
485 }
486 len = PyString_GET_SIZE(str);
487 if (len > buf_size) {
488 PyErr_Format(PyExc_ValueError,
489 "read() returned too much data: "
490 "%i bytes requested, %i returned",
491 buf_size, len);
492 Py_DECREF(str);
493 goto finally;
494 }
495 memcpy(buf, PyString_AsString(str), len);
496 Py_XDECREF(str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000497finally:
Fred Drake0582df92000-07-12 04:49:00 +0000498 Py_XDECREF(arg);
499 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500}
501
502static char xmlparse_ParseFile__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000503"ParseFile(file)
504Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505
506static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000507xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000508{
Fred Drake0582df92000-07-12 04:49:00 +0000509 int rv = 1;
510 PyObject *f;
511 FILE *fp;
512 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000513
Fred Drake0582df92000-07-12 04:49:00 +0000514 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
515 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000516
Fred Drake0582df92000-07-12 04:49:00 +0000517 if (PyFile_Check(f)) {
518 fp = PyFile_AsFile(f);
519 }
520 else{
521 fp = NULL;
522 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
523 PyErr_Clear();
524 PyErr_SetString(PyExc_TypeError,
525 "argument must have 'read' attribute");
526 return 0;
527 }
528 }
529 for (;;) {
530 int bytes_read;
531 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
532 if (buf == NULL)
533 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000534
Fred Drake0582df92000-07-12 04:49:00 +0000535 if (fp) {
536 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
537 if (bytes_read < 0) {
538 PyErr_SetFromErrno(PyExc_IOError);
539 return NULL;
540 }
541 }
542 else {
543 bytes_read = readinst(buf, BUF_SIZE, readmethod);
544 if (bytes_read < 0)
545 return NULL;
546 }
547 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
548 if (PyErr_Occurred())
549 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000550
Fred Drake0582df92000-07-12 04:49:00 +0000551 if (!rv || bytes_read == 0)
552 break;
553 }
554 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000555}
556
557static char xmlparse_SetBase__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000558"SetBase(base_url)
559Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000560
561static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000562xmlparse_SetBase(xmlparseobject *self, PyObject *args)
563{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000564 char *base;
565
Fred Drake0582df92000-07-12 04:49:00 +0000566 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000567 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000568 if (!XML_SetBase(self->itself, base)) {
569 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000570 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000571 Py_INCREF(Py_None);
572 return Py_None;
573}
574
575static char xmlparse_GetBase__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000576"GetBase() -> url
577Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000578
579static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000580xmlparse_GetBase(xmlparseobject *self, PyObject *args)
581{
582 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000583 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000584
Fred Drake0582df92000-07-12 04:49:00 +0000585 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000586}
587
588static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000589 {"Parse", (PyCFunction)xmlparse_Parse,
590 METH_VARARGS, xmlparse_Parse__doc__},
591 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
592 METH_VARARGS, xmlparse_ParseFile__doc__},
593 {"SetBase", (PyCFunction)xmlparse_SetBase,
594 METH_VARARGS, xmlparse_SetBase__doc__},
595 {"GetBase", (PyCFunction)xmlparse_GetBase,
596 METH_VARARGS, xmlparse_GetBase__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000597 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000598};
599
600/* ---------- */
601
602
603static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000604newxmlparseobject(char *encoding, char *namespace_separator)
605{
606 int i;
607 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000608
609#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000610 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
611 if (self == NULL)
612 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000613
Fred Drake0582df92000-07-12 04:49:00 +0000614 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000615#else
Fred Drake0582df92000-07-12 04:49:00 +0000616 /* Code for versions 1.6 and later */
617 self = PyObject_New(xmlparseobject, &Xmlparsetype);
618 if (self == NULL)
619 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000620
Fred Drake0582df92000-07-12 04:49:00 +0000621 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000622#endif
Fred Drake0582df92000-07-12 04:49:00 +0000623 if (namespace_separator) {
624 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
625 }
626 else{
627 self->itself = XML_ParserCreate(encoding);
628 }
629 if (self->itself == NULL) {
630 PyErr_SetString(PyExc_RuntimeError,
631 "XML_ParserCreate failed");
632 Py_DECREF(self);
633 return NULL;
634 }
635 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000636
Fred Drake0582df92000-07-12 04:49:00 +0000637 for(i = 0; handler_info[i].name != NULL; i++)
638 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000639
Fred Drake0582df92000-07-12 04:49:00 +0000640 self->handlers = malloc(sizeof(PyObject *)*i);
641 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000642
Fred Drake0582df92000-07-12 04:49:00 +0000643 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000644}
645
646
647static void
Fred Drake0582df92000-07-12 04:49:00 +0000648xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649{
Fred Drake0582df92000-07-12 04:49:00 +0000650 int i;
651 if (self->itself)
652 XML_ParserFree(self->itself);
653 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000654
Fred Drake0582df92000-07-12 04:49:00 +0000655 for (i=0; handler_info[i].name != NULL; i++) {
656 Py_XDECREF(self->handlers[i]);
657 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000658#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000659 /* Code for versions before 1.6 */
660 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000661#else
Fred Drake0582df92000-07-12 04:49:00 +0000662 /* Code for versions 1.6 and later */
663 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000664#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000665}
666
Fred Drake0582df92000-07-12 04:49:00 +0000667static int
668handlername2int(const char *name)
669{
670 int i;
671 for (i=0; handler_info[i].name != NULL; i++) {
672 if (strcmp(name, handler_info[i].name) == 0) {
673 return i;
674 }
675 }
676 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000677}
678
679static PyObject *
680xmlparse_getattr(xmlparseobject *self, char *name)
681{
Fred Drake0582df92000-07-12 04:49:00 +0000682 int handlernum;
683 if (strcmp(name, "ErrorCode") == 0)
684 return Py_BuildValue("l",
685 (long)XML_GetErrorCode(self->itself));
686 if (strcmp(name, "ErrorLineNumber") == 0)
687 return Py_BuildValue("l",
688 (long)XML_GetErrorLineNumber(self->itself));
689 if (strcmp(name, "ErrorColumnNumber") == 0)
690 return Py_BuildValue("l",
691 (long)XML_GetErrorColumnNumber(self->itself));
692 if (strcmp(name, "ErrorByteIndex") == 0)
693 return Py_BuildValue("l",
694 XML_GetErrorByteIndex(self->itself));
695 if (strcmp(name, "returns_unicode") == 0)
696 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000697
Fred Drake0582df92000-07-12 04:49:00 +0000698 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000699
Fred Drake0582df92000-07-12 04:49:00 +0000700 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
701 Py_INCREF(self->handlers[handlernum]);
702 return self->handlers[handlernum];
703 }
704 if (strcmp(name, "__members__") == 0) {
705 int i;
706 PyObject *rc = PyList_New(0);
707 for(i = 0; handler_info[i].name!=NULL; i++) {
708 PyList_Append(rc,
709 PyString_FromString(handler_info[i].name));
710 }
711 PyList_Append(rc, PyString_FromString("ErrorCode"));
712 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
713 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
714 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000715
Fred Drake0582df92000-07-12 04:49:00 +0000716 return rc;
717 }
718 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000719}
720
Fred Drake0582df92000-07-12 04:49:00 +0000721static int sethandler(xmlparseobject *self, const char *name, PyObject* v)
722{
723 int handlernum = handlername2int(name);
724 if (handlernum != -1) {
725 Py_INCREF(v);
726 Py_XDECREF(self->handlers[handlernum]);
727 self->handlers[handlernum] = v;
728 handler_info[handlernum].setter(self->itself,
729 handler_info[handlernum].handler);
730 return 1;
731 }
732 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000733}
734
735static int
736xmlparse_setattr( xmlparseobject *self, char *name, PyObject *v)
737{
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000738 /* Set attribute 'name' to value 'v'. v==NULL means delete */
739 if (v==NULL) {
740 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
741 return -1;
742 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000743
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000744 if (strcmp(name, "returns_unicode") == 0) {
745 PyObject *intobj = PyNumber_Int(v);
746 if (intobj == NULL) return -1;
747 if (PyInt_AsLong(intobj)) {
748#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
749 PyErr_SetString(PyExc_ValueError,
750 "Cannot return Unicode strings in Python 1.5");
751 return -1;
752#else
753 self->returns_unicode = 1;
754#endif
755 }
756 else self->returns_unicode = 0;
757 Py_DECREF(intobj);
758 return 0;
759 }
760 if( sethandler( self, name, v ) ){
761 return 0;
762 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000763
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000764 PyErr_SetString( PyExc_AttributeError, name );
765 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000766}
767
768static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000769"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000770
771static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000772 PyObject_HEAD_INIT(NULL)
773 0, /*ob_size*/
774 "xmlparser", /*tp_name*/
775 sizeof(xmlparseobject), /*tp_basicsize*/
776 0, /*tp_itemsize*/
777 /* methods */
778 (destructor)xmlparse_dealloc, /*tp_dealloc*/
779 (printfunc)0, /*tp_print*/
780 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
781 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
782 (cmpfunc)0, /*tp_compare*/
783 (reprfunc)0, /*tp_repr*/
784 0, /*tp_as_number*/
785 0, /*tp_as_sequence*/
786 0, /*tp_as_mapping*/
787 (hashfunc)0, /*tp_hash*/
788 (ternaryfunc)0, /*tp_call*/
789 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000790
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000791 /* Space for future expansion */
792 0L,0L,0L,0L,
793 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000794};
795
796/* End of code for xmlparser objects */
797/* -------------------------------------------------------- */
798
799
800static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000801"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
802Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000803
804static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000805pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
806{
807 char *encoding = NULL;
808 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000809 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000810
Fred Drake0582df92000-07-12 04:49:00 +0000811 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000812 &encoding, &namespace_separator))
813 return NULL;
814 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000815}
816
817static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000818"ErrorString(errno) -> string\n\
819Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000820
821static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000822pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000823{
Fred Drake0582df92000-07-12 04:49:00 +0000824 long code = 0;
825
826 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
827 return NULL;
828 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000829}
830
831/* List of methods defined in the module */
832
833static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000834 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
835 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
836 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
837 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000838
Fred Drake0582df92000-07-12 04:49:00 +0000839 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000840};
841
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000842/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000843
844static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000845"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000847/* Initialization function for the module */
848
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000849void
Fred Drake0582df92000-07-12 04:49:00 +0000850initpyexpat(void)
851{
852 PyObject *m, *d;
853 char *rev = "$Revision$";
854 PyObject *errors_module, *errors_dict;
855 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000856
Fred Drake0582df92000-07-12 04:49:00 +0000857 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000858
Fred Drake0582df92000-07-12 04:49:00 +0000859 /* Create the module and add the functions */
860 m = Py_InitModule4("pyexpat", pyexpat_methods,
861 pyexpat_module_documentation,
862 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000863
Fred Drake0582df92000-07-12 04:49:00 +0000864 /* Add some symbolic constants to the module */
865 d = PyModule_GetDict(m);
866 ErrorObject = PyString_FromString("pyexpat.error");
867 PyDict_SetItemString(d, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000868
Fred Drake0582df92000-07-12 04:49:00 +0000869 PyDict_SetItemString(d, "__version__",
870 PyString_FromStringAndSize(rev+11,
871 strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000872
Fred Drake0582df92000-07-12 04:49:00 +0000873 sys_modules = PySys_GetObject("modules");
874 errors_module = PyModule_New("pyexpat.errors");
875 PyDict_SetItemString(d, "errors", errors_module);
876 PyDict_SetItemString(sys_modules, "pyexpat.errors", errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000877
Fred Drake0582df92000-07-12 04:49:00 +0000878 /* XXX When Expat supports some way of figuring out how it was
879 compiled, this should check and set native_encoding
880 appropriately.
881 */
882 PyDict_SetItemString(d, "native_encoding",
883 PyString_FromString("UTF-8"));
884 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000885
886#define MYCONST(name) \
Fred Drake0582df92000-07-12 04:49:00 +0000887 PyDict_SetItemString(errors_dict, #name, \
888 PyString_FromString(XML_ErrorString(name)))
Fred Drake7bd9f412000-07-04 23:51:31 +0000889
Fred Drake0582df92000-07-12 04:49:00 +0000890 MYCONST(XML_ERROR_NO_MEMORY);
891 MYCONST(XML_ERROR_SYNTAX);
892 MYCONST(XML_ERROR_NO_ELEMENTS);
893 MYCONST(XML_ERROR_INVALID_TOKEN);
894 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
895 MYCONST(XML_ERROR_PARTIAL_CHAR);
896 MYCONST(XML_ERROR_TAG_MISMATCH);
897 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
898 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
899 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
900 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
901 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
902 MYCONST(XML_ERROR_ASYNC_ENTITY);
903 MYCONST(XML_ERROR_BAD_CHAR_REF);
904 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
905 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
906 MYCONST(XML_ERROR_MISPLACED_XML_PI);
907 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
908 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Fred Drake7bd9f412000-07-04 23:51:31 +0000909
Fred Drake0582df92000-07-12 04:49:00 +0000910 /* Check for errors */
911 if (PyErr_Occurred())
912 Py_FatalError("can't initialize module pyexpat");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000913}
914
Fred Drake0582df92000-07-12 04:49:00 +0000915void clear_handlers(xmlparseobject *self)
916{
917 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000918
Fred Drake0582df92000-07-12 04:49:00 +0000919 for (; handler_info[i].name!=NULL; i++) {
920 self->handlers[i]=NULL;
921 handler_info[i].setter( self->itself, NULL );
922 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000923}
924
925typedef void (*pairsetter)( XML_Parser, void *handler1, void *handler2 );
926
Fred Drake0582df92000-07-12 04:49:00 +0000927void pyxml_UpdatePairedHandlers(xmlparseobject *self,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000928 int startHandler,
929 int endHandler,
Fred Drake0582df92000-07-12 04:49:00 +0000930 pairsetter setter)
931{
932 void *start_handler=NULL;
933 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000934
Fred Drake0582df92000-07-12 04:49:00 +0000935 if (self->handlers[startHandler]
936 && self->handlers[endHandler]!=Py_None) {
937 start_handler=handler_info[startHandler].handler;
938 }
939 if (self->handlers[EndElement]
940 && self->handlers[EndElement] !=Py_None) {
941 end_handler=handler_info[endHandler].handler;
942 }
943 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000944}
945
Fred Drake0582df92000-07-12 04:49:00 +0000946void pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
947{
948 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
949 StartElement, EndElement,
950 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000951}
952
Fred Drake0582df92000-07-12 04:49:00 +0000953void pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
954{
955 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
956 StartElement, EndElement,
957 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000958}
959
Fred Drake0582df92000-07-12 04:49:00 +0000960void pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
961{
962 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
963 StartNamespaceDecl, EndNamespaceDecl,
964 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000965}
966
Fred Drake0582df92000-07-12 04:49:00 +0000967void pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
968{
969 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
970 StartNamespaceDecl, EndNamespaceDecl,
971 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000972}
973
Fred Drake0582df92000-07-12 04:49:00 +0000974void pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
975{
976 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
977 StartCdataSection, EndCdataSection,
978 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000979}
980
Fred Drake0582df92000-07-12 04:49:00 +0000981void pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
982{
983 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
984 StartCdataSection, EndCdataSection,
985 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000986}
987
Fred Drake0582df92000-07-12 04:49:00 +0000988statichere struct HandlerInfo handler_info[] = {
989 {"StartElementHandler",
990 pyxml_SetStartElementHandler,
991 (xmlhandler)my_StartElementHandler},
992 {"EndElementHandler",
993 pyxml_SetEndElementHandler,
994 (xmlhandler)my_EndElementHandler},
995 {"ProcessingInstructionHandler",
996 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
997 (xmlhandler)my_ProcessingInstructionHandler},
998 {"CharacterDataHandler",
999 (xmlhandlersetter)XML_SetCharacterDataHandler,
1000 (xmlhandler)my_CharacterDataHandler},
1001 {"UnparsedEntityDeclHandler",
1002 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1003 (xmlhandler)my_UnparsedEntityDeclHandler },
1004 {"NotationDeclHandler",
1005 (xmlhandlersetter)XML_SetNotationDeclHandler,
1006 (xmlhandler)my_NotationDeclHandler },
1007 {"StartNamespaceDeclHandler",
1008 pyxml_SetStartNamespaceDeclHandler,
1009 (xmlhandler)my_StartNamespaceDeclHandler },
1010 {"EndNamespaceDeclHandler",
1011 pyxml_SetEndNamespaceDeclHandler,
1012 (xmlhandler)my_EndNamespaceDeclHandler },
1013 {"CommentHandler",
1014 (xmlhandlersetter)XML_SetCommentHandler,
1015 (xmlhandler)my_CommentHandler},
1016 {"StartCdataSectionHandler",
1017 pyxml_SetStartCdataSection,
1018 (xmlhandler)my_StartCdataSectionHandler},
1019 {"EndCdataSectionHandler",
1020 pyxml_SetEndCdataSection,
1021 (xmlhandler)my_EndCdataSectionHandler},
1022 {"DefaultHandler",
1023 (xmlhandlersetter)XML_SetDefaultHandler,
1024 (xmlhandler)my_DefaultHandler},
1025 {"DefaultHandlerExpand",
1026 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1027 (xmlhandler)my_DefaultHandlerExpandHandler},
1028 {"NotStandaloneHandler",
1029 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1030 (xmlhandler)my_NotStandaloneHandler},
1031 {"ExternalEntityRefHandler",
1032 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1033 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001034
Fred Drake0582df92000-07-12 04:49:00 +00001035 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001036};