blob: ce66e5a1ed5b088655d0e94c3b1a5117f43be54e [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 Drake676940b2000-09-22 15:21:31 +0000417 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000418 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000419
Fred Drakeca1f4262000-09-21 20:10:23 +0000420 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000421 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000422
Tim Peters954eef72000-09-22 06:01:11 +0000423 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424
Fred Drakeca1f4262000-09-21 20:10:23 +0000425 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000426 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000427
Fred Drake0582df92000-07-12 04:49:00 +0000428 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000429 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000430 PyErr_Format(PyExc_TypeError,
431 "read() did not return a string object (type=%.400s)",
432 str->ob_type->tp_name);
433 goto finally;
434 }
435 len = PyString_GET_SIZE(str);
436 if (len > buf_size) {
437 PyErr_Format(PyExc_ValueError,
438 "read() returned too much data: "
439 "%i bytes requested, %i returned",
440 buf_size, len);
441 Py_DECREF(str);
442 goto finally;
443 }
444 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000445finally:
Fred Drake0582df92000-07-12 04:49:00 +0000446 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000447 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000448 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000449}
450
451static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000452"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000453Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000454
455static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000456xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000457{
Fred Drake0582df92000-07-12 04:49:00 +0000458 int rv = 1;
459 PyObject *f;
460 FILE *fp;
461 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000462
Fred Drake0582df92000-07-12 04:49:00 +0000463 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
464 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000465
Fred Drake0582df92000-07-12 04:49:00 +0000466 if (PyFile_Check(f)) {
467 fp = PyFile_AsFile(f);
468 }
469 else{
470 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000471 readmethod = PyObject_GetAttrString(f, "read");
472 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000473 PyErr_Clear();
474 PyErr_SetString(PyExc_TypeError,
475 "argument must have 'read' attribute");
476 return 0;
477 }
478 }
479 for (;;) {
480 int bytes_read;
481 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
482 if (buf == NULL)
483 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000484
Fred Drake0582df92000-07-12 04:49:00 +0000485 if (fp) {
486 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
487 if (bytes_read < 0) {
488 PyErr_SetFromErrno(PyExc_IOError);
489 return NULL;
490 }
491 }
492 else {
493 bytes_read = readinst(buf, BUF_SIZE, readmethod);
494 if (bytes_read < 0)
495 return NULL;
496 }
497 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
498 if (PyErr_Occurred())
499 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500
Fred Drake0582df92000-07-12 04:49:00 +0000501 if (!rv || bytes_read == 0)
502 break;
503 }
504 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505}
506
507static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000508"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000509Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000510
511static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000512xmlparse_SetBase(xmlparseobject *self, PyObject *args)
513{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000514 char *base;
515
Fred Drake0582df92000-07-12 04:49:00 +0000516 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000517 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000518 if (!XML_SetBase(self->itself, base)) {
519 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000520 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000521 Py_INCREF(Py_None);
522 return Py_None;
523}
524
525static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000526"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000527Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000528
529static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000530xmlparse_GetBase(xmlparseobject *self, PyObject *args)
531{
532 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000533 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000534
Fred Drake0582df92000-07-12 04:49:00 +0000535 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000536}
537
538static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000539 {"Parse", (PyCFunction)xmlparse_Parse,
540 METH_VARARGS, xmlparse_Parse__doc__},
541 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
542 METH_VARARGS, xmlparse_ParseFile__doc__},
543 {"SetBase", (PyCFunction)xmlparse_SetBase,
544 METH_VARARGS, xmlparse_SetBase__doc__},
545 {"GetBase", (PyCFunction)xmlparse_GetBase,
546 METH_VARARGS, xmlparse_GetBase__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000547 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000548};
549
550/* ---------- */
551
552
553static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000554newxmlparseobject(char *encoding, char *namespace_separator)
555{
556 int i;
557 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000558
559#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000560 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
561 if (self == NULL)
562 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000563
Fred Drake0582df92000-07-12 04:49:00 +0000564 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000565#else
Fred Drake0582df92000-07-12 04:49:00 +0000566 /* Code for versions 1.6 and later */
567 self = PyObject_New(xmlparseobject, &Xmlparsetype);
568 if (self == NULL)
569 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000570
Fred Drake0582df92000-07-12 04:49:00 +0000571 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000572#endif
Fred Drake0582df92000-07-12 04:49:00 +0000573 if (namespace_separator) {
574 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
575 }
576 else{
577 self->itself = XML_ParserCreate(encoding);
578 }
579 if (self->itself == NULL) {
580 PyErr_SetString(PyExc_RuntimeError,
581 "XML_ParserCreate failed");
582 Py_DECREF(self);
583 return NULL;
584 }
585 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000586
Fred Drake0582df92000-07-12 04:49:00 +0000587 for(i = 0; handler_info[i].name != NULL; i++)
588 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000589
Fred Drake0582df92000-07-12 04:49:00 +0000590 self->handlers = malloc(sizeof(PyObject *)*i);
591 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000592
Fred Drake0582df92000-07-12 04:49:00 +0000593 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000594}
595
596
597static void
Fred Drake0582df92000-07-12 04:49:00 +0000598xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000599{
Fred Drake0582df92000-07-12 04:49:00 +0000600 int i;
601 if (self->itself)
602 XML_ParserFree(self->itself);
603 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000604
Fred Drake0582df92000-07-12 04:49:00 +0000605 for (i=0; handler_info[i].name != NULL; i++) {
606 Py_XDECREF(self->handlers[i]);
607 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000608#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000609 /* Code for versions before 1.6 */
610 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000611#else
Fred Drake0582df92000-07-12 04:49:00 +0000612 /* Code for versions 1.6 and later */
613 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000614#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000615}
616
Fred Drake0582df92000-07-12 04:49:00 +0000617static int
618handlername2int(const char *name)
619{
620 int i;
621 for (i=0; handler_info[i].name != NULL; i++) {
622 if (strcmp(name, handler_info[i].name) == 0) {
623 return i;
624 }
625 }
626 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000627}
628
629static PyObject *
630xmlparse_getattr(xmlparseobject *self, char *name)
631{
Fred Drake0582df92000-07-12 04:49:00 +0000632 int handlernum;
633 if (strcmp(name, "ErrorCode") == 0)
634 return Py_BuildValue("l",
635 (long)XML_GetErrorCode(self->itself));
636 if (strcmp(name, "ErrorLineNumber") == 0)
637 return Py_BuildValue("l",
638 (long)XML_GetErrorLineNumber(self->itself));
639 if (strcmp(name, "ErrorColumnNumber") == 0)
640 return Py_BuildValue("l",
641 (long)XML_GetErrorColumnNumber(self->itself));
642 if (strcmp(name, "ErrorByteIndex") == 0)
643 return Py_BuildValue("l",
644 XML_GetErrorByteIndex(self->itself));
645 if (strcmp(name, "returns_unicode") == 0)
646 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000647
Fred Drake0582df92000-07-12 04:49:00 +0000648 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649
Fred Drake0582df92000-07-12 04:49:00 +0000650 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
651 Py_INCREF(self->handlers[handlernum]);
652 return self->handlers[handlernum];
653 }
654 if (strcmp(name, "__members__") == 0) {
655 int i;
656 PyObject *rc = PyList_New(0);
657 for(i = 0; handler_info[i].name!=NULL; i++) {
658 PyList_Append(rc,
659 PyString_FromString(handler_info[i].name));
660 }
661 PyList_Append(rc, PyString_FromString("ErrorCode"));
662 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
663 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
664 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000665
Fred Drake0582df92000-07-12 04:49:00 +0000666 return rc;
667 }
668 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000669}
670
Fred Drake6f987622000-08-25 18:03:30 +0000671static int
672sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000673{
674 int handlernum = handlername2int(name);
675 if (handlernum != -1) {
676 Py_INCREF(v);
677 Py_XDECREF(self->handlers[handlernum]);
678 self->handlers[handlernum] = v;
679 handler_info[handlernum].setter(self->itself,
680 handler_info[handlernum].handler);
681 return 1;
682 }
683 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000684}
685
686static int
Fred Drake6f987622000-08-25 18:03:30 +0000687xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000688{
Fred Drake6f987622000-08-25 18:03:30 +0000689 /* Set attribute 'name' to value 'v'. v==NULL means delete */
690 if (v==NULL) {
691 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
692 return -1;
693 }
694 if (strcmp(name, "returns_unicode") == 0) {
695 PyObject *intobj = PyNumber_Int(v);
696 if (intobj == NULL) return -1;
697 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000698#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000699 PyErr_SetString(PyExc_ValueError,
700 "Cannot return Unicode strings in Python 1.5");
701 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000702#else
Fred Drake6f987622000-08-25 18:03:30 +0000703 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000704#endif
Fred Drake6f987622000-08-25 18:03:30 +0000705 }
706 else
707 self->returns_unicode = 0;
708 Py_DECREF(intobj);
709 return 0;
710 }
711 if (sethandler(self, name, v)) {
712 return 0;
713 }
714 PyErr_SetString(PyExc_AttributeError, name);
715 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000716}
717
718static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000719"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000720
721static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000722 PyObject_HEAD_INIT(NULL)
723 0, /*ob_size*/
724 "xmlparser", /*tp_name*/
725 sizeof(xmlparseobject), /*tp_basicsize*/
726 0, /*tp_itemsize*/
727 /* methods */
728 (destructor)xmlparse_dealloc, /*tp_dealloc*/
729 (printfunc)0, /*tp_print*/
730 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
731 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
732 (cmpfunc)0, /*tp_compare*/
733 (reprfunc)0, /*tp_repr*/
734 0, /*tp_as_number*/
735 0, /*tp_as_sequence*/
736 0, /*tp_as_mapping*/
737 (hashfunc)0, /*tp_hash*/
738 (ternaryfunc)0, /*tp_call*/
739 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000740
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000741 /* Space for future expansion */
742 0L,0L,0L,0L,
743 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000744};
745
746/* End of code for xmlparser objects */
747/* -------------------------------------------------------- */
748
749
750static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000751"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
752Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000753
754static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000755pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
756{
757 char *encoding = NULL;
758 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000759 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000760
Fred Drake0582df92000-07-12 04:49:00 +0000761 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000762 &encoding, &namespace_separator))
763 return NULL;
764 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000765}
766
767static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000768"ErrorString(errno) -> string\n\
769Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000770
771static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000772pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000773{
Fred Drake0582df92000-07-12 04:49:00 +0000774 long code = 0;
775
776 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
777 return NULL;
778 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000779}
780
781/* List of methods defined in the module */
782
783static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000784 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
785 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
786 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
787 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000788
Fred Drake0582df92000-07-12 04:49:00 +0000789 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000790};
791
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000792/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000793
794static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000795"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000796
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000797/* Initialization function for the module */
798
Tim Peters6d7c4422000-08-26 07:38:06 +0000799DL_EXPORT(void) initpyexpat(void); /* supply a prototype */
Fred Drake6f987622000-08-25 18:03:30 +0000800
801DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000802initpyexpat(void)
803{
804 PyObject *m, *d;
805 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000806 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000807 PyObject *errors_module, *errors_dict;
808 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000809
Fred Drake6f987622000-08-25 18:03:30 +0000810 if (errmod_name == NULL)
811 return;
812
Fred Drake0582df92000-07-12 04:49:00 +0000813 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000814
Fred Drake0582df92000-07-12 04:49:00 +0000815 /* Create the module and add the functions */
816 m = Py_InitModule4("pyexpat", pyexpat_methods,
817 pyexpat_module_documentation,
818 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000819
Fred Drake0582df92000-07-12 04:49:00 +0000820 /* Add some symbolic constants to the module */
821 d = PyModule_GetDict(m);
Fred Drakec23b5232000-08-24 21:57:43 +0000822 if (ErrorObject == NULL)
823 ErrorObject = PyErr_NewException("pyexpat.error", NULL, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000824 PyDict_SetItemString(d, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000825
Fred Drake0582df92000-07-12 04:49:00 +0000826 PyDict_SetItemString(d, "__version__",
827 PyString_FromStringAndSize(rev+11,
828 strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000829
Fred Drake0582df92000-07-12 04:49:00 +0000830 /* XXX When Expat supports some way of figuring out how it was
831 compiled, this should check and set native_encoding
832 appropriately.
833 */
834 PyDict_SetItemString(d, "native_encoding",
835 PyString_FromString("UTF-8"));
Fred Drakec23b5232000-08-24 21:57:43 +0000836
Fred Drake6f987622000-08-25 18:03:30 +0000837 errors_module = PyDict_GetItem(d, errmod_name);
838 if (errors_module == NULL) {
839 errors_module = PyModule_New("pyexpat.errors");
840 if (errors_module != NULL) {
841 sys_modules = PySys_GetObject("modules");
842 PyDict_SetItemString(d, "errors", errors_module);
843 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000844 }
845 }
Fred Drake6f987622000-08-25 18:03:30 +0000846 Py_DECREF(errmod_name);
847 if (errors_module == NULL)
848 /* Don't code dump later! */
849 return;
850
Fred Drake0582df92000-07-12 04:49:00 +0000851 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000852
853#define MYCONST(name) \
Fred Drake0582df92000-07-12 04:49:00 +0000854 PyDict_SetItemString(errors_dict, #name, \
855 PyString_FromString(XML_ErrorString(name)))
Fred Drake7bd9f412000-07-04 23:51:31 +0000856
Fred Drake0582df92000-07-12 04:49:00 +0000857 MYCONST(XML_ERROR_NO_MEMORY);
858 MYCONST(XML_ERROR_SYNTAX);
859 MYCONST(XML_ERROR_NO_ELEMENTS);
860 MYCONST(XML_ERROR_INVALID_TOKEN);
861 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
862 MYCONST(XML_ERROR_PARTIAL_CHAR);
863 MYCONST(XML_ERROR_TAG_MISMATCH);
864 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
865 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
866 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
867 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
868 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
869 MYCONST(XML_ERROR_ASYNC_ENTITY);
870 MYCONST(XML_ERROR_BAD_CHAR_REF);
871 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
872 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
873 MYCONST(XML_ERROR_MISPLACED_XML_PI);
874 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
875 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000876}
877
Fred Drake6f987622000-08-25 18:03:30 +0000878static void
879clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000880{
881 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000882
Fred Drake0582df92000-07-12 04:49:00 +0000883 for (; handler_info[i].name!=NULL; i++) {
884 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000885 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000886 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000887}
888
Fred Drake6f987622000-08-25 18:03:30 +0000889typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000890
Fred Drake6f987622000-08-25 18:03:30 +0000891static void
892pyxml_UpdatePairedHandlers(xmlparseobject *self,
893 int startHandler,
894 int endHandler,
895 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000896{
897 void *start_handler=NULL;
898 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000899
Fred Drake0582df92000-07-12 04:49:00 +0000900 if (self->handlers[startHandler]
901 && self->handlers[endHandler]!=Py_None) {
902 start_handler=handler_info[startHandler].handler;
903 }
904 if (self->handlers[EndElement]
905 && self->handlers[EndElement] !=Py_None) {
906 end_handler=handler_info[endHandler].handler;
907 }
908 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000909}
910
Fred Drake6f987622000-08-25 18:03:30 +0000911static void
912pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000913{
914 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
915 StartElement, EndElement,
916 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000917}
918
Fred Drake6f987622000-08-25 18:03:30 +0000919static void
920pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000921{
922 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
923 StartElement, EndElement,
924 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000925}
926
Fred Drake6f987622000-08-25 18:03:30 +0000927static void
928pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000929{
930 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
931 StartNamespaceDecl, EndNamespaceDecl,
932 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000933}
934
Fred Drake6f987622000-08-25 18:03:30 +0000935static void
936pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000937{
938 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
939 StartNamespaceDecl, EndNamespaceDecl,
940 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000941}
942
Fred Drake6f987622000-08-25 18:03:30 +0000943static void
944pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000945{
946 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
947 StartCdataSection, EndCdataSection,
948 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000949}
950
Fred Drake6f987622000-08-25 18:03:30 +0000951static void
952pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000953{
954 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
955 StartCdataSection, EndCdataSection,
956 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000957}
958
Fred Drake0582df92000-07-12 04:49:00 +0000959statichere struct HandlerInfo handler_info[] = {
960 {"StartElementHandler",
961 pyxml_SetStartElementHandler,
962 (xmlhandler)my_StartElementHandler},
963 {"EndElementHandler",
964 pyxml_SetEndElementHandler,
965 (xmlhandler)my_EndElementHandler},
966 {"ProcessingInstructionHandler",
967 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
968 (xmlhandler)my_ProcessingInstructionHandler},
969 {"CharacterDataHandler",
970 (xmlhandlersetter)XML_SetCharacterDataHandler,
971 (xmlhandler)my_CharacterDataHandler},
972 {"UnparsedEntityDeclHandler",
973 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
974 (xmlhandler)my_UnparsedEntityDeclHandler },
975 {"NotationDeclHandler",
976 (xmlhandlersetter)XML_SetNotationDeclHandler,
977 (xmlhandler)my_NotationDeclHandler },
978 {"StartNamespaceDeclHandler",
979 pyxml_SetStartNamespaceDeclHandler,
980 (xmlhandler)my_StartNamespaceDeclHandler },
981 {"EndNamespaceDeclHandler",
982 pyxml_SetEndNamespaceDeclHandler,
983 (xmlhandler)my_EndNamespaceDeclHandler },
984 {"CommentHandler",
985 (xmlhandlersetter)XML_SetCommentHandler,
986 (xmlhandler)my_CommentHandler},
987 {"StartCdataSectionHandler",
988 pyxml_SetStartCdataSection,
989 (xmlhandler)my_StartCdataSectionHandler},
990 {"EndCdataSectionHandler",
991 pyxml_SetEndCdataSection,
992 (xmlhandler)my_EndCdataSectionHandler},
993 {"DefaultHandler",
994 (xmlhandlersetter)XML_SetDefaultHandler,
995 (xmlhandler)my_DefaultHandler},
996 {"DefaultHandlerExpand",
997 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
998 (xmlhandler)my_DefaultHandlerExpandHandler},
999 {"NotStandaloneHandler",
1000 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1001 (xmlhandler)my_NotStandaloneHandler},
1002 {"ExternalEntityRefHandler",
1003 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1004 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001005
Fred Drake0582df92000-07-12 04:49:00 +00001006 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001007};