blob: 7a0d0356aee5da7c817e6d09f853765a090974f1 [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__[] =
Fred Drake2d4ac202001-01-03 15:36:25 +0000538"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);
Fred Drakee8f3ad52000-12-16 01:48:29 +0000722 for(i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +0000723 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"));
Fred Drakee8f3ad52000-12-16 01:48:29 +0000730 PyList_Append(rc, PyString_FromString("returns_unicode"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000731
Fred Drake0582df92000-07-12 04:49:00 +0000732 return rc;
733 }
734 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000735}
736
Fred Drake6f987622000-08-25 18:03:30 +0000737static int
738sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000739{
740 int handlernum = handlername2int(name);
741 if (handlernum != -1) {
742 Py_INCREF(v);
743 Py_XDECREF(self->handlers[handlernum]);
744 self->handlers[handlernum] = v;
745 handler_info[handlernum].setter(self->itself,
746 handler_info[handlernum].handler);
747 return 1;
748 }
749 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000750}
751
752static int
Fred Drake6f987622000-08-25 18:03:30 +0000753xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000754{
Fred Drake6f987622000-08-25 18:03:30 +0000755 /* Set attribute 'name' to value 'v'. v==NULL means delete */
756 if (v==NULL) {
757 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
758 return -1;
759 }
760 if (strcmp(name, "returns_unicode") == 0) {
761 PyObject *intobj = PyNumber_Int(v);
762 if (intobj == NULL) return -1;
763 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000764#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000765 PyErr_SetString(PyExc_ValueError,
766 "Cannot return Unicode strings in Python 1.5");
767 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000768#else
Fred Drake6f987622000-08-25 18:03:30 +0000769 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000770#endif
Fred Drake6f987622000-08-25 18:03:30 +0000771 }
772 else
773 self->returns_unicode = 0;
774 Py_DECREF(intobj);
775 return 0;
776 }
777 if (sethandler(self, name, v)) {
778 return 0;
779 }
780 PyErr_SetString(PyExc_AttributeError, name);
781 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000782}
783
784static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000785"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000786
787static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000788 PyObject_HEAD_INIT(NULL)
789 0, /*ob_size*/
790 "xmlparser", /*tp_name*/
791 sizeof(xmlparseobject), /*tp_basicsize*/
792 0, /*tp_itemsize*/
793 /* methods */
794 (destructor)xmlparse_dealloc, /*tp_dealloc*/
795 (printfunc)0, /*tp_print*/
796 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
797 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
798 (cmpfunc)0, /*tp_compare*/
799 (reprfunc)0, /*tp_repr*/
800 0, /*tp_as_number*/
801 0, /*tp_as_sequence*/
802 0, /*tp_as_mapping*/
803 (hashfunc)0, /*tp_hash*/
804 (ternaryfunc)0, /*tp_call*/
805 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000806
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000807 /* Space for future expansion */
808 0L,0L,0L,0L,
809 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000810};
811
812/* End of code for xmlparser objects */
813/* -------------------------------------------------------- */
814
815
816static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000817"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
818Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000819
820static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000821pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
822{
823 char *encoding = NULL;
824 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000825 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000826
Fred Drake0582df92000-07-12 04:49:00 +0000827 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000828 &encoding, &namespace_separator))
829 return NULL;
Fred Drake4ba298c2000-10-29 04:57:53 +0000830 if (namespace_separator != NULL
831 && strlen(namespace_separator) != 1) {
832 PyErr_SetString(PyExc_ValueError,
833 "namespace_separator must be one character,"
834 " omitted, or None");
835 return NULL;
836 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000837 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000838}
839
840static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000841"ErrorString(errno) -> string\n\
842Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000843
844static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000845pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846{
Fred Drake0582df92000-07-12 04:49:00 +0000847 long code = 0;
848
849 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
850 return NULL;
851 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000852}
853
854/* List of methods defined in the module */
855
856static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000857 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
858 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
859 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
860 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000861
Fred Drake0582df92000-07-12 04:49:00 +0000862 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000863};
864
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000865/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000866
867static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000868"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000869
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000870/* Initialization function for the module */
871
Fred Drake93adb692000-09-23 04:55:48 +0000872void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +0000873
Martin v. Löwisc0718eb2000-09-29 19:05:48 +0000874#if PY_VERSION_HEX < 0x2000000
875
876/* 1.5 compatibility: PyModule_AddObject */
877static int
878PyModule_AddObject(PyObject *m, char *name, PyObject *o)
879{
880 PyObject *dict;
881 if (!PyModule_Check(m) || o == NULL)
882 return -1;
883 dict = PyModule_GetDict(m);
884 if (dict == NULL)
885 return -1;
886 if (PyDict_SetItemString(dict, name, o))
887 return -1;
888 Py_DECREF(o);
889 return 0;
890}
891
Fred Drakea77254a2000-09-29 19:23:29 +0000892static int
Martin v. Löwisc0718eb2000-09-29 19:05:48 +0000893PyModule_AddStringConstant(PyObject *m, char *name, char *value)
894{
895 return PyModule_AddObject(m, name, PyString_FromString(value));
896}
897
898#endif
899
Fred Drake6f987622000-08-25 18:03:30 +0000900DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000901initpyexpat(void)
902{
903 PyObject *m, *d;
904 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000905 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000906 PyObject *errors_module, *errors_dict;
907 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000908
Fred Drake6f987622000-08-25 18:03:30 +0000909 if (errmod_name == NULL)
910 return;
911
Fred Drake0582df92000-07-12 04:49:00 +0000912 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000913
Fred Drake0582df92000-07-12 04:49:00 +0000914 /* Create the module and add the functions */
915 m = Py_InitModule4("pyexpat", pyexpat_methods,
916 pyexpat_module_documentation,
917 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000918
Fred Drake0582df92000-07-12 04:49:00 +0000919 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +0000920 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +0000921 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
922 NULL, NULL);
923 PyModule_AddObject(m, "error", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +0000924 Py_INCREF(&Xmlparsetype);
925 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000926
Fred Drake93adb692000-09-23 04:55:48 +0000927 PyModule_AddObject(m, "__version__",
928 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Fred Drake738293d2000-12-21 17:25:07 +0000929#ifdef XML_MAJOR_VERSION
930 PyModule_AddStringConstant(m, "EXPAT_VERSION",
931 (char *) XML_ExpatVersion());
932 PyModule_AddObject(m, "version_info",
933 Py_BuildValue("(iii)", XML_MAJOR_VERSION,
934 XML_MINOR_VERSION, XML_MICRO_VERSION));
935#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000936
Fred Drake0582df92000-07-12 04:49:00 +0000937 /* XXX When Expat supports some way of figuring out how it was
938 compiled, this should check and set native_encoding
939 appropriately.
940 */
Fred Drake93adb692000-09-23 04:55:48 +0000941 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +0000942
Fred Drake93adb692000-09-23 04:55:48 +0000943 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +0000944 errors_module = PyDict_GetItem(d, errmod_name);
945 if (errors_module == NULL) {
946 errors_module = PyModule_New("pyexpat.errors");
947 if (errors_module != NULL) {
948 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +0000949 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +0000950 /* gives away the reference to errors_module */
951 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000952 }
953 }
Fred Drake6f987622000-08-25 18:03:30 +0000954 Py_DECREF(errmod_name);
955 if (errors_module == NULL)
956 /* Don't code dump later! */
957 return;
958
Fred Drake0582df92000-07-12 04:49:00 +0000959 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000960
961#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +0000962 PyModule_AddStringConstant(errors_module, #name, \
963 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +0000964
Fred Drake0582df92000-07-12 04:49:00 +0000965 MYCONST(XML_ERROR_NO_MEMORY);
966 MYCONST(XML_ERROR_SYNTAX);
967 MYCONST(XML_ERROR_NO_ELEMENTS);
968 MYCONST(XML_ERROR_INVALID_TOKEN);
969 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
970 MYCONST(XML_ERROR_PARTIAL_CHAR);
971 MYCONST(XML_ERROR_TAG_MISMATCH);
972 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
973 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
974 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
975 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
976 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
977 MYCONST(XML_ERROR_ASYNC_ENTITY);
978 MYCONST(XML_ERROR_BAD_CHAR_REF);
979 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
980 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
981 MYCONST(XML_ERROR_MISPLACED_XML_PI);
982 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
983 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Fred Drake93adb692000-09-23 04:55:48 +0000984#undef MYCONST
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000985}
986
Fred Drake6f987622000-08-25 18:03:30 +0000987static void
988clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000989{
990 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000991
Fred Drake0582df92000-07-12 04:49:00 +0000992 for (; handler_info[i].name!=NULL; i++) {
993 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000994 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000995 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000996}
997
Fred Drake6f987622000-08-25 18:03:30 +0000998typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000999
Fred Drake6f987622000-08-25 18:03:30 +00001000static void
1001pyxml_UpdatePairedHandlers(xmlparseobject *self,
1002 int startHandler,
1003 int endHandler,
1004 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +00001005{
1006 void *start_handler=NULL;
1007 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001008
Fred Drake0582df92000-07-12 04:49:00 +00001009 if (self->handlers[startHandler]
1010 && self->handlers[endHandler]!=Py_None) {
1011 start_handler=handler_info[startHandler].handler;
1012 }
1013 if (self->handlers[EndElement]
1014 && self->handlers[EndElement] !=Py_None) {
1015 end_handler=handler_info[endHandler].handler;
1016 }
1017 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001018}
1019
Fred Drake6f987622000-08-25 18:03:30 +00001020static void
1021pyxml_SetStartElementHandler(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_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001030{
1031 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1032 StartElement, EndElement,
1033 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001034}
1035
Fred Drake6f987622000-08-25 18:03:30 +00001036static void
1037pyxml_SetStartNamespaceDeclHandler(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_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001046{
1047 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1048 StartNamespaceDecl, EndNamespaceDecl,
1049 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001050}
1051
Fred Drake6f987622000-08-25 18:03:30 +00001052static void
1053pyxml_SetStartCdataSection(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 Drake6f987622000-08-25 18:03:30 +00001060static void
1061pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001062{
1063 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1064 StartCdataSection, EndCdataSection,
1065 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001066}
1067
Fred Drake0582df92000-07-12 04:49:00 +00001068statichere struct HandlerInfo handler_info[] = {
1069 {"StartElementHandler",
1070 pyxml_SetStartElementHandler,
1071 (xmlhandler)my_StartElementHandler},
1072 {"EndElementHandler",
1073 pyxml_SetEndElementHandler,
1074 (xmlhandler)my_EndElementHandler},
1075 {"ProcessingInstructionHandler",
1076 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1077 (xmlhandler)my_ProcessingInstructionHandler},
1078 {"CharacterDataHandler",
1079 (xmlhandlersetter)XML_SetCharacterDataHandler,
1080 (xmlhandler)my_CharacterDataHandler},
1081 {"UnparsedEntityDeclHandler",
1082 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1083 (xmlhandler)my_UnparsedEntityDeclHandler },
1084 {"NotationDeclHandler",
1085 (xmlhandlersetter)XML_SetNotationDeclHandler,
1086 (xmlhandler)my_NotationDeclHandler },
1087 {"StartNamespaceDeclHandler",
1088 pyxml_SetStartNamespaceDeclHandler,
1089 (xmlhandler)my_StartNamespaceDeclHandler },
1090 {"EndNamespaceDeclHandler",
1091 pyxml_SetEndNamespaceDeclHandler,
1092 (xmlhandler)my_EndNamespaceDeclHandler },
1093 {"CommentHandler",
1094 (xmlhandlersetter)XML_SetCommentHandler,
1095 (xmlhandler)my_CommentHandler},
1096 {"StartCdataSectionHandler",
1097 pyxml_SetStartCdataSection,
1098 (xmlhandler)my_StartCdataSectionHandler},
1099 {"EndCdataSectionHandler",
1100 pyxml_SetEndCdataSection,
1101 (xmlhandler)my_EndCdataSectionHandler},
1102 {"DefaultHandler",
1103 (xmlhandlersetter)XML_SetDefaultHandler,
1104 (xmlhandler)my_DefaultHandler},
1105 {"DefaultHandlerExpand",
1106 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1107 (xmlhandler)my_DefaultHandlerExpandHandler},
1108 {"NotStandaloneHandler",
1109 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1110 (xmlhandler)my_NotStandaloneHandler},
1111 {"ExternalEntityRefHandler",
1112 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1113 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001114
Fred Drake0582df92000-07-12 04:49:00 +00001115 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001116};