blob: 5000229006f33fe3a425b4c477512784411d41d5 [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001#include "Python.h"
2#include "xmlparse.h"
3
4/*
5** The version number should match the one in _checkversion
6*/
7#define VERSION "1.9"
8
Fred Drake0582df92000-07-12 04:49:00 +00009enum HandlerTypes {
10 StartElement,
11 EndElement,
12 ProcessingInstruction,
13 CharacterData,
14 UnparsedEntityDecl,
15 NotationDecl,
16 StartNamespaceDecl,
17 EndNamespaceDecl,
18 Comment,
19 StartCdataSection,
20 EndCdataSection,
21 Default,
22 DefaultHandlerExpand,
23 NotStandalone,
24 ExternalEntityRef
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000025};
26
27static PyObject *ErrorObject;
28
29/* ----------------------------------------------------- */
30
31/* Declarations for objects of type xmlparser */
32
33typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000034 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000035
Fred Drake0582df92000-07-12 04:49:00 +000036 XML_Parser itself;
37 int returns_unicode; /* True if Unicode strings are returned;
38 if false, UTF-8 strings are returned */
39 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000040} xmlparseobject;
41
42staticforward PyTypeObject Xmlparsetype;
43
Fred Drake6f987622000-08-25 18:03:30 +000044typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000045typedef void* xmlhandler;
46
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000047struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000048 const char *name;
49 xmlhandlersetter setter;
50 xmlhandler handler;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000051};
52
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000053staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000054
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000055/* Convert an array of attributes and their values into a Python dict */
56
Fred Drake0582df92000-07-12 04:49:00 +000057static PyObject *
58conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000059{
Fred Drake0582df92000-07-12 04:49:00 +000060 PyObject *attrs_obj = NULL;
61 XML_Char **attrs_p, **attrs_k = NULL;
62 int attrs_len;
63 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000064
Fred Drake0582df92000-07-12 04:49:00 +000065 if ((attrs_obj = PyDict_New()) == NULL)
66 goto finally;
67 for (attrs_len = 0, attrs_p = atts;
68 *attrs_p;
69 attrs_p++, attrs_len++) {
70 if (attrs_len % 2) {
71 rv = PyString_FromString(*attrs_p);
72 if (!rv) {
73 Py_DECREF(attrs_obj);
74 attrs_obj = NULL;
75 goto finally;
76 }
77 if (PyDict_SetItemString(attrs_obj,
78 (char*)*attrs_k, rv) < 0) {
79 Py_DECREF(attrs_obj);
80 attrs_obj = NULL;
81 goto finally;
82 }
83 Py_DECREF(rv);
84 }
85 else
86 attrs_k = attrs_p;
87 }
88 finally:
89 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000090}
91
92#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +000093static PyObject *
94conv_atts_using_unicode(XML_Char **atts)
95{
Fred Drakeca1f4262000-09-21 20:10:23 +000096 PyObject *attrs_obj;
Fred Drake0582df92000-07-12 04:49:00 +000097 XML_Char **attrs_p, **attrs_k = NULL;
98 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000099
Fred Drake0582df92000-07-12 04:49:00 +0000100 if ((attrs_obj = PyDict_New()) == NULL)
101 goto finally;
102 for (attrs_len = 0, attrs_p = atts;
103 *attrs_p;
104 attrs_p++, attrs_len++) {
105 if (attrs_len % 2) {
106 PyObject *attr_str, *value_str;
107 const char *p = (const char *) (*attrs_k);
108 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
109 if (!attr_str) {
110 Py_DECREF(attrs_obj);
111 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000112 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000113 }
114 p = (const char *) *attrs_p;
115 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
116 if (!value_str) {
117 Py_DECREF(attrs_obj);
118 Py_DECREF(attr_str);
119 attrs_obj = NULL;
120 goto finally;
121 }
122 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
123 Py_DECREF(attrs_obj);
Fred Drakeca1f4262000-09-21 20:10:23 +0000124 Py_DECREF(attr_str);
125 Py_DECREF(value_str);
Fred Drake0582df92000-07-12 04:49:00 +0000126 attrs_obj = NULL;
127 goto finally;
128 }
129 Py_DECREF(attr_str);
130 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000131 }
Fred Drake0582df92000-07-12 04:49:00 +0000132 else
133 attrs_k = attrs_p;
134 }
135 finally:
136 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000137}
138
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000139/* Convert a string of XML_Chars into a Unicode string.
140 Returns None if str is a null pointer. */
141
Fred Drake0582df92000-07-12 04:49:00 +0000142static PyObject *
143conv_string_to_unicode(XML_Char *str)
144{
145 /* XXX currently this code assumes that XML_Char is 8-bit,
146 and hence in UTF-8. */
147 /* UTF-8 from Expat, Unicode desired */
148 if (str == NULL) {
149 Py_INCREF(Py_None);
150 return Py_None;
151 }
152 return PyUnicode_DecodeUTF8((const char *)str,
153 strlen((const char *)str),
154 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000155}
156
Fred Drake0582df92000-07-12 04:49:00 +0000157static PyObject *
158conv_string_len_to_unicode(const XML_Char *str, int len)
159{
160 /* XXX currently this code assumes that XML_Char is 8-bit,
161 and hence in UTF-8. */
162 /* UTF-8 from Expat, Unicode desired */
163 if (str == NULL) {
164 Py_INCREF(Py_None);
165 return Py_None;
166 }
Fred Drake6f987622000-08-25 18:03:30 +0000167 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000168}
169#endif
170
171/* Convert a string of XML_Chars into an 8-bit Python string.
172 Returns None if str is a null pointer. */
173
Fred Drake6f987622000-08-25 18:03:30 +0000174static PyObject *
175conv_string_to_utf8(XML_Char *str)
176{
177 /* XXX currently this code assumes that XML_Char is 8-bit,
178 and hence in UTF-8. */
179 /* UTF-8 from Expat, UTF-8 desired */
180 if (str == NULL) {
181 Py_INCREF(Py_None);
182 return Py_None;
183 }
184 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000185}
186
Fred Drake6f987622000-08-25 18:03:30 +0000187static PyObject *
188conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000189{
Fred Drake6f987622000-08-25 18:03:30 +0000190 /* XXX currently this code assumes that XML_Char is 8-bit,
191 and hence in UTF-8. */
192 /* UTF-8 from Expat, UTF-8 desired */
193 if (str == NULL) {
194 Py_INCREF(Py_None);
195 return Py_None;
196 }
197 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000198}
199
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000200/* Callback routines */
201
Fred Drake6f987622000-08-25 18:03:30 +0000202static void clear_handlers(xmlparseobject *self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000203
Fred Drake6f987622000-08-25 18:03:30 +0000204static void
205flag_error(xmlparseobject *self)
206{
207 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000208}
209
Fred Drake6f987622000-08-25 18:03:30 +0000210#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000211 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000212\
213static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000214 xmlparseobject *self = GETUSERDATA ; \
215 PyObject *args=NULL; \
216 PyObject *rv=NULL; \
217 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000218\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000219 if (self->handlers[NAME] \
220 && self->handlers[NAME] != Py_None) { \
221 args = Py_BuildValue PARAM_FORMAT ;\
222 if (!args) return RETURN; \
223 rv = PyEval_CallObject(self->handlers[NAME], args); \
224 Py_DECREF(args); \
225 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000226 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000227 return RETURN; \
228 } \
229 CONVERSION \
230 Py_DECREF(rv); \
231 } \
232 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000233}
234
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000235#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
236#define STRING_CONV_FUNC conv_string_to_utf8
237#else
238/* Python 1.6 and later versions */
239#define STRING_CONV_FUNC (self->returns_unicode \
240 ? conv_string_to_unicode : conv_string_to_utf8)
241#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000242
Fred Drake6f987622000-08-25 18:03:30 +0000243#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
244 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
245 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000246
Fred Drake6f987622000-08-25 18:03:30 +0000247#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
248 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
249 rc = PyInt_AsLong(rv);, rc, \
250 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000251
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000252#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000253VOID_HANDLER(StartElement,
254 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000255 ("(O&O&)", STRING_CONV_FUNC, name,
256 conv_atts_using_string, atts ) )
257#else
258/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000259VOID_HANDLER(StartElement,
260 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000261 ("(O&O&)", STRING_CONV_FUNC, name,
262 (self->returns_unicode
263 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000264 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000265#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000266
Fred Drake6f987622000-08-25 18:03:30 +0000267VOID_HANDLER(EndElement,
268 (void *userData, const XML_Char *name),
269 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000270
Fred Drake6f987622000-08-25 18:03:30 +0000271VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000272 (void *userData,
273 const XML_Char *target,
274 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000275 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000276
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000277#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000278VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000279 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000280 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000281#else
Fred Drake6f987622000-08-25 18:03:30 +0000282VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000283 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000284 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000285 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000286 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000287#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000288
Fred Drake6f987622000-08-25 18:03:30 +0000289VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000290 (void *userData,
291 const XML_Char *entityName,
292 const XML_Char *base,
293 const XML_Char *systemId,
294 const XML_Char *publicId,
295 const XML_Char *notationName),
296 ("(O&O&O&O&O&)",
297 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
298 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
299 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000300
Fred Drake6f987622000-08-25 18:03:30 +0000301VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000302 (void *userData,
303 const XML_Char *notationName,
304 const XML_Char *base,
305 const XML_Char *systemId,
306 const XML_Char *publicId),
307 ("(O&O&O&O&)",
308 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
309 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000310
Fred Drake6f987622000-08-25 18:03:30 +0000311VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000312 (void *userData,
313 const XML_Char *prefix,
314 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000315 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000316
Fred Drake6f987622000-08-25 18:03:30 +0000317VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000318 (void *userData,
319 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000320 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000321
Fred Drake6f987622000-08-25 18:03:30 +0000322VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000323 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000324 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000325
Fred Drake6f987622000-08-25 18:03:30 +0000326VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000327 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000328 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000329
Fred Drake6f987622000-08-25 18:03:30 +0000330VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000331 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000332 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000333
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000334#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000335VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000336 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000337 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000338
Fred Drake6f987622000-08-25 18:03:30 +0000339VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000340 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000341 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000342#else
Fred Drake6f987622000-08-25 18:03:30 +0000343VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000344 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000345 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000346 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000347 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348
Fred Drake6f987622000-08-25 18:03:30 +0000349VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000350 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000351 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000352 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000353 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000354#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000355
Fred Drake6f987622000-08-25 18:03:30 +0000356INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000357 (void *userData),
358 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000359
Fred Drake6f987622000-08-25 18:03:30 +0000360RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000361 (XML_Parser parser,
362 const XML_Char *context,
363 const XML_Char *base,
364 const XML_Char *systemId,
365 const XML_Char *publicId),
366 int rc=0;,
367 ("(O&O&O&O&)",
368 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000369 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
370 rc = PyInt_AsLong(rv);, rc,
371 XML_GetUserData(parser))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000372
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000373
374
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000375/* ---------------------------------------------------------------- */
376
377static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000378"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000379Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000380
381static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000382xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000383{
Fred Drake0582df92000-07-12 04:49:00 +0000384 char *s;
385 int slen;
386 int isFinal = 0;
387 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000388
Fred Drake0582df92000-07-12 04:49:00 +0000389 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
390 return NULL;
391 rv = XML_Parse(self->itself, s, slen, isFinal);
392 if (PyErr_Occurred()) {
393 return NULL;
394 }
395 else if (rv == 0) {
396 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
397 XML_ErrorString(XML_GetErrorCode(self->itself)),
398 XML_GetErrorLineNumber(self->itself),
399 XML_GetErrorColumnNumber(self->itself));
400 return NULL;
401 }
402 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000403}
404
Fred Drakeca1f4262000-09-21 20:10:23 +0000405/* File reading copied from cPickle */
406
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000407#define BUF_SIZE 2048
408
Fred Drake0582df92000-07-12 04:49:00 +0000409static int
410readinst(char *buf, int buf_size, PyObject *meth)
411{
412 PyObject *arg = NULL;
413 PyObject *bytes = NULL;
414 PyObject *str = NULL;
415 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000416
Fred Drake676940b2000-09-22 15:21:31 +0000417 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000418 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000419
Fred Drakeca1f4262000-09-21 20:10:23 +0000420 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000421 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000422
Tim Peters954eef72000-09-22 06:01:11 +0000423 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424
Fred Drakeca1f4262000-09-21 20:10:23 +0000425 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000426 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000427
Fred Drake0582df92000-07-12 04:49:00 +0000428 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000429 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000430 PyErr_Format(PyExc_TypeError,
431 "read() did not return a string object (type=%.400s)",
432 str->ob_type->tp_name);
433 goto finally;
434 }
435 len = PyString_GET_SIZE(str);
436 if (len > buf_size) {
437 PyErr_Format(PyExc_ValueError,
438 "read() returned too much data: "
439 "%i bytes requested, %i returned",
440 buf_size, len);
441 Py_DECREF(str);
442 goto finally;
443 }
444 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000445finally:
Fred Drake0582df92000-07-12 04:49:00 +0000446 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000447 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000448 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000449}
450
451static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000452"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000453Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000454
455static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000456xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000457{
Fred Drake0582df92000-07-12 04:49:00 +0000458 int rv = 1;
459 PyObject *f;
460 FILE *fp;
461 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000462
Fred Drake0582df92000-07-12 04:49:00 +0000463 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
464 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000465
Fred Drake0582df92000-07-12 04:49:00 +0000466 if (PyFile_Check(f)) {
467 fp = PyFile_AsFile(f);
468 }
469 else{
470 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000471 readmethod = PyObject_GetAttrString(f, "read");
472 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000473 PyErr_Clear();
474 PyErr_SetString(PyExc_TypeError,
475 "argument must have 'read' attribute");
476 return 0;
477 }
478 }
479 for (;;) {
480 int bytes_read;
481 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
482 if (buf == NULL)
483 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000484
Fred Drake0582df92000-07-12 04:49:00 +0000485 if (fp) {
486 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
487 if (bytes_read < 0) {
488 PyErr_SetFromErrno(PyExc_IOError);
489 return NULL;
490 }
491 }
492 else {
493 bytes_read = readinst(buf, BUF_SIZE, readmethod);
494 if (bytes_read < 0)
495 return NULL;
496 }
497 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
498 if (PyErr_Occurred())
499 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500
Fred Drake0582df92000-07-12 04:49:00 +0000501 if (!rv || bytes_read == 0)
502 break;
503 }
504 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505}
506
507static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000508"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000509Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000510
511static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000512xmlparse_SetBase(xmlparseobject *self, PyObject *args)
513{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000514 char *base;
515
Fred Drake0582df92000-07-12 04:49:00 +0000516 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000517 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000518 if (!XML_SetBase(self->itself, base)) {
519 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000520 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000521 Py_INCREF(Py_None);
522 return Py_None;
523}
524
525static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000526"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000527Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000528
529static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000530xmlparse_GetBase(xmlparseobject *self, PyObject *args)
531{
532 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000533 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000534
Fred Drake0582df92000-07-12 04:49:00 +0000535 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000536}
537
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000538static char xmlparse_ExternalEntityParserCreate__doc__[] =
539"ExternalEntityParserCreate(context, encoding)\n\
540Create a parser for parsing an external entity based on the
541information passed to the ExternalEntityRefHandler.";
542
543static PyObject *
544xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
545{
546 char *context;
547 char *encoding = NULL;
548 xmlparseobject *new_parser;
549 int i;
550
551 if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
552 &encoding)) {
553 return NULL;
554 }
555
556#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
557 new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
558 if (new_parser == NULL)
559 return NULL;
560
561 new_parser->returns_unicode = 0;
562#else
563 /* Code for versions 1.6 and later */
564 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
565 if (new_parser == NULL)
566 return NULL;
567
568 new_parser->returns_unicode = 1;
569#endif
570
571 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
572 encoding);
573 if (!new_parser) {
574 Py_DECREF(new_parser);
575 return PyErr_NoMemory();
576 }
577
578 XML_SetUserData(new_parser->itself, (void *)new_parser);
579
580 /* allocate and clear handlers first */
581 for(i = 0; handler_info[i].name != NULL; i++)
582 /* do nothing */;
583
584 new_parser->handlers = malloc(sizeof(PyObject *)*i);
585 clear_handlers(new_parser);
586
587 /* then copy handlers from self */
588 for (i = 0; handler_info[i].name != NULL; i++) {
589 if (self->handlers[i]) {
590 Py_INCREF(self->handlers[i]);
591 new_parser->handlers[i] = self->handlers[i];
592 handler_info[i].setter(new_parser->itself,
593 handler_info[i].handler);
594 }
595 }
596
597 return new_parser;
598}
599
600
601
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000602static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000603 {"Parse", (PyCFunction)xmlparse_Parse,
604 METH_VARARGS, xmlparse_Parse__doc__},
605 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
606 METH_VARARGS, xmlparse_ParseFile__doc__},
607 {"SetBase", (PyCFunction)xmlparse_SetBase,
608 METH_VARARGS, xmlparse_SetBase__doc__},
609 {"GetBase", (PyCFunction)xmlparse_GetBase,
610 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000611 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
612 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000613 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000614};
615
616/* ---------- */
617
618
619static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000620newxmlparseobject(char *encoding, char *namespace_separator)
621{
622 int i;
623 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000624
625#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000626 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
627 if (self == NULL)
628 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000629
Fred Drake0582df92000-07-12 04:49:00 +0000630 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000631#else
Fred Drake0582df92000-07-12 04:49:00 +0000632 /* Code for versions 1.6 and later */
633 self = PyObject_New(xmlparseobject, &Xmlparsetype);
634 if (self == NULL)
635 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000636
Fred Drake0582df92000-07-12 04:49:00 +0000637 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000638#endif
Fred Drake0582df92000-07-12 04:49:00 +0000639 if (namespace_separator) {
640 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
641 }
642 else{
643 self->itself = XML_ParserCreate(encoding);
644 }
645 if (self->itself == NULL) {
646 PyErr_SetString(PyExc_RuntimeError,
647 "XML_ParserCreate failed");
648 Py_DECREF(self);
649 return NULL;
650 }
651 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000652
Fred Drake0582df92000-07-12 04:49:00 +0000653 for(i = 0; handler_info[i].name != NULL; i++)
654 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000655
Fred Drake0582df92000-07-12 04:49:00 +0000656 self->handlers = malloc(sizeof(PyObject *)*i);
657 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000658
Fred Drake0582df92000-07-12 04:49:00 +0000659 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000660}
661
662
663static void
Fred Drake0582df92000-07-12 04:49:00 +0000664xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000665{
Fred Drake0582df92000-07-12 04:49:00 +0000666 int i;
667 if (self->itself)
668 XML_ParserFree(self->itself);
669 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000670
Fred Drake0582df92000-07-12 04:49:00 +0000671 for (i=0; handler_info[i].name != NULL; i++) {
672 Py_XDECREF(self->handlers[i]);
673 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000674#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000675 /* Code for versions before 1.6 */
676 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000677#else
Fred Drake0582df92000-07-12 04:49:00 +0000678 /* Code for versions 1.6 and later */
679 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000680#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000681}
682
Fred Drake0582df92000-07-12 04:49:00 +0000683static int
684handlername2int(const char *name)
685{
686 int i;
687 for (i=0; handler_info[i].name != NULL; i++) {
688 if (strcmp(name, handler_info[i].name) == 0) {
689 return i;
690 }
691 }
692 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000693}
694
695static PyObject *
696xmlparse_getattr(xmlparseobject *self, char *name)
697{
Fred Drake0582df92000-07-12 04:49:00 +0000698 int handlernum;
699 if (strcmp(name, "ErrorCode") == 0)
700 return Py_BuildValue("l",
701 (long)XML_GetErrorCode(self->itself));
702 if (strcmp(name, "ErrorLineNumber") == 0)
703 return Py_BuildValue("l",
704 (long)XML_GetErrorLineNumber(self->itself));
705 if (strcmp(name, "ErrorColumnNumber") == 0)
706 return Py_BuildValue("l",
707 (long)XML_GetErrorColumnNumber(self->itself));
708 if (strcmp(name, "ErrorByteIndex") == 0)
709 return Py_BuildValue("l",
710 XML_GetErrorByteIndex(self->itself));
711 if (strcmp(name, "returns_unicode") == 0)
712 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000713
Fred Drake0582df92000-07-12 04:49:00 +0000714 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000715
Fred Drake0582df92000-07-12 04:49:00 +0000716 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
717 Py_INCREF(self->handlers[handlernum]);
718 return self->handlers[handlernum];
719 }
720 if (strcmp(name, "__members__") == 0) {
721 int i;
722 PyObject *rc = PyList_New(0);
723 for(i = 0; handler_info[i].name!=NULL; i++) {
724 PyList_Append(rc,
725 PyString_FromString(handler_info[i].name));
726 }
727 PyList_Append(rc, PyString_FromString("ErrorCode"));
728 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
729 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
730 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
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;
830 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000831}
832
833static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000834"ErrorString(errno) -> string\n\
835Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000836
837static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000838pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000839{
Fred Drake0582df92000-07-12 04:49:00 +0000840 long code = 0;
841
842 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
843 return NULL;
844 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000845}
846
847/* List of methods defined in the module */
848
849static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000850 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
851 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
852 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
853 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000854
Fred Drake0582df92000-07-12 04:49:00 +0000855 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000856};
857
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000858/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000859
860static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000861"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000862
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000863/* Initialization function for the module */
864
Fred Drake93adb692000-09-23 04:55:48 +0000865void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +0000866
867DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000868initpyexpat(void)
869{
870 PyObject *m, *d;
871 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000872 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000873 PyObject *errors_module, *errors_dict;
874 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000875
Fred Drake6f987622000-08-25 18:03:30 +0000876 if (errmod_name == NULL)
877 return;
878
Fred Drake0582df92000-07-12 04:49:00 +0000879 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880
Fred Drake0582df92000-07-12 04:49:00 +0000881 /* Create the module and add the functions */
882 m = Py_InitModule4("pyexpat", pyexpat_methods,
883 pyexpat_module_documentation,
884 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000885
Fred Drake0582df92000-07-12 04:49:00 +0000886 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +0000887 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +0000888 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
889 NULL, NULL);
890 PyModule_AddObject(m, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000891
Fred Drake93adb692000-09-23 04:55:48 +0000892 PyModule_AddObject(m, "__version__",
893 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000894
Fred Drake0582df92000-07-12 04:49:00 +0000895 /* XXX When Expat supports some way of figuring out how it was
896 compiled, this should check and set native_encoding
897 appropriately.
898 */
Fred Drake93adb692000-09-23 04:55:48 +0000899 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +0000900
Fred Drake93adb692000-09-23 04:55:48 +0000901 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +0000902 errors_module = PyDict_GetItem(d, errmod_name);
903 if (errors_module == NULL) {
904 errors_module = PyModule_New("pyexpat.errors");
905 if (errors_module != NULL) {
906 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +0000907 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +0000908 /* gives away the reference to errors_module */
909 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000910 }
911 }
Fred Drake6f987622000-08-25 18:03:30 +0000912 Py_DECREF(errmod_name);
913 if (errors_module == NULL)
914 /* Don't code dump later! */
915 return;
916
Fred Drake0582df92000-07-12 04:49:00 +0000917 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000918
919#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +0000920 PyModule_AddStringConstant(errors_module, #name, \
921 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +0000922
Fred Drake0582df92000-07-12 04:49:00 +0000923 MYCONST(XML_ERROR_NO_MEMORY);
924 MYCONST(XML_ERROR_SYNTAX);
925 MYCONST(XML_ERROR_NO_ELEMENTS);
926 MYCONST(XML_ERROR_INVALID_TOKEN);
927 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
928 MYCONST(XML_ERROR_PARTIAL_CHAR);
929 MYCONST(XML_ERROR_TAG_MISMATCH);
930 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
931 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
932 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
933 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
934 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
935 MYCONST(XML_ERROR_ASYNC_ENTITY);
936 MYCONST(XML_ERROR_BAD_CHAR_REF);
937 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
938 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
939 MYCONST(XML_ERROR_MISPLACED_XML_PI);
940 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
941 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Fred Drake93adb692000-09-23 04:55:48 +0000942#undef MYCONST
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000943}
944
Fred Drake6f987622000-08-25 18:03:30 +0000945static void
946clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000947{
948 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000949
Fred Drake0582df92000-07-12 04:49:00 +0000950 for (; handler_info[i].name!=NULL; i++) {
951 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000952 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000953 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000954}
955
Fred Drake6f987622000-08-25 18:03:30 +0000956typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000957
Fred Drake6f987622000-08-25 18:03:30 +0000958static void
959pyxml_UpdatePairedHandlers(xmlparseobject *self,
960 int startHandler,
961 int endHandler,
962 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000963{
964 void *start_handler=NULL;
965 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000966
Fred Drake0582df92000-07-12 04:49:00 +0000967 if (self->handlers[startHandler]
968 && self->handlers[endHandler]!=Py_None) {
969 start_handler=handler_info[startHandler].handler;
970 }
971 if (self->handlers[EndElement]
972 && self->handlers[EndElement] !=Py_None) {
973 end_handler=handler_info[endHandler].handler;
974 }
975 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000976}
977
Fred Drake6f987622000-08-25 18:03:30 +0000978static void
979pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000980{
981 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
982 StartElement, EndElement,
983 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000984}
985
Fred Drake6f987622000-08-25 18:03:30 +0000986static void
987pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000988{
989 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
990 StartElement, EndElement,
991 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000992}
993
Fred Drake6f987622000-08-25 18:03:30 +0000994static void
995pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000996{
997 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
998 StartNamespaceDecl, EndNamespaceDecl,
999 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001000}
1001
Fred Drake6f987622000-08-25 18:03:30 +00001002static void
1003pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001004{
1005 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1006 StartNamespaceDecl, EndNamespaceDecl,
1007 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001008}
1009
Fred Drake6f987622000-08-25 18:03:30 +00001010static void
1011pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001012{
1013 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1014 StartCdataSection, EndCdataSection,
1015 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001016}
1017
Fred Drake6f987622000-08-25 18:03:30 +00001018static void
1019pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001020{
1021 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1022 StartCdataSection, EndCdataSection,
1023 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001024}
1025
Fred Drake0582df92000-07-12 04:49:00 +00001026statichere struct HandlerInfo handler_info[] = {
1027 {"StartElementHandler",
1028 pyxml_SetStartElementHandler,
1029 (xmlhandler)my_StartElementHandler},
1030 {"EndElementHandler",
1031 pyxml_SetEndElementHandler,
1032 (xmlhandler)my_EndElementHandler},
1033 {"ProcessingInstructionHandler",
1034 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1035 (xmlhandler)my_ProcessingInstructionHandler},
1036 {"CharacterDataHandler",
1037 (xmlhandlersetter)XML_SetCharacterDataHandler,
1038 (xmlhandler)my_CharacterDataHandler},
1039 {"UnparsedEntityDeclHandler",
1040 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1041 (xmlhandler)my_UnparsedEntityDeclHandler },
1042 {"NotationDeclHandler",
1043 (xmlhandlersetter)XML_SetNotationDeclHandler,
1044 (xmlhandler)my_NotationDeclHandler },
1045 {"StartNamespaceDeclHandler",
1046 pyxml_SetStartNamespaceDeclHandler,
1047 (xmlhandler)my_StartNamespaceDeclHandler },
1048 {"EndNamespaceDeclHandler",
1049 pyxml_SetEndNamespaceDeclHandler,
1050 (xmlhandler)my_EndNamespaceDeclHandler },
1051 {"CommentHandler",
1052 (xmlhandlersetter)XML_SetCommentHandler,
1053 (xmlhandler)my_CommentHandler},
1054 {"StartCdataSectionHandler",
1055 pyxml_SetStartCdataSection,
1056 (xmlhandler)my_StartCdataSectionHandler},
1057 {"EndCdataSectionHandler",
1058 pyxml_SetEndCdataSection,
1059 (xmlhandler)my_EndCdataSectionHandler},
1060 {"DefaultHandler",
1061 (xmlhandlersetter)XML_SetDefaultHandler,
1062 (xmlhandler)my_DefaultHandler},
1063 {"DefaultHandlerExpand",
1064 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1065 (xmlhandler)my_DefaultHandlerExpandHandler},
1066 {"NotStandaloneHandler",
1067 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1068 (xmlhandler)my_NotStandaloneHandler},
1069 {"ExternalEntityRefHandler",
1070 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1071 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001072
Fred Drake0582df92000-07-12 04:49:00 +00001073 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001074};