blob: d270aa211d112988cd970f61d816f4881356a0ae [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001#include "Python.h"
2#include "xmlparse.h"
3
4/*
5** The version number should match the one in _checkversion
6*/
7#define VERSION "1.9"
8
Fred Drake0582df92000-07-12 04:49:00 +00009enum HandlerTypes {
10 StartElement,
11 EndElement,
12 ProcessingInstruction,
13 CharacterData,
14 UnparsedEntityDecl,
15 NotationDecl,
16 StartNamespaceDecl,
17 EndNamespaceDecl,
18 Comment,
19 StartCdataSection,
20 EndCdataSection,
21 Default,
22 DefaultHandlerExpand,
23 NotStandalone,
24 ExternalEntityRef
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000025};
26
27static PyObject *ErrorObject;
28
29/* ----------------------------------------------------- */
30
31/* Declarations for objects of type xmlparser */
32
33typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000034 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000035
Fred Drake0582df92000-07-12 04:49:00 +000036 XML_Parser itself;
37 int returns_unicode; /* True if Unicode strings are returned;
38 if false, UTF-8 strings are returned */
39 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000040} xmlparseobject;
41
42staticforward PyTypeObject Xmlparsetype;
43
Fred Drake6f987622000-08-25 18:03:30 +000044typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000045typedef void* xmlhandler;
46
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000047struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000048 const char *name;
49 xmlhandlersetter setter;
50 xmlhandler handler;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000051};
52
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000053staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000054
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000055/* Convert an array of attributes and their values into a Python dict */
56
Fred Drake0582df92000-07-12 04:49:00 +000057static PyObject *
58conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000059{
Fred Drake0582df92000-07-12 04:49:00 +000060 PyObject *attrs_obj = NULL;
61 XML_Char **attrs_p, **attrs_k = NULL;
62 int attrs_len;
63 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000064
Fred Drake0582df92000-07-12 04:49:00 +000065 if ((attrs_obj = PyDict_New()) == NULL)
66 goto finally;
67 for (attrs_len = 0, attrs_p = atts;
68 *attrs_p;
69 attrs_p++, attrs_len++) {
70 if (attrs_len % 2) {
71 rv = PyString_FromString(*attrs_p);
72 if (!rv) {
73 Py_DECREF(attrs_obj);
74 attrs_obj = NULL;
75 goto finally;
76 }
77 if (PyDict_SetItemString(attrs_obj,
78 (char*)*attrs_k, rv) < 0) {
79 Py_DECREF(attrs_obj);
80 attrs_obj = NULL;
81 goto finally;
82 }
83 Py_DECREF(rv);
84 }
85 else
86 attrs_k = attrs_p;
87 }
88 finally:
89 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000090}
91
92#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +000093static PyObject *
94conv_atts_using_unicode(XML_Char **atts)
95{
96 PyObject *attrs_obj = NULL;
97 XML_Char **attrs_p, **attrs_k = NULL;
98 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000099
Fred Drake0582df92000-07-12 04:49:00 +0000100 if ((attrs_obj = PyDict_New()) == NULL)
101 goto finally;
102 for (attrs_len = 0, attrs_p = atts;
103 *attrs_p;
104 attrs_p++, attrs_len++) {
105 if (attrs_len % 2) {
106 PyObject *attr_str, *value_str;
107 const char *p = (const char *) (*attrs_k);
108 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
109 if (!attr_str) {
110 Py_DECREF(attrs_obj);
111 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000112 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000113 }
114 p = (const char *) *attrs_p;
115 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
116 if (!value_str) {
117 Py_DECREF(attrs_obj);
118 Py_DECREF(attr_str);
119 attrs_obj = NULL;
120 goto finally;
121 }
122 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
123 Py_DECREF(attrs_obj);
124 attrs_obj = NULL;
125 goto finally;
126 }
127 Py_DECREF(attr_str);
128 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000129 }
Fred Drake0582df92000-07-12 04:49:00 +0000130 else
131 attrs_k = attrs_p;
132 }
133 finally:
134 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000135}
136
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000137/* Convert a string of XML_Chars into a Unicode string.
138 Returns None if str is a null pointer. */
139
Fred Drake0582df92000-07-12 04:49:00 +0000140static PyObject *
141conv_string_to_unicode(XML_Char *str)
142{
143 /* XXX currently this code assumes that XML_Char is 8-bit,
144 and hence in UTF-8. */
145 /* UTF-8 from Expat, Unicode desired */
146 if (str == NULL) {
147 Py_INCREF(Py_None);
148 return Py_None;
149 }
150 return PyUnicode_DecodeUTF8((const char *)str,
151 strlen((const char *)str),
152 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000153}
154
Fred Drake0582df92000-07-12 04:49:00 +0000155static PyObject *
156conv_string_len_to_unicode(const XML_Char *str, int len)
157{
158 /* XXX currently this code assumes that XML_Char is 8-bit,
159 and hence in UTF-8. */
160 /* UTF-8 from Expat, Unicode desired */
161 if (str == NULL) {
162 Py_INCREF(Py_None);
163 return Py_None;
164 }
Fred Drake6f987622000-08-25 18:03:30 +0000165 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000166}
167#endif
168
169/* Convert a string of XML_Chars into an 8-bit Python string.
170 Returns None if str is a null pointer. */
171
Fred Drake6f987622000-08-25 18:03:30 +0000172static PyObject *
173conv_string_to_utf8(XML_Char *str)
174{
175 /* XXX currently this code assumes that XML_Char is 8-bit,
176 and hence in UTF-8. */
177 /* UTF-8 from Expat, UTF-8 desired */
178 if (str == NULL) {
179 Py_INCREF(Py_None);
180 return Py_None;
181 }
182 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000183}
184
Fred Drake6f987622000-08-25 18:03:30 +0000185static PyObject *
186conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000187{
Fred Drake6f987622000-08-25 18:03:30 +0000188 /* XXX currently this code assumes that XML_Char is 8-bit,
189 and hence in UTF-8. */
190 /* UTF-8 from Expat, UTF-8 desired */
191 if (str == NULL) {
192 Py_INCREF(Py_None);
193 return Py_None;
194 }
195 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000196}
197
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000198/* Callback routines */
199
Fred Drake6f987622000-08-25 18:03:30 +0000200static void clear_handlers(xmlparseobject *self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000201
Fred Drake6f987622000-08-25 18:03:30 +0000202static void
203flag_error(xmlparseobject *self)
204{
205 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000206}
207
Fred Drake6f987622000-08-25 18:03:30 +0000208#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000209 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000210\
211static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000212 xmlparseobject *self = GETUSERDATA ; \
213 PyObject *args=NULL; \
214 PyObject *rv=NULL; \
215 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000216\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000217 if (self->handlers[NAME] \
218 && self->handlers[NAME] != Py_None) { \
219 args = Py_BuildValue PARAM_FORMAT ;\
220 if (!args) return RETURN; \
221 rv = PyEval_CallObject(self->handlers[NAME], args); \
222 Py_DECREF(args); \
223 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000224 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000225 return RETURN; \
226 } \
227 CONVERSION \
228 Py_DECREF(rv); \
229 } \
230 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000231}
232
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000233#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
234#define STRING_CONV_FUNC conv_string_to_utf8
235#else
236/* Python 1.6 and later versions */
237#define STRING_CONV_FUNC (self->returns_unicode \
238 ? conv_string_to_unicode : conv_string_to_utf8)
239#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000240
Fred Drake6f987622000-08-25 18:03:30 +0000241#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
242 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
243 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000244
Fred Drake6f987622000-08-25 18:03:30 +0000245#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
246 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
247 rc = PyInt_AsLong(rv);, rc, \
248 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000249
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000250#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000251VOID_HANDLER(StartElement,
252 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000253 ("(O&O&)", STRING_CONV_FUNC, name,
254 conv_atts_using_string, atts ) )
255#else
256/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000257VOID_HANDLER(StartElement,
258 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000259 ("(O&O&)", STRING_CONV_FUNC, name,
260 (self->returns_unicode
261 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000262 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000263#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000264
Fred Drake6f987622000-08-25 18:03:30 +0000265VOID_HANDLER(EndElement,
266 (void *userData, const XML_Char *name),
267 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000268
Fred Drake6f987622000-08-25 18:03:30 +0000269VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000270 (void *userData,
271 const XML_Char *target,
272 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000273 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000274
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000275#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000276VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000277 (void *userData, const XML_Char *data, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000278 ("(O)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000279#else
Fred Drake6f987622000-08-25 18:03:30 +0000280VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000281 (void *userData, const XML_Char *data, int len),
282 ("(O)", (self->returns_unicode
283 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000284 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000285#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000286
Fred Drake6f987622000-08-25 18:03:30 +0000287VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000288 (void *userData,
289 const XML_Char *entityName,
290 const XML_Char *base,
291 const XML_Char *systemId,
292 const XML_Char *publicId,
293 const XML_Char *notationName),
294 ("(O&O&O&O&O&)",
295 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
296 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
297 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000298
Fred Drake6f987622000-08-25 18:03:30 +0000299VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000300 (void *userData,
301 const XML_Char *notationName,
302 const XML_Char *base,
303 const XML_Char *systemId,
304 const XML_Char *publicId),
305 ("(O&O&O&O&)",
306 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
307 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000308
Fred Drake6f987622000-08-25 18:03:30 +0000309VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000310 (void *userData,
311 const XML_Char *prefix,
312 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000313 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000314
Fred Drake6f987622000-08-25 18:03:30 +0000315VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000316 (void *userData,
317 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000318 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000319
Fred Drake6f987622000-08-25 18:03:30 +0000320VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000321 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000322 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000323
Fred Drake6f987622000-08-25 18:03:30 +0000324VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000325 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000326 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000327
Fred Drake6f987622000-08-25 18:03:30 +0000328VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000329 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000330 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000331
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000332#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000333VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000334 (void *userData, const XML_Char *s, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000335 ("(O)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000336
Fred Drake6f987622000-08-25 18:03:30 +0000337VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000338 (void *userData, const XML_Char *s, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000339 ("(O)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000340#else
Fred Drake6f987622000-08-25 18:03:30 +0000341VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000342 (void *userData, const XML_Char *s, int len),
343 ("(O)", (self->returns_unicode
344 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000345 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000346
Fred Drake6f987622000-08-25 18:03:30 +0000347VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348 (void *userData, const XML_Char *s, int len),
349 ("(O)", (self->returns_unicode
350 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000351 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000352#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000353
Fred Drake6f987622000-08-25 18:03:30 +0000354INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000355 (void *userData),
356 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000357
Fred Drake6f987622000-08-25 18:03:30 +0000358RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000359 (XML_Parser parser,
360 const XML_Char *context,
361 const XML_Char *base,
362 const XML_Char *systemId,
363 const XML_Char *publicId),
364 int rc=0;,
365 ("(O&O&O&O&)",
366 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000367 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
368 rc = PyInt_AsLong(rv);, rc,
369 XML_GetUserData(parser))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000370
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000371
372
373/* File reading copied from cPickle */
374
375#define UNLESS(E) if (!(E))
376
377/*
378static int
379read_other(xmlparseobject *self, char **s, int n) {
380 PyObject *bytes=NULL, *str=NULL, *arg=NULL;
381 int res = -1;
382
383 UNLESS(bytes = PyInt_FromLong(n)) {
384 if (!PyErr_Occurred())
385 PyErr_SetNone(PyExc_EOFError);
386
387 goto finally;
388 }
389
390 UNLESS(arg)
391 UNLESS(arg = PyTuple_New(1))
392 goto finally;
393
394 Py_INCREF(bytes);
395 if (PyTuple_SetItem(arg, 0, bytes) < 0)
396 goto finally;
397
398 UNLESS(str = PyObject_CallObject(self->read, arg))
399 goto finally;
400
401 *s = PyString_AsString(str);
402
403 res = n;
404
405finally:
406 Py_XDECREF(arg);
407 Py_XDECREF(bytes);
408
409 return res;
410}
411
412*/
413
414
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000415
416/* ---------------------------------------------------------------- */
417
418static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000419"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000420Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000421
422static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000423xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424{
Fred Drake0582df92000-07-12 04:49:00 +0000425 char *s;
426 int slen;
427 int isFinal = 0;
428 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000429
Fred Drake0582df92000-07-12 04:49:00 +0000430 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
431 return NULL;
432 rv = XML_Parse(self->itself, s, slen, isFinal);
433 if (PyErr_Occurred()) {
434 return NULL;
435 }
436 else if (rv == 0) {
437 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
438 XML_ErrorString(XML_GetErrorCode(self->itself)),
439 XML_GetErrorLineNumber(self->itself),
440 XML_GetErrorColumnNumber(self->itself));
441 return NULL;
442 }
443 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000444}
445
446#define BUF_SIZE 2048
447
Fred Drake0582df92000-07-12 04:49:00 +0000448static int
449readinst(char *buf, int buf_size, PyObject *meth)
450{
451 PyObject *arg = NULL;
452 PyObject *bytes = NULL;
453 PyObject *str = NULL;
454 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000455
Fred Drake0582df92000-07-12 04:49:00 +0000456 UNLESS(bytes = PyInt_FromLong(buf_size)) {
457 if (!PyErr_Occurred())
458 PyErr_SetNone(PyExc_EOFError);
459 goto finally;
460 }
461 UNLESS(arg)
462 UNLESS(arg = PyTuple_New(1))
463 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000464
Fred Drake0582df92000-07-12 04:49:00 +0000465 if (PyTuple_SetItem(arg, 0, bytes) < 0)
466 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000467
Fred Drake0582df92000-07-12 04:49:00 +0000468 UNLESS(str = PyObject_CallObject(meth, arg))
469 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000470
Fred Drake0582df92000-07-12 04:49:00 +0000471 /* XXX what to do if it returns a Unicode string? */
Fred Drake6f987622000-08-25 18:03:30 +0000472 UNLESS(PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000473 PyErr_Format(PyExc_TypeError,
474 "read() did not return a string object (type=%.400s)",
475 str->ob_type->tp_name);
476 goto finally;
477 }
478 len = PyString_GET_SIZE(str);
479 if (len > buf_size) {
480 PyErr_Format(PyExc_ValueError,
481 "read() returned too much data: "
482 "%i bytes requested, %i returned",
483 buf_size, len);
484 Py_DECREF(str);
485 goto finally;
486 }
487 memcpy(buf, PyString_AsString(str), len);
488 Py_XDECREF(str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000489finally:
Fred Drake0582df92000-07-12 04:49:00 +0000490 Py_XDECREF(arg);
491 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000492}
493
494static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000495"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000496Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000497
498static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000499xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500{
Fred Drake0582df92000-07-12 04:49:00 +0000501 int rv = 1;
502 PyObject *f;
503 FILE *fp;
504 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505
Fred Drake0582df92000-07-12 04:49:00 +0000506 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
507 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000508
Fred Drake0582df92000-07-12 04:49:00 +0000509 if (PyFile_Check(f)) {
510 fp = PyFile_AsFile(f);
511 }
512 else{
513 fp = NULL;
514 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
515 PyErr_Clear();
516 PyErr_SetString(PyExc_TypeError,
517 "argument must have 'read' attribute");
518 return 0;
519 }
520 }
521 for (;;) {
522 int bytes_read;
523 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
524 if (buf == NULL)
525 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000526
Fred Drake0582df92000-07-12 04:49:00 +0000527 if (fp) {
528 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
529 if (bytes_read < 0) {
530 PyErr_SetFromErrno(PyExc_IOError);
531 return NULL;
532 }
533 }
534 else {
535 bytes_read = readinst(buf, BUF_SIZE, readmethod);
536 if (bytes_read < 0)
537 return NULL;
538 }
539 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
540 if (PyErr_Occurred())
541 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000542
Fred Drake0582df92000-07-12 04:49:00 +0000543 if (!rv || bytes_read == 0)
544 break;
545 }
546 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000547}
548
549static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000550"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000551Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000552
553static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000554xmlparse_SetBase(xmlparseobject *self, PyObject *args)
555{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000556 char *base;
557
Fred Drake0582df92000-07-12 04:49:00 +0000558 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000559 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000560 if (!XML_SetBase(self->itself, base)) {
561 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000562 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000563 Py_INCREF(Py_None);
564 return Py_None;
565}
566
567static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000568"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000569Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000570
571static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000572xmlparse_GetBase(xmlparseobject *self, PyObject *args)
573{
574 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000575 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000576
Fred Drake0582df92000-07-12 04:49:00 +0000577 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000578}
579
580static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000581 {"Parse", (PyCFunction)xmlparse_Parse,
582 METH_VARARGS, xmlparse_Parse__doc__},
583 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
584 METH_VARARGS, xmlparse_ParseFile__doc__},
585 {"SetBase", (PyCFunction)xmlparse_SetBase,
586 METH_VARARGS, xmlparse_SetBase__doc__},
587 {"GetBase", (PyCFunction)xmlparse_GetBase,
588 METH_VARARGS, xmlparse_GetBase__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000589 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000590};
591
592/* ---------- */
593
594
595static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000596newxmlparseobject(char *encoding, char *namespace_separator)
597{
598 int i;
599 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000600
601#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000602 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
603 if (self == NULL)
604 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000605
Fred Drake0582df92000-07-12 04:49:00 +0000606 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000607#else
Fred Drake0582df92000-07-12 04:49:00 +0000608 /* Code for versions 1.6 and later */
609 self = PyObject_New(xmlparseobject, &Xmlparsetype);
610 if (self == NULL)
611 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000612
Fred Drake0582df92000-07-12 04:49:00 +0000613 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000614#endif
Fred Drake0582df92000-07-12 04:49:00 +0000615 if (namespace_separator) {
616 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
617 }
618 else{
619 self->itself = XML_ParserCreate(encoding);
620 }
621 if (self->itself == NULL) {
622 PyErr_SetString(PyExc_RuntimeError,
623 "XML_ParserCreate failed");
624 Py_DECREF(self);
625 return NULL;
626 }
627 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000628
Fred Drake0582df92000-07-12 04:49:00 +0000629 for(i = 0; handler_info[i].name != NULL; i++)
630 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000631
Fred Drake0582df92000-07-12 04:49:00 +0000632 self->handlers = malloc(sizeof(PyObject *)*i);
633 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000634
Fred Drake0582df92000-07-12 04:49:00 +0000635 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000636}
637
638
639static void
Fred Drake0582df92000-07-12 04:49:00 +0000640xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000641{
Fred Drake0582df92000-07-12 04:49:00 +0000642 int i;
643 if (self->itself)
644 XML_ParserFree(self->itself);
645 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000646
Fred Drake0582df92000-07-12 04:49:00 +0000647 for (i=0; handler_info[i].name != NULL; i++) {
648 Py_XDECREF(self->handlers[i]);
649 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000650#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000651 /* Code for versions before 1.6 */
652 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000653#else
Fred Drake0582df92000-07-12 04:49:00 +0000654 /* Code for versions 1.6 and later */
655 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000656#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000657}
658
Fred Drake0582df92000-07-12 04:49:00 +0000659static int
660handlername2int(const char *name)
661{
662 int i;
663 for (i=0; handler_info[i].name != NULL; i++) {
664 if (strcmp(name, handler_info[i].name) == 0) {
665 return i;
666 }
667 }
668 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000669}
670
671static PyObject *
672xmlparse_getattr(xmlparseobject *self, char *name)
673{
Fred Drake0582df92000-07-12 04:49:00 +0000674 int handlernum;
675 if (strcmp(name, "ErrorCode") == 0)
676 return Py_BuildValue("l",
677 (long)XML_GetErrorCode(self->itself));
678 if (strcmp(name, "ErrorLineNumber") == 0)
679 return Py_BuildValue("l",
680 (long)XML_GetErrorLineNumber(self->itself));
681 if (strcmp(name, "ErrorColumnNumber") == 0)
682 return Py_BuildValue("l",
683 (long)XML_GetErrorColumnNumber(self->itself));
684 if (strcmp(name, "ErrorByteIndex") == 0)
685 return Py_BuildValue("l",
686 XML_GetErrorByteIndex(self->itself));
687 if (strcmp(name, "returns_unicode") == 0)
688 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000689
Fred Drake0582df92000-07-12 04:49:00 +0000690 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000691
Fred Drake0582df92000-07-12 04:49:00 +0000692 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
693 Py_INCREF(self->handlers[handlernum]);
694 return self->handlers[handlernum];
695 }
696 if (strcmp(name, "__members__") == 0) {
697 int i;
698 PyObject *rc = PyList_New(0);
699 for(i = 0; handler_info[i].name!=NULL; i++) {
700 PyList_Append(rc,
701 PyString_FromString(handler_info[i].name));
702 }
703 PyList_Append(rc, PyString_FromString("ErrorCode"));
704 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
705 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
706 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000707
Fred Drake0582df92000-07-12 04:49:00 +0000708 return rc;
709 }
710 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000711}
712
Fred Drake6f987622000-08-25 18:03:30 +0000713static int
714sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000715{
716 int handlernum = handlername2int(name);
717 if (handlernum != -1) {
718 Py_INCREF(v);
719 Py_XDECREF(self->handlers[handlernum]);
720 self->handlers[handlernum] = v;
721 handler_info[handlernum].setter(self->itself,
722 handler_info[handlernum].handler);
723 return 1;
724 }
725 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000726}
727
728static int
Fred Drake6f987622000-08-25 18:03:30 +0000729xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000730{
Fred Drake6f987622000-08-25 18:03:30 +0000731 /* Set attribute 'name' to value 'v'. v==NULL means delete */
732 if (v==NULL) {
733 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
734 return -1;
735 }
736 if (strcmp(name, "returns_unicode") == 0) {
737 PyObject *intobj = PyNumber_Int(v);
738 if (intobj == NULL) return -1;
739 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000740#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000741 PyErr_SetString(PyExc_ValueError,
742 "Cannot return Unicode strings in Python 1.5");
743 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000744#else
Fred Drake6f987622000-08-25 18:03:30 +0000745 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000746#endif
Fred Drake6f987622000-08-25 18:03:30 +0000747 }
748 else
749 self->returns_unicode = 0;
750 Py_DECREF(intobj);
751 return 0;
752 }
753 if (sethandler(self, name, v)) {
754 return 0;
755 }
756 PyErr_SetString(PyExc_AttributeError, name);
757 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000758}
759
760static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000761"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000762
763static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000764 PyObject_HEAD_INIT(NULL)
765 0, /*ob_size*/
766 "xmlparser", /*tp_name*/
767 sizeof(xmlparseobject), /*tp_basicsize*/
768 0, /*tp_itemsize*/
769 /* methods */
770 (destructor)xmlparse_dealloc, /*tp_dealloc*/
771 (printfunc)0, /*tp_print*/
772 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
773 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
774 (cmpfunc)0, /*tp_compare*/
775 (reprfunc)0, /*tp_repr*/
776 0, /*tp_as_number*/
777 0, /*tp_as_sequence*/
778 0, /*tp_as_mapping*/
779 (hashfunc)0, /*tp_hash*/
780 (ternaryfunc)0, /*tp_call*/
781 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000782
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000783 /* Space for future expansion */
784 0L,0L,0L,0L,
785 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000786};
787
788/* End of code for xmlparser objects */
789/* -------------------------------------------------------- */
790
791
792static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000793"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
794Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000795
796static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000797pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
798{
799 char *encoding = NULL;
800 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000801 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000802
Fred Drake0582df92000-07-12 04:49:00 +0000803 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000804 &encoding, &namespace_separator))
805 return NULL;
806 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000807}
808
809static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000810"ErrorString(errno) -> string\n\
811Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000812
813static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000814pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000815{
Fred Drake0582df92000-07-12 04:49:00 +0000816 long code = 0;
817
818 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
819 return NULL;
820 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000821}
822
823/* List of methods defined in the module */
824
825static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000826 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
827 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
828 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
829 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000830
Fred Drake0582df92000-07-12 04:49:00 +0000831 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000832};
833
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000834/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000835
836static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000837"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000838
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000839/* Initialization function for the module */
840
Tim Peters6d7c4422000-08-26 07:38:06 +0000841DL_EXPORT(void) initpyexpat(void); /* supply a prototype */
Fred Drake6f987622000-08-25 18:03:30 +0000842
843DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000844initpyexpat(void)
845{
846 PyObject *m, *d;
847 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000848 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000849 PyObject *errors_module, *errors_dict;
850 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000851
Fred Drake6f987622000-08-25 18:03:30 +0000852 if (errmod_name == NULL)
853 return;
854
Fred Drake0582df92000-07-12 04:49:00 +0000855 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000856
Fred Drake0582df92000-07-12 04:49:00 +0000857 /* Create the module and add the functions */
858 m = Py_InitModule4("pyexpat", pyexpat_methods,
859 pyexpat_module_documentation,
860 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000861
Fred Drake0582df92000-07-12 04:49:00 +0000862 /* Add some symbolic constants to the module */
863 d = PyModule_GetDict(m);
Fred Drakec23b5232000-08-24 21:57:43 +0000864 if (ErrorObject == NULL)
865 ErrorObject = PyErr_NewException("pyexpat.error", NULL, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000866 PyDict_SetItemString(d, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000867
Fred Drake0582df92000-07-12 04:49:00 +0000868 PyDict_SetItemString(d, "__version__",
869 PyString_FromStringAndSize(rev+11,
870 strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000871
Fred Drake0582df92000-07-12 04:49:00 +0000872 /* XXX When Expat supports some way of figuring out how it was
873 compiled, this should check and set native_encoding
874 appropriately.
875 */
876 PyDict_SetItemString(d, "native_encoding",
877 PyString_FromString("UTF-8"));
Fred Drakec23b5232000-08-24 21:57:43 +0000878
Fred Drake6f987622000-08-25 18:03:30 +0000879 errors_module = PyDict_GetItem(d, errmod_name);
880 if (errors_module == NULL) {
881 errors_module = PyModule_New("pyexpat.errors");
882 if (errors_module != NULL) {
883 sys_modules = PySys_GetObject("modules");
884 PyDict_SetItemString(d, "errors", errors_module);
885 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000886 }
887 }
Fred Drake6f987622000-08-25 18:03:30 +0000888 Py_DECREF(errmod_name);
889 if (errors_module == NULL)
890 /* Don't code dump later! */
891 return;
892
Fred Drake0582df92000-07-12 04:49:00 +0000893 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000894
895#define MYCONST(name) \
Fred Drake0582df92000-07-12 04:49:00 +0000896 PyDict_SetItemString(errors_dict, #name, \
897 PyString_FromString(XML_ErrorString(name)))
Fred Drake7bd9f412000-07-04 23:51:31 +0000898
Fred Drake0582df92000-07-12 04:49:00 +0000899 MYCONST(XML_ERROR_NO_MEMORY);
900 MYCONST(XML_ERROR_SYNTAX);
901 MYCONST(XML_ERROR_NO_ELEMENTS);
902 MYCONST(XML_ERROR_INVALID_TOKEN);
903 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
904 MYCONST(XML_ERROR_PARTIAL_CHAR);
905 MYCONST(XML_ERROR_TAG_MISMATCH);
906 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
907 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
908 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
909 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
910 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
911 MYCONST(XML_ERROR_ASYNC_ENTITY);
912 MYCONST(XML_ERROR_BAD_CHAR_REF);
913 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
914 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
915 MYCONST(XML_ERROR_MISPLACED_XML_PI);
916 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
917 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000918}
919
Fred Drake6f987622000-08-25 18:03:30 +0000920static void
921clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000922{
923 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000924
Fred Drake0582df92000-07-12 04:49:00 +0000925 for (; handler_info[i].name!=NULL; i++) {
926 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000927 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000928 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000929}
930
Fred Drake6f987622000-08-25 18:03:30 +0000931typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000932
Fred Drake6f987622000-08-25 18:03:30 +0000933static void
934pyxml_UpdatePairedHandlers(xmlparseobject *self,
935 int startHandler,
936 int endHandler,
937 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000938{
939 void *start_handler=NULL;
940 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000941
Fred Drake0582df92000-07-12 04:49:00 +0000942 if (self->handlers[startHandler]
943 && self->handlers[endHandler]!=Py_None) {
944 start_handler=handler_info[startHandler].handler;
945 }
946 if (self->handlers[EndElement]
947 && self->handlers[EndElement] !=Py_None) {
948 end_handler=handler_info[endHandler].handler;
949 }
950 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000951}
952
Fred Drake6f987622000-08-25 18:03:30 +0000953static void
954pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000955{
956 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
957 StartElement, EndElement,
958 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000959}
960
Fred Drake6f987622000-08-25 18:03:30 +0000961static void
962pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000963{
964 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
965 StartElement, EndElement,
966 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000967}
968
Fred Drake6f987622000-08-25 18:03:30 +0000969static void
970pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000971{
972 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
973 StartNamespaceDecl, EndNamespaceDecl,
974 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000975}
976
Fred Drake6f987622000-08-25 18:03:30 +0000977static void
978pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000979{
980 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
981 StartNamespaceDecl, EndNamespaceDecl,
982 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000983}
984
Fred Drake6f987622000-08-25 18:03:30 +0000985static void
986pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000987{
988 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
989 StartCdataSection, EndCdataSection,
990 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000991}
992
Fred Drake6f987622000-08-25 18:03:30 +0000993static void
994pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000995{
996 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
997 StartCdataSection, EndCdataSection,
998 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000999}
1000
Fred Drake0582df92000-07-12 04:49:00 +00001001statichere struct HandlerInfo handler_info[] = {
1002 {"StartElementHandler",
1003 pyxml_SetStartElementHandler,
1004 (xmlhandler)my_StartElementHandler},
1005 {"EndElementHandler",
1006 pyxml_SetEndElementHandler,
1007 (xmlhandler)my_EndElementHandler},
1008 {"ProcessingInstructionHandler",
1009 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1010 (xmlhandler)my_ProcessingInstructionHandler},
1011 {"CharacterDataHandler",
1012 (xmlhandlersetter)XML_SetCharacterDataHandler,
1013 (xmlhandler)my_CharacterDataHandler},
1014 {"UnparsedEntityDeclHandler",
1015 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1016 (xmlhandler)my_UnparsedEntityDeclHandler },
1017 {"NotationDeclHandler",
1018 (xmlhandlersetter)XML_SetNotationDeclHandler,
1019 (xmlhandler)my_NotationDeclHandler },
1020 {"StartNamespaceDeclHandler",
1021 pyxml_SetStartNamespaceDeclHandler,
1022 (xmlhandler)my_StartNamespaceDeclHandler },
1023 {"EndNamespaceDeclHandler",
1024 pyxml_SetEndNamespaceDeclHandler,
1025 (xmlhandler)my_EndNamespaceDeclHandler },
1026 {"CommentHandler",
1027 (xmlhandlersetter)XML_SetCommentHandler,
1028 (xmlhandler)my_CommentHandler},
1029 {"StartCdataSectionHandler",
1030 pyxml_SetStartCdataSection,
1031 (xmlhandler)my_StartCdataSectionHandler},
1032 {"EndCdataSectionHandler",
1033 pyxml_SetEndCdataSection,
1034 (xmlhandler)my_EndCdataSectionHandler},
1035 {"DefaultHandler",
1036 (xmlhandlersetter)XML_SetDefaultHandler,
1037 (xmlhandler)my_DefaultHandler},
1038 {"DefaultHandlerExpand",
1039 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1040 (xmlhandler)my_DefaultHandlerExpandHandler},
1041 {"NotStandaloneHandler",
1042 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1043 (xmlhandler)my_NotStandaloneHandler},
1044 {"ExternalEntityRefHandler",
1045 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1046 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001047
Fred Drake0582df92000-07-12 04:49:00 +00001048 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001049};