blob: 95a098098dcecc34bdea7e969ce47554ac5235f1 [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{
Fred Drakeca1f4262000-09-21 20:10:23 +000096 PyObject *attrs_obj;
Fred Drake0582df92000-07-12 04:49:00 +000097 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);
Fred Drakeca1f4262000-09-21 20:10:23 +0000124 Py_DECREF(attr_str);
125 Py_DECREF(value_str);
Fred Drake0582df92000-07-12 04:49:00 +0000126 attrs_obj = NULL;
127 goto finally;
128 }
129 Py_DECREF(attr_str);
130 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000131 }
Fred Drake0582df92000-07-12 04:49:00 +0000132 else
133 attrs_k = attrs_p;
134 }
135 finally:
136 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000137}
138
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000139/* Convert a string of XML_Chars into a Unicode string.
140 Returns None if str is a null pointer. */
141
Fred Drake0582df92000-07-12 04:49:00 +0000142static PyObject *
143conv_string_to_unicode(XML_Char *str)
144{
145 /* XXX currently this code assumes that XML_Char is 8-bit,
146 and hence in UTF-8. */
147 /* UTF-8 from Expat, Unicode desired */
148 if (str == NULL) {
149 Py_INCREF(Py_None);
150 return Py_None;
151 }
152 return PyUnicode_DecodeUTF8((const char *)str,
153 strlen((const char *)str),
154 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000155}
156
Fred Drake0582df92000-07-12 04:49:00 +0000157static PyObject *
158conv_string_len_to_unicode(const XML_Char *str, int len)
159{
160 /* XXX currently this code assumes that XML_Char is 8-bit,
161 and hence in UTF-8. */
162 /* UTF-8 from Expat, Unicode desired */
163 if (str == NULL) {
164 Py_INCREF(Py_None);
165 return Py_None;
166 }
Fred Drake6f987622000-08-25 18:03:30 +0000167 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000168}
169#endif
170
171/* Convert a string of XML_Chars into an 8-bit Python string.
172 Returns None if str is a null pointer. */
173
Fred Drake6f987622000-08-25 18:03:30 +0000174static PyObject *
175conv_string_to_utf8(XML_Char *str)
176{
177 /* XXX currently this code assumes that XML_Char is 8-bit,
178 and hence in UTF-8. */
179 /* UTF-8 from Expat, UTF-8 desired */
180 if (str == NULL) {
181 Py_INCREF(Py_None);
182 return Py_None;
183 }
184 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000185}
186
Fred Drake6f987622000-08-25 18:03:30 +0000187static PyObject *
188conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000189{
Fred Drake6f987622000-08-25 18:03:30 +0000190 /* XXX currently this code assumes that XML_Char is 8-bit,
191 and hence in UTF-8. */
192 /* UTF-8 from Expat, UTF-8 desired */
193 if (str == NULL) {
194 Py_INCREF(Py_None);
195 return Py_None;
196 }
197 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000198}
199
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000200/* Callback routines */
201
Fred Drake6f987622000-08-25 18:03:30 +0000202static void clear_handlers(xmlparseobject *self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000203
Fred Drake6f987622000-08-25 18:03:30 +0000204static void
205flag_error(xmlparseobject *self)
206{
207 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000208}
209
Fred Drake6f987622000-08-25 18:03:30 +0000210#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000211 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000212\
213static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000214 xmlparseobject *self = GETUSERDATA ; \
215 PyObject *args=NULL; \
216 PyObject *rv=NULL; \
217 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000218\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000219 if (self->handlers[NAME] \
220 && self->handlers[NAME] != Py_None) { \
221 args = Py_BuildValue PARAM_FORMAT ;\
222 if (!args) return RETURN; \
223 rv = PyEval_CallObject(self->handlers[NAME], args); \
224 Py_DECREF(args); \
225 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000226 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000227 return RETURN; \
228 } \
229 CONVERSION \
230 Py_DECREF(rv); \
231 } \
232 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000233}
234
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000235#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
236#define STRING_CONV_FUNC conv_string_to_utf8
237#else
238/* Python 1.6 and later versions */
239#define STRING_CONV_FUNC (self->returns_unicode \
240 ? conv_string_to_unicode : conv_string_to_utf8)
241#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000242
Fred Drake6f987622000-08-25 18:03:30 +0000243#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
244 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
245 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000246
Fred Drake6f987622000-08-25 18:03:30 +0000247#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
248 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
249 rc = PyInt_AsLong(rv);, rc, \
250 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000251
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000252#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000253VOID_HANDLER(StartElement,
254 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000255 ("(O&O&)", STRING_CONV_FUNC, name,
256 conv_atts_using_string, atts ) )
257#else
258/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000259VOID_HANDLER(StartElement,
260 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000261 ("(O&O&)", STRING_CONV_FUNC, name,
262 (self->returns_unicode
263 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000264 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000265#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000266
Fred Drake6f987622000-08-25 18:03:30 +0000267VOID_HANDLER(EndElement,
268 (void *userData, const XML_Char *name),
269 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000270
Fred Drake6f987622000-08-25 18:03:30 +0000271VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000272 (void *userData,
273 const XML_Char *target,
274 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000275 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000276
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000277#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000278VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000279 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000280 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000281#else
Fred Drake6f987622000-08-25 18:03:30 +0000282VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000283 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000284 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000285 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000286 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000287#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000288
Fred Drake6f987622000-08-25 18:03:30 +0000289VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000290 (void *userData,
291 const XML_Char *entityName,
292 const XML_Char *base,
293 const XML_Char *systemId,
294 const XML_Char *publicId,
295 const XML_Char *notationName),
296 ("(O&O&O&O&O&)",
297 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
298 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
299 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000300
Fred Drake6f987622000-08-25 18:03:30 +0000301VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000302 (void *userData,
303 const XML_Char *notationName,
304 const XML_Char *base,
305 const XML_Char *systemId,
306 const XML_Char *publicId),
307 ("(O&O&O&O&)",
308 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
309 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000310
Fred Drake6f987622000-08-25 18:03:30 +0000311VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000312 (void *userData,
313 const XML_Char *prefix,
314 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000315 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000316
Fred Drake6f987622000-08-25 18:03:30 +0000317VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000318 (void *userData,
319 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000320 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000321
Fred Drake6f987622000-08-25 18:03:30 +0000322VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000323 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000324 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000325
Fred Drake6f987622000-08-25 18:03:30 +0000326VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000327 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000328 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000329
Fred Drake6f987622000-08-25 18:03:30 +0000330VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000331 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000332 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000333
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000334#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000335VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000336 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000337 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000338
Fred Drake6f987622000-08-25 18:03:30 +0000339VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000340 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000341 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000342#else
Fred Drake6f987622000-08-25 18:03:30 +0000343VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000344 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000345 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000346 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000347 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348
Fred Drake6f987622000-08-25 18:03:30 +0000349VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000350 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000351 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000352 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000353 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000354#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000355
Fred Drake6f987622000-08-25 18:03:30 +0000356INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000357 (void *userData),
358 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000359
Fred Drake6f987622000-08-25 18:03:30 +0000360RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000361 (XML_Parser parser,
362 const XML_Char *context,
363 const XML_Char *base,
364 const XML_Char *systemId,
365 const XML_Char *publicId),
366 int rc=0;,
367 ("(O&O&O&O&)",
368 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000369 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
370 rc = PyInt_AsLong(rv);, rc,
371 XML_GetUserData(parser))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000372
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000373
374
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000375/* ---------------------------------------------------------------- */
376
377static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000378"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000379Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000380
381static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000382xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000383{
Fred Drake0582df92000-07-12 04:49:00 +0000384 char *s;
385 int slen;
386 int isFinal = 0;
387 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000388
Fred Drake0582df92000-07-12 04:49:00 +0000389 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
390 return NULL;
391 rv = XML_Parse(self->itself, s, slen, isFinal);
392 if (PyErr_Occurred()) {
393 return NULL;
394 }
395 else if (rv == 0) {
396 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
397 XML_ErrorString(XML_GetErrorCode(self->itself)),
398 XML_GetErrorLineNumber(self->itself),
399 XML_GetErrorColumnNumber(self->itself));
400 return NULL;
401 }
402 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000403}
404
Fred Drakeca1f4262000-09-21 20:10:23 +0000405/* File reading copied from cPickle */
406
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000407#define BUF_SIZE 2048
408
Fred Drake0582df92000-07-12 04:49:00 +0000409static int
410readinst(char *buf, int buf_size, PyObject *meth)
411{
412 PyObject *arg = NULL;
413 PyObject *bytes = NULL;
414 PyObject *str = NULL;
415 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000416
Fred Drakeca1f4262000-09-21 20:10:23 +0000417 if ((bytes = PyInt_FromLong(buf_size)) == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000418 if (!PyErr_Occurred())
419 PyErr_SetNone(PyExc_EOFError);
420 goto finally;
421 }
Fred Drakeca1f4262000-09-21 20:10:23 +0000422 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000423 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424
Tim Peters954eef72000-09-22 06:01:11 +0000425 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000426
Fred Drakeca1f4262000-09-21 20:10:23 +0000427 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000428 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000429
Fred Drake0582df92000-07-12 04:49:00 +0000430 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000431 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000432 PyErr_Format(PyExc_TypeError,
433 "read() did not return a string object (type=%.400s)",
434 str->ob_type->tp_name);
435 goto finally;
436 }
437 len = PyString_GET_SIZE(str);
438 if (len > buf_size) {
439 PyErr_Format(PyExc_ValueError,
440 "read() returned too much data: "
441 "%i bytes requested, %i returned",
442 buf_size, len);
443 Py_DECREF(str);
444 goto finally;
445 }
446 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000447finally:
Fred Drake0582df92000-07-12 04:49:00 +0000448 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000449 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000450 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000451}
452
453static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000454"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000455Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000456
457static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000458xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000459{
Fred Drake0582df92000-07-12 04:49:00 +0000460 int rv = 1;
461 PyObject *f;
462 FILE *fp;
463 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000464
Fred Drake0582df92000-07-12 04:49:00 +0000465 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
466 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000467
Fred Drake0582df92000-07-12 04:49:00 +0000468 if (PyFile_Check(f)) {
469 fp = PyFile_AsFile(f);
470 }
471 else{
472 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000473 readmethod = PyObject_GetAttrString(f, "read");
474 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000475 PyErr_Clear();
476 PyErr_SetString(PyExc_TypeError,
477 "argument must have 'read' attribute");
478 return 0;
479 }
480 }
481 for (;;) {
482 int bytes_read;
483 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
484 if (buf == NULL)
485 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000486
Fred Drake0582df92000-07-12 04:49:00 +0000487 if (fp) {
488 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
489 if (bytes_read < 0) {
490 PyErr_SetFromErrno(PyExc_IOError);
491 return NULL;
492 }
493 }
494 else {
495 bytes_read = readinst(buf, BUF_SIZE, readmethod);
496 if (bytes_read < 0)
497 return NULL;
498 }
499 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
500 if (PyErr_Occurred())
501 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000502
Fred Drake0582df92000-07-12 04:49:00 +0000503 if (!rv || bytes_read == 0)
504 break;
505 }
506 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000507}
508
509static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000510"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000511Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000512
513static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000514xmlparse_SetBase(xmlparseobject *self, PyObject *args)
515{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000516 char *base;
517
Fred Drake0582df92000-07-12 04:49:00 +0000518 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000519 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000520 if (!XML_SetBase(self->itself, base)) {
521 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000522 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000523 Py_INCREF(Py_None);
524 return Py_None;
525}
526
527static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000528"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000529Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000530
531static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000532xmlparse_GetBase(xmlparseobject *self, PyObject *args)
533{
534 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000535 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000536
Fred Drake0582df92000-07-12 04:49:00 +0000537 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000538}
539
540static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000541 {"Parse", (PyCFunction)xmlparse_Parse,
542 METH_VARARGS, xmlparse_Parse__doc__},
543 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
544 METH_VARARGS, xmlparse_ParseFile__doc__},
545 {"SetBase", (PyCFunction)xmlparse_SetBase,
546 METH_VARARGS, xmlparse_SetBase__doc__},
547 {"GetBase", (PyCFunction)xmlparse_GetBase,
548 METH_VARARGS, xmlparse_GetBase__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000549 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000550};
551
552/* ---------- */
553
554
555static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000556newxmlparseobject(char *encoding, char *namespace_separator)
557{
558 int i;
559 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000560
561#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000562 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
563 if (self == NULL)
564 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000565
Fred Drake0582df92000-07-12 04:49:00 +0000566 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000567#else
Fred Drake0582df92000-07-12 04:49:00 +0000568 /* Code for versions 1.6 and later */
569 self = PyObject_New(xmlparseobject, &Xmlparsetype);
570 if (self == NULL)
571 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000572
Fred Drake0582df92000-07-12 04:49:00 +0000573 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000574#endif
Fred Drake0582df92000-07-12 04:49:00 +0000575 if (namespace_separator) {
576 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
577 }
578 else{
579 self->itself = XML_ParserCreate(encoding);
580 }
581 if (self->itself == NULL) {
582 PyErr_SetString(PyExc_RuntimeError,
583 "XML_ParserCreate failed");
584 Py_DECREF(self);
585 return NULL;
586 }
587 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000588
Fred Drake0582df92000-07-12 04:49:00 +0000589 for(i = 0; handler_info[i].name != NULL; i++)
590 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000591
Fred Drake0582df92000-07-12 04:49:00 +0000592 self->handlers = malloc(sizeof(PyObject *)*i);
593 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000594
Fred Drake0582df92000-07-12 04:49:00 +0000595 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000596}
597
598
599static void
Fred Drake0582df92000-07-12 04:49:00 +0000600xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000601{
Fred Drake0582df92000-07-12 04:49:00 +0000602 int i;
603 if (self->itself)
604 XML_ParserFree(self->itself);
605 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000606
Fred Drake0582df92000-07-12 04:49:00 +0000607 for (i=0; handler_info[i].name != NULL; i++) {
608 Py_XDECREF(self->handlers[i]);
609 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000610#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000611 /* Code for versions before 1.6 */
612 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000613#else
Fred Drake0582df92000-07-12 04:49:00 +0000614 /* Code for versions 1.6 and later */
615 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000616#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000617}
618
Fred Drake0582df92000-07-12 04:49:00 +0000619static int
620handlername2int(const char *name)
621{
622 int i;
623 for (i=0; handler_info[i].name != NULL; i++) {
624 if (strcmp(name, handler_info[i].name) == 0) {
625 return i;
626 }
627 }
628 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000629}
630
631static PyObject *
632xmlparse_getattr(xmlparseobject *self, char *name)
633{
Fred Drake0582df92000-07-12 04:49:00 +0000634 int handlernum;
635 if (strcmp(name, "ErrorCode") == 0)
636 return Py_BuildValue("l",
637 (long)XML_GetErrorCode(self->itself));
638 if (strcmp(name, "ErrorLineNumber") == 0)
639 return Py_BuildValue("l",
640 (long)XML_GetErrorLineNumber(self->itself));
641 if (strcmp(name, "ErrorColumnNumber") == 0)
642 return Py_BuildValue("l",
643 (long)XML_GetErrorColumnNumber(self->itself));
644 if (strcmp(name, "ErrorByteIndex") == 0)
645 return Py_BuildValue("l",
646 XML_GetErrorByteIndex(self->itself));
647 if (strcmp(name, "returns_unicode") == 0)
648 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649
Fred Drake0582df92000-07-12 04:49:00 +0000650 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000651
Fred Drake0582df92000-07-12 04:49:00 +0000652 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
653 Py_INCREF(self->handlers[handlernum]);
654 return self->handlers[handlernum];
655 }
656 if (strcmp(name, "__members__") == 0) {
657 int i;
658 PyObject *rc = PyList_New(0);
659 for(i = 0; handler_info[i].name!=NULL; i++) {
660 PyList_Append(rc,
661 PyString_FromString(handler_info[i].name));
662 }
663 PyList_Append(rc, PyString_FromString("ErrorCode"));
664 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
665 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
666 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000667
Fred Drake0582df92000-07-12 04:49:00 +0000668 return rc;
669 }
670 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000671}
672
Fred Drake6f987622000-08-25 18:03:30 +0000673static int
674sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000675{
676 int handlernum = handlername2int(name);
677 if (handlernum != -1) {
678 Py_INCREF(v);
679 Py_XDECREF(self->handlers[handlernum]);
680 self->handlers[handlernum] = v;
681 handler_info[handlernum].setter(self->itself,
682 handler_info[handlernum].handler);
683 return 1;
684 }
685 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000686}
687
688static int
Fred Drake6f987622000-08-25 18:03:30 +0000689xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000690{
Fred Drake6f987622000-08-25 18:03:30 +0000691 /* Set attribute 'name' to value 'v'. v==NULL means delete */
692 if (v==NULL) {
693 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
694 return -1;
695 }
696 if (strcmp(name, "returns_unicode") == 0) {
697 PyObject *intobj = PyNumber_Int(v);
698 if (intobj == NULL) return -1;
699 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000700#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000701 PyErr_SetString(PyExc_ValueError,
702 "Cannot return Unicode strings in Python 1.5");
703 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000704#else
Fred Drake6f987622000-08-25 18:03:30 +0000705 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000706#endif
Fred Drake6f987622000-08-25 18:03:30 +0000707 }
708 else
709 self->returns_unicode = 0;
710 Py_DECREF(intobj);
711 return 0;
712 }
713 if (sethandler(self, name, v)) {
714 return 0;
715 }
716 PyErr_SetString(PyExc_AttributeError, name);
717 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000718}
719
720static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000721"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000722
723static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000724 PyObject_HEAD_INIT(NULL)
725 0, /*ob_size*/
726 "xmlparser", /*tp_name*/
727 sizeof(xmlparseobject), /*tp_basicsize*/
728 0, /*tp_itemsize*/
729 /* methods */
730 (destructor)xmlparse_dealloc, /*tp_dealloc*/
731 (printfunc)0, /*tp_print*/
732 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
733 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
734 (cmpfunc)0, /*tp_compare*/
735 (reprfunc)0, /*tp_repr*/
736 0, /*tp_as_number*/
737 0, /*tp_as_sequence*/
738 0, /*tp_as_mapping*/
739 (hashfunc)0, /*tp_hash*/
740 (ternaryfunc)0, /*tp_call*/
741 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000742
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000743 /* Space for future expansion */
744 0L,0L,0L,0L,
745 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000746};
747
748/* End of code for xmlparser objects */
749/* -------------------------------------------------------- */
750
751
752static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000753"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
754Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000755
756static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000757pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
758{
759 char *encoding = NULL;
760 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000761 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000762
Fred Drake0582df92000-07-12 04:49:00 +0000763 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000764 &encoding, &namespace_separator))
765 return NULL;
766 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000767}
768
769static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000770"ErrorString(errno) -> string\n\
771Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000772
773static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000774pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000775{
Fred Drake0582df92000-07-12 04:49:00 +0000776 long code = 0;
777
778 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
779 return NULL;
780 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000781}
782
783/* List of methods defined in the module */
784
785static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000786 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
787 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
788 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
789 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000790
Fred Drake0582df92000-07-12 04:49:00 +0000791 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000792};
793
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000794/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000795
796static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000797"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000798
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000799/* Initialization function for the module */
800
Tim Peters6d7c4422000-08-26 07:38:06 +0000801DL_EXPORT(void) initpyexpat(void); /* supply a prototype */
Fred Drake6f987622000-08-25 18:03:30 +0000802
803DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000804initpyexpat(void)
805{
806 PyObject *m, *d;
807 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000808 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000809 PyObject *errors_module, *errors_dict;
810 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000811
Fred Drake6f987622000-08-25 18:03:30 +0000812 if (errmod_name == NULL)
813 return;
814
Fred Drake0582df92000-07-12 04:49:00 +0000815 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000816
Fred Drake0582df92000-07-12 04:49:00 +0000817 /* Create the module and add the functions */
818 m = Py_InitModule4("pyexpat", pyexpat_methods,
819 pyexpat_module_documentation,
820 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000821
Fred Drake0582df92000-07-12 04:49:00 +0000822 /* Add some symbolic constants to the module */
823 d = PyModule_GetDict(m);
Fred Drakec23b5232000-08-24 21:57:43 +0000824 if (ErrorObject == NULL)
825 ErrorObject = PyErr_NewException("pyexpat.error", NULL, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000826 PyDict_SetItemString(d, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000827
Fred Drake0582df92000-07-12 04:49:00 +0000828 PyDict_SetItemString(d, "__version__",
829 PyString_FromStringAndSize(rev+11,
830 strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000831
Fred Drake0582df92000-07-12 04:49:00 +0000832 /* XXX When Expat supports some way of figuring out how it was
833 compiled, this should check and set native_encoding
834 appropriately.
835 */
836 PyDict_SetItemString(d, "native_encoding",
837 PyString_FromString("UTF-8"));
Fred Drakec23b5232000-08-24 21:57:43 +0000838
Fred Drake6f987622000-08-25 18:03:30 +0000839 errors_module = PyDict_GetItem(d, errmod_name);
840 if (errors_module == NULL) {
841 errors_module = PyModule_New("pyexpat.errors");
842 if (errors_module != NULL) {
843 sys_modules = PySys_GetObject("modules");
844 PyDict_SetItemString(d, "errors", errors_module);
845 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000846 }
847 }
Fred Drake6f987622000-08-25 18:03:30 +0000848 Py_DECREF(errmod_name);
849 if (errors_module == NULL)
850 /* Don't code dump later! */
851 return;
852
Fred Drake0582df92000-07-12 04:49:00 +0000853 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000854
855#define MYCONST(name) \
Fred Drake0582df92000-07-12 04:49:00 +0000856 PyDict_SetItemString(errors_dict, #name, \
857 PyString_FromString(XML_ErrorString(name)))
Fred Drake7bd9f412000-07-04 23:51:31 +0000858
Fred Drake0582df92000-07-12 04:49:00 +0000859 MYCONST(XML_ERROR_NO_MEMORY);
860 MYCONST(XML_ERROR_SYNTAX);
861 MYCONST(XML_ERROR_NO_ELEMENTS);
862 MYCONST(XML_ERROR_INVALID_TOKEN);
863 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
864 MYCONST(XML_ERROR_PARTIAL_CHAR);
865 MYCONST(XML_ERROR_TAG_MISMATCH);
866 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
867 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
868 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
869 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
870 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
871 MYCONST(XML_ERROR_ASYNC_ENTITY);
872 MYCONST(XML_ERROR_BAD_CHAR_REF);
873 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
874 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
875 MYCONST(XML_ERROR_MISPLACED_XML_PI);
876 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
877 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000878}
879
Fred Drake6f987622000-08-25 18:03:30 +0000880static void
881clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000882{
883 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000884
Fred Drake0582df92000-07-12 04:49:00 +0000885 for (; handler_info[i].name!=NULL; i++) {
886 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000887 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000888 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000889}
890
Fred Drake6f987622000-08-25 18:03:30 +0000891typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000892
Fred Drake6f987622000-08-25 18:03:30 +0000893static void
894pyxml_UpdatePairedHandlers(xmlparseobject *self,
895 int startHandler,
896 int endHandler,
897 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000898{
899 void *start_handler=NULL;
900 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000901
Fred Drake0582df92000-07-12 04:49:00 +0000902 if (self->handlers[startHandler]
903 && self->handlers[endHandler]!=Py_None) {
904 start_handler=handler_info[startHandler].handler;
905 }
906 if (self->handlers[EndElement]
907 && self->handlers[EndElement] !=Py_None) {
908 end_handler=handler_info[endHandler].handler;
909 }
910 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000911}
912
Fred Drake6f987622000-08-25 18:03:30 +0000913static void
914pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000915{
916 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
917 StartElement, EndElement,
918 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000919}
920
Fred Drake6f987622000-08-25 18:03:30 +0000921static void
922pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000923{
924 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
925 StartElement, EndElement,
926 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000927}
928
Fred Drake6f987622000-08-25 18:03:30 +0000929static void
930pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000931{
932 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
933 StartNamespaceDecl, EndNamespaceDecl,
934 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000935}
936
Fred Drake6f987622000-08-25 18:03:30 +0000937static void
938pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000939{
940 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
941 StartNamespaceDecl, EndNamespaceDecl,
942 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000943}
944
Fred Drake6f987622000-08-25 18:03:30 +0000945static void
946pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000947{
948 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
949 StartCdataSection, EndCdataSection,
950 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000951}
952
Fred Drake6f987622000-08-25 18:03:30 +0000953static void
954pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000955{
956 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
957 StartCdataSection, EndCdataSection,
958 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000959}
960
Fred Drake0582df92000-07-12 04:49:00 +0000961statichere struct HandlerInfo handler_info[] = {
962 {"StartElementHandler",
963 pyxml_SetStartElementHandler,
964 (xmlhandler)my_StartElementHandler},
965 {"EndElementHandler",
966 pyxml_SetEndElementHandler,
967 (xmlhandler)my_EndElementHandler},
968 {"ProcessingInstructionHandler",
969 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
970 (xmlhandler)my_ProcessingInstructionHandler},
971 {"CharacterDataHandler",
972 (xmlhandlersetter)XML_SetCharacterDataHandler,
973 (xmlhandler)my_CharacterDataHandler},
974 {"UnparsedEntityDeclHandler",
975 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
976 (xmlhandler)my_UnparsedEntityDeclHandler },
977 {"NotationDeclHandler",
978 (xmlhandlersetter)XML_SetNotationDeclHandler,
979 (xmlhandler)my_NotationDeclHandler },
980 {"StartNamespaceDeclHandler",
981 pyxml_SetStartNamespaceDeclHandler,
982 (xmlhandler)my_StartNamespaceDeclHandler },
983 {"EndNamespaceDeclHandler",
984 pyxml_SetEndNamespaceDeclHandler,
985 (xmlhandler)my_EndNamespaceDeclHandler },
986 {"CommentHandler",
987 (xmlhandlersetter)XML_SetCommentHandler,
988 (xmlhandler)my_CommentHandler},
989 {"StartCdataSectionHandler",
990 pyxml_SetStartCdataSection,
991 (xmlhandler)my_StartCdataSectionHandler},
992 {"EndCdataSectionHandler",
993 pyxml_SetEndCdataSection,
994 (xmlhandler)my_EndCdataSectionHandler},
995 {"DefaultHandler",
996 (xmlhandlersetter)XML_SetDefaultHandler,
997 (xmlhandler)my_DefaultHandler},
998 {"DefaultHandlerExpand",
999 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1000 (xmlhandler)my_DefaultHandlerExpandHandler},
1001 {"NotStandaloneHandler",
1002 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1003 (xmlhandler)my_NotStandaloneHandler},
1004 {"ExternalEntityRefHandler",
1005 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1006 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001007
Fred Drake0582df92000-07-12 04:49:00 +00001008 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001009};