blob: 35530cf870a685004a9c49ac3125d97d8d08780c [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001#include "Python.h"
Fred Drakea77254a2000-09-29 19:23:29 +00002#ifdef HAVE_EXPAT_H
3#include "expat.h"
4#else
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00005#include "xmlparse.h"
Fred Drakea77254a2000-09-29 19:23:29 +00006#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00007
Fred Drake0582df92000-07-12 04:49:00 +00008enum HandlerTypes {
9 StartElement,
10 EndElement,
11 ProcessingInstruction,
12 CharacterData,
13 UnparsedEntityDecl,
14 NotationDecl,
15 StartNamespaceDecl,
16 EndNamespaceDecl,
17 Comment,
18 StartCdataSection,
19 EndCdataSection,
20 Default,
21 DefaultHandlerExpand,
22 NotStandalone,
23 ExternalEntityRef
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000024};
25
26static PyObject *ErrorObject;
27
28/* ----------------------------------------------------- */
29
30/* Declarations for objects of type xmlparser */
31
32typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000033 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000034
Fred Drake0582df92000-07-12 04:49:00 +000035 XML_Parser itself;
36 int returns_unicode; /* True if Unicode strings are returned;
37 if false, UTF-8 strings are returned */
38 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000039} xmlparseobject;
40
41staticforward PyTypeObject Xmlparsetype;
42
Fred Drake6f987622000-08-25 18:03:30 +000043typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000044typedef void* xmlhandler;
45
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000046struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000047 const char *name;
48 xmlhandlersetter setter;
49 xmlhandler handler;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000050};
51
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000052staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000053
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000054/* Convert an array of attributes and their values into a Python dict */
55
Fred Drake0582df92000-07-12 04:49:00 +000056static PyObject *
57conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000058{
Fred Drake0582df92000-07-12 04:49:00 +000059 PyObject *attrs_obj = NULL;
60 XML_Char **attrs_p, **attrs_k = NULL;
61 int attrs_len;
62 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000063
Fred Drake0582df92000-07-12 04:49:00 +000064 if ((attrs_obj = PyDict_New()) == NULL)
65 goto finally;
66 for (attrs_len = 0, attrs_p = atts;
67 *attrs_p;
68 attrs_p++, attrs_len++) {
69 if (attrs_len % 2) {
70 rv = PyString_FromString(*attrs_p);
71 if (!rv) {
72 Py_DECREF(attrs_obj);
73 attrs_obj = NULL;
74 goto finally;
75 }
76 if (PyDict_SetItemString(attrs_obj,
77 (char*)*attrs_k, rv) < 0) {
78 Py_DECREF(attrs_obj);
79 attrs_obj = NULL;
80 goto finally;
81 }
82 Py_DECREF(rv);
83 }
84 else
85 attrs_k = attrs_p;
86 }
87 finally:
88 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000089}
90
91#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +000092static PyObject *
93conv_atts_using_unicode(XML_Char **atts)
94{
Fred Drakeca1f4262000-09-21 20:10:23 +000095 PyObject *attrs_obj;
Fred Drake0582df92000-07-12 04:49:00 +000096 XML_Char **attrs_p, **attrs_k = NULL;
97 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000098
Fred Drake0582df92000-07-12 04:49:00 +000099 if ((attrs_obj = PyDict_New()) == NULL)
100 goto finally;
101 for (attrs_len = 0, attrs_p = atts;
102 *attrs_p;
103 attrs_p++, attrs_len++) {
104 if (attrs_len % 2) {
105 PyObject *attr_str, *value_str;
106 const char *p = (const char *) (*attrs_k);
107 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
108 if (!attr_str) {
109 Py_DECREF(attrs_obj);
110 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000111 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000112 }
113 p = (const char *) *attrs_p;
114 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
115 if (!value_str) {
116 Py_DECREF(attrs_obj);
117 Py_DECREF(attr_str);
118 attrs_obj = NULL;
119 goto finally;
120 }
121 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
122 Py_DECREF(attrs_obj);
Fred Drakeca1f4262000-09-21 20:10:23 +0000123 Py_DECREF(attr_str);
124 Py_DECREF(value_str);
Fred Drake0582df92000-07-12 04:49:00 +0000125 attrs_obj = NULL;
126 goto finally;
127 }
128 Py_DECREF(attr_str);
129 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000130 }
Fred Drake0582df92000-07-12 04:49:00 +0000131 else
132 attrs_k = attrs_p;
133 }
134 finally:
135 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000136}
137
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000138/* Convert a string of XML_Chars into a Unicode string.
139 Returns None if str is a null pointer. */
140
Fred Drake0582df92000-07-12 04:49:00 +0000141static PyObject *
142conv_string_to_unicode(XML_Char *str)
143{
144 /* XXX currently this code assumes that XML_Char is 8-bit,
145 and hence in UTF-8. */
146 /* UTF-8 from Expat, Unicode desired */
147 if (str == NULL) {
148 Py_INCREF(Py_None);
149 return Py_None;
150 }
151 return PyUnicode_DecodeUTF8((const char *)str,
152 strlen((const char *)str),
153 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000154}
155
Fred Drake0582df92000-07-12 04:49:00 +0000156static PyObject *
157conv_string_len_to_unicode(const XML_Char *str, int len)
158{
159 /* XXX currently this code assumes that XML_Char is 8-bit,
160 and hence in UTF-8. */
161 /* UTF-8 from Expat, Unicode desired */
162 if (str == NULL) {
163 Py_INCREF(Py_None);
164 return Py_None;
165 }
Fred Drake6f987622000-08-25 18:03:30 +0000166 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000167}
168#endif
169
170/* Convert a string of XML_Chars into an 8-bit Python string.
171 Returns None if str is a null pointer. */
172
Fred Drake6f987622000-08-25 18:03:30 +0000173static PyObject *
174conv_string_to_utf8(XML_Char *str)
175{
176 /* XXX currently this code assumes that XML_Char is 8-bit,
177 and hence in UTF-8. */
178 /* UTF-8 from Expat, UTF-8 desired */
179 if (str == NULL) {
180 Py_INCREF(Py_None);
181 return Py_None;
182 }
183 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000184}
185
Fred Drake6f987622000-08-25 18:03:30 +0000186static PyObject *
187conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000188{
Fred Drake6f987622000-08-25 18:03:30 +0000189 /* XXX currently this code assumes that XML_Char is 8-bit,
190 and hence in UTF-8. */
191 /* UTF-8 from Expat, UTF-8 desired */
192 if (str == NULL) {
193 Py_INCREF(Py_None);
194 return Py_None;
195 }
196 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000197}
198
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000199/* Callback routines */
200
Fred Drake6f987622000-08-25 18:03:30 +0000201static void clear_handlers(xmlparseobject *self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000202
Fred Drake6f987622000-08-25 18:03:30 +0000203static void
204flag_error(xmlparseobject *self)
205{
206 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000207}
208
Fred Drake6f987622000-08-25 18:03:30 +0000209#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000210 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000211\
212static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000213 xmlparseobject *self = GETUSERDATA ; \
214 PyObject *args=NULL; \
215 PyObject *rv=NULL; \
216 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000217\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000218 if (self->handlers[NAME] \
219 && self->handlers[NAME] != Py_None) { \
220 args = Py_BuildValue PARAM_FORMAT ;\
221 if (!args) return RETURN; \
222 rv = PyEval_CallObject(self->handlers[NAME], args); \
223 Py_DECREF(args); \
224 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000225 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000226 return RETURN; \
227 } \
228 CONVERSION \
229 Py_DECREF(rv); \
230 } \
231 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000232}
233
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000234#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
235#define STRING_CONV_FUNC conv_string_to_utf8
236#else
237/* Python 1.6 and later versions */
238#define STRING_CONV_FUNC (self->returns_unicode \
239 ? conv_string_to_unicode : conv_string_to_utf8)
240#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000241
Fred Drake6f987622000-08-25 18:03:30 +0000242#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
243 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
244 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000245
Fred Drake6f987622000-08-25 18:03:30 +0000246#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
247 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
248 rc = PyInt_AsLong(rv);, rc, \
249 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000250
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000251#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000252VOID_HANDLER(StartElement,
253 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000254 ("(O&O&)", STRING_CONV_FUNC, name,
255 conv_atts_using_string, atts ) )
256#else
257/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000258VOID_HANDLER(StartElement,
259 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000260 ("(O&O&)", STRING_CONV_FUNC, name,
261 (self->returns_unicode
262 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000263 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000264#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000265
Fred Drake6f987622000-08-25 18:03:30 +0000266VOID_HANDLER(EndElement,
267 (void *userData, const XML_Char *name),
268 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000269
Fred Drake6f987622000-08-25 18:03:30 +0000270VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000271 (void *userData,
272 const XML_Char *target,
273 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000274 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000275
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000276#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000277VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000278 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000279 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000280#else
Fred Drake6f987622000-08-25 18:03:30 +0000281VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000282 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000283 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000284 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000285 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000286#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000287
Fred Drake6f987622000-08-25 18:03:30 +0000288VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000289 (void *userData,
290 const XML_Char *entityName,
291 const XML_Char *base,
292 const XML_Char *systemId,
293 const XML_Char *publicId,
294 const XML_Char *notationName),
295 ("(O&O&O&O&O&)",
296 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
297 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
298 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000299
Fred Drake6f987622000-08-25 18:03:30 +0000300VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000301 (void *userData,
302 const XML_Char *notationName,
303 const XML_Char *base,
304 const XML_Char *systemId,
305 const XML_Char *publicId),
306 ("(O&O&O&O&)",
307 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
308 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000309
Fred Drake6f987622000-08-25 18:03:30 +0000310VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000311 (void *userData,
312 const XML_Char *prefix,
313 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000314 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000315
Fred Drake6f987622000-08-25 18:03:30 +0000316VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000317 (void *userData,
318 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000319 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000320
Fred Drake6f987622000-08-25 18:03:30 +0000321VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000322 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000323 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000324
Fred Drake6f987622000-08-25 18:03:30 +0000325VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000326 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000327 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000328
Fred Drake6f987622000-08-25 18:03:30 +0000329VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000330 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000331 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000332
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000333#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000334VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000335 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000336 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000337
Fred Drake6f987622000-08-25 18:03:30 +0000338VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000339 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000340 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000341#else
Fred Drake6f987622000-08-25 18:03:30 +0000342VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000343 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000344 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000345 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000346 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000347
Fred Drake6f987622000-08-25 18:03:30 +0000348VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000349 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000350 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000351 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000352 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000353#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000354
Fred Drake6f987622000-08-25 18:03:30 +0000355INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000356 (void *userData),
357 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000358
Fred Drake6f987622000-08-25 18:03:30 +0000359RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000360 (XML_Parser parser,
361 const XML_Char *context,
362 const XML_Char *base,
363 const XML_Char *systemId,
364 const XML_Char *publicId),
365 int rc=0;,
366 ("(O&O&O&O&)",
367 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000368 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
369 rc = PyInt_AsLong(rv);, rc,
370 XML_GetUserData(parser))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000371
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000372
373
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000374/* ---------------------------------------------------------------- */
375
376static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000377"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000378Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000379
380static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000381xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000382{
Fred Drake0582df92000-07-12 04:49:00 +0000383 char *s;
384 int slen;
385 int isFinal = 0;
386 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000387
Fred Drake0582df92000-07-12 04:49:00 +0000388 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
389 return NULL;
390 rv = XML_Parse(self->itself, s, slen, isFinal);
391 if (PyErr_Occurred()) {
392 return NULL;
393 }
394 else if (rv == 0) {
395 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
396 XML_ErrorString(XML_GetErrorCode(self->itself)),
397 XML_GetErrorLineNumber(self->itself),
398 XML_GetErrorColumnNumber(self->itself));
399 return NULL;
400 }
401 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000402}
403
Fred Drakeca1f4262000-09-21 20:10:23 +0000404/* File reading copied from cPickle */
405
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000406#define BUF_SIZE 2048
407
Fred Drake0582df92000-07-12 04:49:00 +0000408static int
409readinst(char *buf, int buf_size, PyObject *meth)
410{
411 PyObject *arg = NULL;
412 PyObject *bytes = NULL;
413 PyObject *str = NULL;
414 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000415
Fred Drake676940b2000-09-22 15:21:31 +0000416 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000417 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000418
Fred Drakeca1f4262000-09-21 20:10:23 +0000419 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000420 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000421
Tim Peters954eef72000-09-22 06:01:11 +0000422 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000423
Fred Drakeca1f4262000-09-21 20:10:23 +0000424 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000425 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000426
Fred Drake0582df92000-07-12 04:49:00 +0000427 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000428 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000429 PyErr_Format(PyExc_TypeError,
430 "read() did not return a string object (type=%.400s)",
431 str->ob_type->tp_name);
432 goto finally;
433 }
434 len = PyString_GET_SIZE(str);
435 if (len > buf_size) {
436 PyErr_Format(PyExc_ValueError,
437 "read() returned too much data: "
438 "%i bytes requested, %i returned",
439 buf_size, len);
440 Py_DECREF(str);
441 goto finally;
442 }
443 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000444finally:
Fred Drake0582df92000-07-12 04:49:00 +0000445 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000446 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000447 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000448}
449
450static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000451"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000452Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000453
454static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000455xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000456{
Fred Drake0582df92000-07-12 04:49:00 +0000457 int rv = 1;
458 PyObject *f;
459 FILE *fp;
460 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000461
Fred Drake0582df92000-07-12 04:49:00 +0000462 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
463 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000464
Fred Drake0582df92000-07-12 04:49:00 +0000465 if (PyFile_Check(f)) {
466 fp = PyFile_AsFile(f);
467 }
468 else{
469 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000470 readmethod = PyObject_GetAttrString(f, "read");
471 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000472 PyErr_Clear();
473 PyErr_SetString(PyExc_TypeError,
474 "argument must have 'read' attribute");
475 return 0;
476 }
477 }
478 for (;;) {
479 int bytes_read;
480 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
481 if (buf == NULL)
482 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000483
Fred Drake0582df92000-07-12 04:49:00 +0000484 if (fp) {
485 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
486 if (bytes_read < 0) {
487 PyErr_SetFromErrno(PyExc_IOError);
488 return NULL;
489 }
490 }
491 else {
492 bytes_read = readinst(buf, BUF_SIZE, readmethod);
493 if (bytes_read < 0)
494 return NULL;
495 }
496 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
497 if (PyErr_Occurred())
498 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000499
Fred Drake0582df92000-07-12 04:49:00 +0000500 if (!rv || bytes_read == 0)
501 break;
502 }
503 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000504}
505
506static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000507"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000508Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000509
510static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000511xmlparse_SetBase(xmlparseobject *self, PyObject *args)
512{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000513 char *base;
514
Fred Drake0582df92000-07-12 04:49:00 +0000515 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000516 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000517 if (!XML_SetBase(self->itself, base)) {
518 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000519 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000520 Py_INCREF(Py_None);
521 return Py_None;
522}
523
524static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000525"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000526Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000527
528static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000529xmlparse_GetBase(xmlparseobject *self, PyObject *args)
530{
531 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000532 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000533
Fred Drake0582df92000-07-12 04:49:00 +0000534 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000535}
536
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000537static char xmlparse_ExternalEntityParserCreate__doc__[] =
538"ExternalEntityParserCreate(context, encoding)\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000539Create a parser for parsing an external entity based on the\n\
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000540information passed to the ExternalEntityRefHandler.";
541
542static PyObject *
543xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
544{
545 char *context;
546 char *encoding = NULL;
547 xmlparseobject *new_parser;
548 int i;
549
550 if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
551 &encoding)) {
552 return NULL;
553 }
554
555#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
556 new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
557 if (new_parser == NULL)
558 return NULL;
559
560 new_parser->returns_unicode = 0;
561#else
562 /* Code for versions 1.6 and later */
563 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
564 if (new_parser == NULL)
565 return NULL;
566
567 new_parser->returns_unicode = 1;
568#endif
569
570 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
571 encoding);
572 if (!new_parser) {
573 Py_DECREF(new_parser);
574 return PyErr_NoMemory();
575 }
576
577 XML_SetUserData(new_parser->itself, (void *)new_parser);
578
579 /* allocate and clear handlers first */
580 for(i = 0; handler_info[i].name != NULL; i++)
581 /* do nothing */;
582
583 new_parser->handlers = malloc(sizeof(PyObject *)*i);
584 clear_handlers(new_parser);
585
586 /* then copy handlers from self */
587 for (i = 0; handler_info[i].name != NULL; i++) {
588 if (self->handlers[i]) {
589 Py_INCREF(self->handlers[i]);
590 new_parser->handlers[i] = self->handlers[i];
591 handler_info[i].setter(new_parser->itself,
592 handler_info[i].handler);
593 }
594 }
595
Fred Drake28adf522000-09-24 22:07:59 +0000596 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000597}
598
599
600
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000601static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000602 {"Parse", (PyCFunction)xmlparse_Parse,
603 METH_VARARGS, xmlparse_Parse__doc__},
604 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
605 METH_VARARGS, xmlparse_ParseFile__doc__},
606 {"SetBase", (PyCFunction)xmlparse_SetBase,
607 METH_VARARGS, xmlparse_SetBase__doc__},
608 {"GetBase", (PyCFunction)xmlparse_GetBase,
609 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000610 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
611 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000612 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000613};
614
615/* ---------- */
616
617
618static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000619newxmlparseobject(char *encoding, char *namespace_separator)
620{
621 int i;
622 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000623
624#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000625 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
626 if (self == NULL)
627 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000628
Fred Drake0582df92000-07-12 04:49:00 +0000629 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000630#else
Fred Drake0582df92000-07-12 04:49:00 +0000631 /* Code for versions 1.6 and later */
632 self = PyObject_New(xmlparseobject, &Xmlparsetype);
633 if (self == NULL)
634 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000635
Fred Drake0582df92000-07-12 04:49:00 +0000636 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000637#endif
Fred Drake0582df92000-07-12 04:49:00 +0000638 if (namespace_separator) {
639 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
640 }
641 else{
642 self->itself = XML_ParserCreate(encoding);
643 }
644 if (self->itself == NULL) {
645 PyErr_SetString(PyExc_RuntimeError,
646 "XML_ParserCreate failed");
647 Py_DECREF(self);
648 return NULL;
649 }
650 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000651
Fred Drake0582df92000-07-12 04:49:00 +0000652 for(i = 0; handler_info[i].name != NULL; i++)
653 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000654
Fred Drake0582df92000-07-12 04:49:00 +0000655 self->handlers = malloc(sizeof(PyObject *)*i);
656 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000657
Fred Drake0582df92000-07-12 04:49:00 +0000658 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000659}
660
661
662static void
Fred Drake0582df92000-07-12 04:49:00 +0000663xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000664{
Fred Drake0582df92000-07-12 04:49:00 +0000665 int i;
666 if (self->itself)
667 XML_ParserFree(self->itself);
668 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000669
Fred Drake0582df92000-07-12 04:49:00 +0000670 for (i=0; handler_info[i].name != NULL; i++) {
671 Py_XDECREF(self->handlers[i]);
672 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000673#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000674 /* Code for versions before 1.6 */
675 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000676#else
Fred Drake0582df92000-07-12 04:49:00 +0000677 /* Code for versions 1.6 and later */
678 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000679#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000680}
681
Fred Drake0582df92000-07-12 04:49:00 +0000682static int
683handlername2int(const char *name)
684{
685 int i;
686 for (i=0; handler_info[i].name != NULL; i++) {
687 if (strcmp(name, handler_info[i].name) == 0) {
688 return i;
689 }
690 }
691 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000692}
693
694static PyObject *
695xmlparse_getattr(xmlparseobject *self, char *name)
696{
Fred Drake0582df92000-07-12 04:49:00 +0000697 int handlernum;
698 if (strcmp(name, "ErrorCode") == 0)
699 return Py_BuildValue("l",
700 (long)XML_GetErrorCode(self->itself));
701 if (strcmp(name, "ErrorLineNumber") == 0)
702 return Py_BuildValue("l",
703 (long)XML_GetErrorLineNumber(self->itself));
704 if (strcmp(name, "ErrorColumnNumber") == 0)
705 return Py_BuildValue("l",
706 (long)XML_GetErrorColumnNumber(self->itself));
707 if (strcmp(name, "ErrorByteIndex") == 0)
708 return Py_BuildValue("l",
709 XML_GetErrorByteIndex(self->itself));
710 if (strcmp(name, "returns_unicode") == 0)
711 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000712
Fred Drake0582df92000-07-12 04:49:00 +0000713 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000714
Fred Drake0582df92000-07-12 04:49:00 +0000715 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
716 Py_INCREF(self->handlers[handlernum]);
717 return self->handlers[handlernum];
718 }
719 if (strcmp(name, "__members__") == 0) {
720 int i;
721 PyObject *rc = PyList_New(0);
722 for(i = 0; handler_info[i].name!=NULL; i++) {
723 PyList_Append(rc,
724 PyString_FromString(handler_info[i].name));
725 }
726 PyList_Append(rc, PyString_FromString("ErrorCode"));
727 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
728 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
729 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000730
Fred Drake0582df92000-07-12 04:49:00 +0000731 return rc;
732 }
733 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000734}
735
Fred Drake6f987622000-08-25 18:03:30 +0000736static int
737sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000738{
739 int handlernum = handlername2int(name);
740 if (handlernum != -1) {
741 Py_INCREF(v);
742 Py_XDECREF(self->handlers[handlernum]);
743 self->handlers[handlernum] = v;
744 handler_info[handlernum].setter(self->itself,
745 handler_info[handlernum].handler);
746 return 1;
747 }
748 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000749}
750
751static int
Fred Drake6f987622000-08-25 18:03:30 +0000752xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000753{
Fred Drake6f987622000-08-25 18:03:30 +0000754 /* Set attribute 'name' to value 'v'. v==NULL means delete */
755 if (v==NULL) {
756 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
757 return -1;
758 }
759 if (strcmp(name, "returns_unicode") == 0) {
760 PyObject *intobj = PyNumber_Int(v);
761 if (intobj == NULL) return -1;
762 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000763#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000764 PyErr_SetString(PyExc_ValueError,
765 "Cannot return Unicode strings in Python 1.5");
766 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000767#else
Fred Drake6f987622000-08-25 18:03:30 +0000768 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000769#endif
Fred Drake6f987622000-08-25 18:03:30 +0000770 }
771 else
772 self->returns_unicode = 0;
773 Py_DECREF(intobj);
774 return 0;
775 }
776 if (sethandler(self, name, v)) {
777 return 0;
778 }
779 PyErr_SetString(PyExc_AttributeError, name);
780 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000781}
782
783static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000784"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000785
786static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000787 PyObject_HEAD_INIT(NULL)
788 0, /*ob_size*/
789 "xmlparser", /*tp_name*/
790 sizeof(xmlparseobject), /*tp_basicsize*/
791 0, /*tp_itemsize*/
792 /* methods */
793 (destructor)xmlparse_dealloc, /*tp_dealloc*/
794 (printfunc)0, /*tp_print*/
795 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
796 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
797 (cmpfunc)0, /*tp_compare*/
798 (reprfunc)0, /*tp_repr*/
799 0, /*tp_as_number*/
800 0, /*tp_as_sequence*/
801 0, /*tp_as_mapping*/
802 (hashfunc)0, /*tp_hash*/
803 (ternaryfunc)0, /*tp_call*/
804 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000805
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000806 /* Space for future expansion */
807 0L,0L,0L,0L,
808 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000809};
810
811/* End of code for xmlparser objects */
812/* -------------------------------------------------------- */
813
814
815static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000816"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
817Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000818
819static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000820pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
821{
822 char *encoding = NULL;
823 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000824 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000825
Fred Drake0582df92000-07-12 04:49:00 +0000826 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000827 &encoding, &namespace_separator))
828 return NULL;
Fred Drake4ba298c2000-10-29 04:57:53 +0000829 if (namespace_separator != NULL
830 && strlen(namespace_separator) != 1) {
831 PyErr_SetString(PyExc_ValueError,
832 "namespace_separator must be one character,"
833 " omitted, or None");
834 return NULL;
835 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000836 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000837}
838
839static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000840"ErrorString(errno) -> string\n\
841Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000842
843static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000844pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000845{
Fred Drake0582df92000-07-12 04:49:00 +0000846 long code = 0;
847
848 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
849 return NULL;
850 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000851}
852
853/* List of methods defined in the module */
854
855static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000856 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
857 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
858 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
859 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000860
Fred Drake0582df92000-07-12 04:49:00 +0000861 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000862};
863
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000864/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000865
866static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000867"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000868
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000869/* Initialization function for the module */
870
Fred Drake93adb692000-09-23 04:55:48 +0000871void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +0000872
Martin v. Löwisc0718eb2000-09-29 19:05:48 +0000873#if PY_VERSION_HEX < 0x2000000
874
875/* 1.5 compatibility: PyModule_AddObject */
876static int
877PyModule_AddObject(PyObject *m, char *name, PyObject *o)
878{
879 PyObject *dict;
880 if (!PyModule_Check(m) || o == NULL)
881 return -1;
882 dict = PyModule_GetDict(m);
883 if (dict == NULL)
884 return -1;
885 if (PyDict_SetItemString(dict, name, o))
886 return -1;
887 Py_DECREF(o);
888 return 0;
889}
890
Fred Drakea77254a2000-09-29 19:23:29 +0000891static int
Martin v. Löwisc0718eb2000-09-29 19:05:48 +0000892PyModule_AddStringConstant(PyObject *m, char *name, char *value)
893{
894 return PyModule_AddObject(m, name, PyString_FromString(value));
895}
896
897#endif
898
Fred Drake6f987622000-08-25 18:03:30 +0000899DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000900initpyexpat(void)
901{
902 PyObject *m, *d;
903 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000904 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000905 PyObject *errors_module, *errors_dict;
906 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000907
Fred Drake6f987622000-08-25 18:03:30 +0000908 if (errmod_name == NULL)
909 return;
910
Fred Drake0582df92000-07-12 04:49:00 +0000911 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000912
Fred Drake0582df92000-07-12 04:49:00 +0000913 /* Create the module and add the functions */
914 m = Py_InitModule4("pyexpat", pyexpat_methods,
915 pyexpat_module_documentation,
916 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000917
Fred Drake0582df92000-07-12 04:49:00 +0000918 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +0000919 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +0000920 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
921 NULL, NULL);
922 PyModule_AddObject(m, "error", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +0000923 Py_INCREF(&Xmlparsetype);
924 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000925
Fred Drake93adb692000-09-23 04:55:48 +0000926 PyModule_AddObject(m, "__version__",
927 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000928
Fred Drake0582df92000-07-12 04:49:00 +0000929 /* XXX When Expat supports some way of figuring out how it was
930 compiled, this should check and set native_encoding
931 appropriately.
932 */
Fred Drake93adb692000-09-23 04:55:48 +0000933 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +0000934
Fred Drake93adb692000-09-23 04:55:48 +0000935 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +0000936 errors_module = PyDict_GetItem(d, errmod_name);
937 if (errors_module == NULL) {
938 errors_module = PyModule_New("pyexpat.errors");
939 if (errors_module != NULL) {
940 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +0000941 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +0000942 /* gives away the reference to errors_module */
943 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000944 }
945 }
Fred Drake6f987622000-08-25 18:03:30 +0000946 Py_DECREF(errmod_name);
947 if (errors_module == NULL)
948 /* Don't code dump later! */
949 return;
950
Fred Drake0582df92000-07-12 04:49:00 +0000951 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000952
953#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +0000954 PyModule_AddStringConstant(errors_module, #name, \
955 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +0000956
Fred Drake0582df92000-07-12 04:49:00 +0000957 MYCONST(XML_ERROR_NO_MEMORY);
958 MYCONST(XML_ERROR_SYNTAX);
959 MYCONST(XML_ERROR_NO_ELEMENTS);
960 MYCONST(XML_ERROR_INVALID_TOKEN);
961 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
962 MYCONST(XML_ERROR_PARTIAL_CHAR);
963 MYCONST(XML_ERROR_TAG_MISMATCH);
964 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
965 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
966 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
967 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
968 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
969 MYCONST(XML_ERROR_ASYNC_ENTITY);
970 MYCONST(XML_ERROR_BAD_CHAR_REF);
971 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
972 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
973 MYCONST(XML_ERROR_MISPLACED_XML_PI);
974 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
975 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Fred Drake93adb692000-09-23 04:55:48 +0000976#undef MYCONST
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000977}
978
Fred Drake6f987622000-08-25 18:03:30 +0000979static void
980clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000981{
982 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000983
Fred Drake0582df92000-07-12 04:49:00 +0000984 for (; handler_info[i].name!=NULL; i++) {
985 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000986 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000987 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000988}
989
Fred Drake6f987622000-08-25 18:03:30 +0000990typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000991
Fred Drake6f987622000-08-25 18:03:30 +0000992static void
993pyxml_UpdatePairedHandlers(xmlparseobject *self,
994 int startHandler,
995 int endHandler,
996 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000997{
998 void *start_handler=NULL;
999 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001000
Fred Drake0582df92000-07-12 04:49:00 +00001001 if (self->handlers[startHandler]
1002 && self->handlers[endHandler]!=Py_None) {
1003 start_handler=handler_info[startHandler].handler;
1004 }
1005 if (self->handlers[EndElement]
1006 && self->handlers[EndElement] !=Py_None) {
1007 end_handler=handler_info[endHandler].handler;
1008 }
1009 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001010}
1011
Fred Drake6f987622000-08-25 18:03:30 +00001012static void
1013pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001014{
1015 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1016 StartElement, EndElement,
1017 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001018}
1019
Fred Drake6f987622000-08-25 18:03:30 +00001020static void
1021pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001022{
1023 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1024 StartElement, EndElement,
1025 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001026}
1027
Fred Drake6f987622000-08-25 18:03:30 +00001028static void
1029pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001030{
1031 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1032 StartNamespaceDecl, EndNamespaceDecl,
1033 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001034}
1035
Fred Drake6f987622000-08-25 18:03:30 +00001036static void
1037pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001038{
1039 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1040 StartNamespaceDecl, EndNamespaceDecl,
1041 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001042}
1043
Fred Drake6f987622000-08-25 18:03:30 +00001044static void
1045pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001046{
1047 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1048 StartCdataSection, EndCdataSection,
1049 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001050}
1051
Fred Drake6f987622000-08-25 18:03:30 +00001052static void
1053pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001054{
1055 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1056 StartCdataSection, EndCdataSection,
1057 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001058}
1059
Fred Drake0582df92000-07-12 04:49:00 +00001060statichere struct HandlerInfo handler_info[] = {
1061 {"StartElementHandler",
1062 pyxml_SetStartElementHandler,
1063 (xmlhandler)my_StartElementHandler},
1064 {"EndElementHandler",
1065 pyxml_SetEndElementHandler,
1066 (xmlhandler)my_EndElementHandler},
1067 {"ProcessingInstructionHandler",
1068 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1069 (xmlhandler)my_ProcessingInstructionHandler},
1070 {"CharacterDataHandler",
1071 (xmlhandlersetter)XML_SetCharacterDataHandler,
1072 (xmlhandler)my_CharacterDataHandler},
1073 {"UnparsedEntityDeclHandler",
1074 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1075 (xmlhandler)my_UnparsedEntityDeclHandler },
1076 {"NotationDeclHandler",
1077 (xmlhandlersetter)XML_SetNotationDeclHandler,
1078 (xmlhandler)my_NotationDeclHandler },
1079 {"StartNamespaceDeclHandler",
1080 pyxml_SetStartNamespaceDeclHandler,
1081 (xmlhandler)my_StartNamespaceDeclHandler },
1082 {"EndNamespaceDeclHandler",
1083 pyxml_SetEndNamespaceDeclHandler,
1084 (xmlhandler)my_EndNamespaceDeclHandler },
1085 {"CommentHandler",
1086 (xmlhandlersetter)XML_SetCommentHandler,
1087 (xmlhandler)my_CommentHandler},
1088 {"StartCdataSectionHandler",
1089 pyxml_SetStartCdataSection,
1090 (xmlhandler)my_StartCdataSectionHandler},
1091 {"EndCdataSectionHandler",
1092 pyxml_SetEndCdataSection,
1093 (xmlhandler)my_EndCdataSectionHandler},
1094 {"DefaultHandler",
1095 (xmlhandlersetter)XML_SetDefaultHandler,
1096 (xmlhandler)my_DefaultHandler},
1097 {"DefaultHandlerExpand",
1098 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1099 (xmlhandler)my_DefaultHandlerExpandHandler},
1100 {"NotStandaloneHandler",
1101 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1102 (xmlhandler)my_NotStandaloneHandler},
1103 {"ExternalEntityRefHandler",
1104 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1105 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001106
Fred Drake0582df92000-07-12 04:49:00 +00001107 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001108};