blob: f20adcb4f315787773a125ae92c0a717e407b569 [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001#include "Python.h"
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002#include "compile.h"
3#include "frameobject.h"
Fred Drakea77254a2000-09-29 19:23:29 +00004#ifdef HAVE_EXPAT_H
5#include "expat.h"
6#else
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00007#include "xmlparse.h"
Fred Drakea77254a2000-09-29 19:23:29 +00008#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00009
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000010#ifdef XML_MAJOR_VERSION
Martin v. Löwis6512dbd2001-01-21 10:22:12 +000011#define EXPAT_VERSION (0x10000*XML_MAJOR_VERSION+0x100*XML_MINOR_VERSION+XML_MICRO_VERSION)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000012#else
13#ifndef EXPAT_VERSION
14/* Assume Expat 1.1 unless told otherwise */
15#define EXPAT_VERSION 0x010100
16#endif
17#endif
18
19#ifndef PyGC_HEAD_SIZE
20#define PyGC_HEAD_SIZE 0
21#define PyObject_GC_Init(x)
22#define PyObject_GC_Fini(m)
23#define Py_TPFLAGS_GC 0
24#endif
25
Fred Drake0582df92000-07-12 04:49:00 +000026enum HandlerTypes {
27 StartElement,
28 EndElement,
29 ProcessingInstruction,
30 CharacterData,
31 UnparsedEntityDecl,
32 NotationDecl,
33 StartNamespaceDecl,
34 EndNamespaceDecl,
35 Comment,
36 StartCdataSection,
37 EndCdataSection,
38 Default,
39 DefaultHandlerExpand,
40 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000041 ExternalEntityRef,
42 StartDoctypeDecl,
43 EndDoctypeDecl,
44 ExternalParsedEntityDecl,
45 InternalParsedEntityDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000046};
47
48static PyObject *ErrorObject;
49
50/* ----------------------------------------------------- */
51
52/* Declarations for objects of type xmlparser */
53
54typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000055 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000056
Fred Drake0582df92000-07-12 04:49:00 +000057 XML_Parser itself;
58 int returns_unicode; /* True if Unicode strings are returned;
59 if false, UTF-8 strings are returned */
60 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000061} xmlparseobject;
62
63staticforward PyTypeObject Xmlparsetype;
64
Fred Drake6f987622000-08-25 18:03:30 +000065typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000066typedef void* xmlhandler;
67
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000068struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000069 const char *name;
70 xmlhandlersetter setter;
71 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000072 PyCodeObject *tb_code;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000073};
74
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000075staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000076
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000077/* Convert an array of attributes and their values into a Python dict */
78
Fred Drake0582df92000-07-12 04:49:00 +000079static PyObject *
80conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000081{
Fred Drake0582df92000-07-12 04:49:00 +000082 PyObject *attrs_obj = NULL;
83 XML_Char **attrs_p, **attrs_k = NULL;
84 int attrs_len;
85 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000086
Fred Drake0582df92000-07-12 04:49:00 +000087 if ((attrs_obj = PyDict_New()) == NULL)
88 goto finally;
89 for (attrs_len = 0, attrs_p = atts;
90 *attrs_p;
91 attrs_p++, attrs_len++) {
92 if (attrs_len % 2) {
93 rv = PyString_FromString(*attrs_p);
94 if (!rv) {
95 Py_DECREF(attrs_obj);
96 attrs_obj = NULL;
97 goto finally;
98 }
99 if (PyDict_SetItemString(attrs_obj,
100 (char*)*attrs_k, rv) < 0) {
Tim Peterse8157862001-01-22 03:20:55 +0000101 Py_DECREF(rv);
Fred Drake0582df92000-07-12 04:49:00 +0000102 Py_DECREF(attrs_obj);
103 attrs_obj = NULL;
104 goto finally;
105 }
106 Py_DECREF(rv);
107 }
108 else
109 attrs_k = attrs_p;
110 }
111 finally:
112 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000113}
114
115#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +0000116static PyObject *
117conv_atts_using_unicode(XML_Char **atts)
118{
Fred Drakeca1f4262000-09-21 20:10:23 +0000119 PyObject *attrs_obj;
Fred Drake0582df92000-07-12 04:49:00 +0000120 XML_Char **attrs_p, **attrs_k = NULL;
121 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000122
Fred Drake0582df92000-07-12 04:49:00 +0000123 if ((attrs_obj = PyDict_New()) == NULL)
124 goto finally;
125 for (attrs_len = 0, attrs_p = atts;
126 *attrs_p;
127 attrs_p++, attrs_len++) {
128 if (attrs_len % 2) {
129 PyObject *attr_str, *value_str;
130 const char *p = (const char *) (*attrs_k);
131 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
132 if (!attr_str) {
133 Py_DECREF(attrs_obj);
134 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000135 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000136 }
137 p = (const char *) *attrs_p;
138 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
139 if (!value_str) {
140 Py_DECREF(attrs_obj);
141 Py_DECREF(attr_str);
142 attrs_obj = NULL;
143 goto finally;
144 }
145 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
146 Py_DECREF(attrs_obj);
Fred Drakeca1f4262000-09-21 20:10:23 +0000147 Py_DECREF(attr_str);
148 Py_DECREF(value_str);
Fred Drake0582df92000-07-12 04:49:00 +0000149 attrs_obj = NULL;
150 goto finally;
151 }
152 Py_DECREF(attr_str);
153 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000154 }
Fred Drake0582df92000-07-12 04:49:00 +0000155 else
156 attrs_k = attrs_p;
157 }
158 finally:
159 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000160}
161
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000162/* Convert a string of XML_Chars into a Unicode string.
163 Returns None if str is a null pointer. */
164
Fred Drake0582df92000-07-12 04:49:00 +0000165static PyObject *
166conv_string_to_unicode(XML_Char *str)
167{
168 /* XXX currently this code assumes that XML_Char is 8-bit,
169 and hence in UTF-8. */
170 /* UTF-8 from Expat, Unicode desired */
171 if (str == NULL) {
172 Py_INCREF(Py_None);
173 return Py_None;
174 }
175 return PyUnicode_DecodeUTF8((const char *)str,
176 strlen((const char *)str),
177 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000178}
179
Fred Drake0582df92000-07-12 04:49:00 +0000180static PyObject *
181conv_string_len_to_unicode(const XML_Char *str, int len)
182{
183 /* XXX currently this code assumes that XML_Char is 8-bit,
184 and hence in UTF-8. */
185 /* UTF-8 from Expat, Unicode desired */
186 if (str == NULL) {
187 Py_INCREF(Py_None);
188 return Py_None;
189 }
Fred Drake6f987622000-08-25 18:03:30 +0000190 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000191}
192#endif
193
194/* Convert a string of XML_Chars into an 8-bit Python string.
195 Returns None if str is a null pointer. */
196
Fred Drake6f987622000-08-25 18:03:30 +0000197static PyObject *
198conv_string_to_utf8(XML_Char *str)
199{
200 /* XXX currently this code assumes that XML_Char is 8-bit,
201 and hence in UTF-8. */
202 /* UTF-8 from Expat, UTF-8 desired */
203 if (str == NULL) {
204 Py_INCREF(Py_None);
205 return Py_None;
206 }
207 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000208}
209
Fred Drake6f987622000-08-25 18:03:30 +0000210static PyObject *
211conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000212{
Fred Drake6f987622000-08-25 18:03:30 +0000213 /* XXX currently this code assumes that XML_Char is 8-bit,
214 and hence in UTF-8. */
215 /* UTF-8 from Expat, UTF-8 desired */
216 if (str == NULL) {
217 Py_INCREF(Py_None);
218 return Py_None;
219 }
220 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000221}
222
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000223/* Callback routines */
224
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000225static void clear_handlers(xmlparseobject *self, int decref);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000226
Fred Drake6f987622000-08-25 18:03:30 +0000227static void
228flag_error(xmlparseobject *self)
229{
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000230 clear_handlers(self, 1);
231}
232
233static PyCodeObject*
234getcode(enum HandlerTypes slot, char* func_name, int lineno)
235{
236 PyObject *code = NULL;
237 PyObject *name = NULL;
238 PyObject *nulltuple = NULL;
239 PyObject *filename = NULL;
240 if (handler_info[slot].tb_code == NULL) {
241 code = PyString_FromString("");
242 if (code == NULL)
243 goto failed;
244 name = PyString_FromString(func_name);
245 if (name == NULL)
246 goto failed;
247 nulltuple = PyTuple_New(0);
248 if (nulltuple == NULL)
249 goto failed;
250 filename = PyString_FromString("pyexpat.c");
251 handler_info[slot].tb_code = PyCode_New(
252 0, /* argcount */
253 0, /* nlocals */
254 0, /* stacksize */
255 0, /* flags */
256 code, /* code */
257 nulltuple, /* consts */
258 nulltuple, /* names */
259 nulltuple, /* varnames */
Jeremy Hylton903f6542001-01-25 20:07:56 +0000260 nulltuple, /* freevars */
261 nulltuple, /* cellvars */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000262 filename, /* filename */
263 name, /* name */
264 lineno, /* firstlineno */
265 code /* lnotab */
266 );
267 if (handler_info[slot].tb_code == NULL)
268 goto failed;
269 Py_DECREF(code);
270 Py_DECREF(nulltuple);
271 Py_DECREF(filename);
272 Py_DECREF(name);
273 }
274 return handler_info[slot].tb_code;
275 failed:
276 Py_XDECREF(code);
277 Py_XDECREF(name);
278 return NULL;
279}
280
281static PyObject*
282call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
283{
284 PyThreadState *tstate = PyThreadState_GET();
285 PyFrameObject *f;
286 PyObject *res;
287 if (c == NULL)
288 return NULL;
289 f = PyFrame_New(
290 tstate, /*back*/
291 c, /*code*/
292 tstate->frame->f_globals, /*globals*/
Jeremy Hylton903f6542001-01-25 20:07:56 +0000293 NULL, /*locals*/
Jeremy Hylton903f6542001-01-25 20:07:56 +0000294 NULL); /* closure */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000295 if (f == NULL)
296 return NULL;
297 tstate->frame = f;
298 res = PyEval_CallObject(func, args);
299 if (res == NULL && tstate->curexc_traceback == NULL)
300 PyTraceBack_Here(f);
301 tstate->frame = f->f_back;
302 Py_DECREF(f);
303 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000304}
305
Fred Drake6f987622000-08-25 18:03:30 +0000306#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000307 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000308\
309static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000310 xmlparseobject *self = GETUSERDATA ; \
311 PyObject *args=NULL; \
312 PyObject *rv=NULL; \
313 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000314\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000315 if (self->handlers[NAME] \
316 && self->handlers[NAME] != Py_None) { \
317 args = Py_BuildValue PARAM_FORMAT ;\
318 if (!args) return RETURN; \
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000319 rv = call_with_frame(getcode(NAME,#NAME,__LINE__),self->handlers[NAME], args); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000320 Py_DECREF(args); \
321 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000322 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000323 return RETURN; \
324 } \
325 CONVERSION \
326 Py_DECREF(rv); \
327 } \
328 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000329}
330
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000331#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
332#define STRING_CONV_FUNC conv_string_to_utf8
333#else
334/* Python 1.6 and later versions */
335#define STRING_CONV_FUNC (self->returns_unicode \
336 ? conv_string_to_unicode : conv_string_to_utf8)
337#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000338
Fred Drake6f987622000-08-25 18:03:30 +0000339#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
340 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
341 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000342
Fred Drake6f987622000-08-25 18:03:30 +0000343#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
344 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
345 rc = PyInt_AsLong(rv);, rc, \
346 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000347
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000349VOID_HANDLER(StartElement,
350 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000351 ("(O&O&)", STRING_CONV_FUNC, name,
352 conv_atts_using_string, atts ) )
353#else
354/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000355VOID_HANDLER(StartElement,
356 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000357 ("(O&O&)", STRING_CONV_FUNC, name,
358 (self->returns_unicode
359 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000360 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000361#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000362
Fred Drake6f987622000-08-25 18:03:30 +0000363VOID_HANDLER(EndElement,
364 (void *userData, const XML_Char *name),
365 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000366
Fred Drake6f987622000-08-25 18:03:30 +0000367VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000368 (void *userData,
369 const XML_Char *target,
370 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000371 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000372
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000373#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000374VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000375 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000376 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000377#else
Fred Drake6f987622000-08-25 18:03:30 +0000378VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000379 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000380 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000381 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000382 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000383#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000384
Fred Drake6f987622000-08-25 18:03:30 +0000385VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000386 (void *userData,
387 const XML_Char *entityName,
388 const XML_Char *base,
389 const XML_Char *systemId,
390 const XML_Char *publicId,
391 const XML_Char *notationName),
392 ("(O&O&O&O&O&)",
393 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
394 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
395 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000396
Fred Drake6f987622000-08-25 18:03:30 +0000397VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000398 (void *userData,
399 const XML_Char *notationName,
400 const XML_Char *base,
401 const XML_Char *systemId,
402 const XML_Char *publicId),
403 ("(O&O&O&O&)",
404 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
405 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000406
Fred Drake6f987622000-08-25 18:03:30 +0000407VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000408 (void *userData,
409 const XML_Char *prefix,
410 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000411 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000412
Fred Drake6f987622000-08-25 18:03:30 +0000413VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000414 (void *userData,
415 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000416 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000417
Fred Drake6f987622000-08-25 18:03:30 +0000418VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000419 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000420 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000421
Fred Drake6f987622000-08-25 18:03:30 +0000422VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000423 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000424 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000425
Fred Drake6f987622000-08-25 18:03:30 +0000426VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000427 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000428 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000429
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000430#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000431VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000432 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000433 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000434
Fred Drake6f987622000-08-25 18:03:30 +0000435VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000436 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000437 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000438#else
Fred Drake6f987622000-08-25 18:03:30 +0000439VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000440 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000441 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000442 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000443 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000444
Fred Drake6f987622000-08-25 18:03:30 +0000445VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000446 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000447 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000448 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000449 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000450#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000451
Fred Drake6f987622000-08-25 18:03:30 +0000452INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000453 (void *userData),
454 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000455
Fred Drake6f987622000-08-25 18:03:30 +0000456RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000457 (XML_Parser parser,
458 const XML_Char *context,
459 const XML_Char *base,
460 const XML_Char *systemId,
461 const XML_Char *publicId),
462 int rc=0;,
463 ("(O&O&O&O&)",
464 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000465 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
466 rc = PyInt_AsLong(rv);, rc,
467 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000468
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000469/* XXX UnknownEncodingHandler */
470
471#if EXPAT_VERSION >= 0x010200
472
473VOID_HANDLER(StartDoctypeDecl,
474 (void *userData, const XML_Char *doctypeName),
475 ("(O&)", STRING_CONV_FUNC, doctypeName))
476
477VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
478
479VOID_HANDLER(ExternalParsedEntityDecl,
480 (void *userData, const XML_Char *entityName,
481 const XML_Char *base, const XML_Char *systemId,
482 const XML_Char *publicId),
483 ("(O&O&O&O&)", STRING_CONV_FUNC, entityName,
484 STRING_CONV_FUNC, base, STRING_CONV_FUNC, systemId,
485 STRING_CONV_FUNC, publicId))
486
487VOID_HANDLER(InternalParsedEntityDecl,
488 (void *userData, const XML_Char *entityName,
489 const XML_Char *replacementText, int replacementTextLength),
490 ("(O&O&i)", STRING_CONV_FUNC, entityName,
491 STRING_CONV_FUNC, replacementText, replacementTextLength))
492
493#endif /* EXPAT_VERSION >= 0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000494
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000495/* ---------------------------------------------------------------- */
496
497static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000498"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000499Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500
501static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000502xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000503{
Fred Drake0582df92000-07-12 04:49:00 +0000504 char *s;
505 int slen;
506 int isFinal = 0;
507 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000508
Fred Drake0582df92000-07-12 04:49:00 +0000509 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
510 return NULL;
511 rv = XML_Parse(self->itself, s, slen, isFinal);
512 if (PyErr_Occurred()) {
513 return NULL;
514 }
515 else if (rv == 0) {
516 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
517 XML_ErrorString(XML_GetErrorCode(self->itself)),
518 XML_GetErrorLineNumber(self->itself),
519 XML_GetErrorColumnNumber(self->itself));
520 return NULL;
521 }
522 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000523}
524
Fred Drakeca1f4262000-09-21 20:10:23 +0000525/* File reading copied from cPickle */
526
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000527#define BUF_SIZE 2048
528
Fred Drake0582df92000-07-12 04:49:00 +0000529static int
530readinst(char *buf, int buf_size, PyObject *meth)
531{
532 PyObject *arg = NULL;
533 PyObject *bytes = NULL;
534 PyObject *str = NULL;
535 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000536
Fred Drake676940b2000-09-22 15:21:31 +0000537 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000538 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000539
Fred Drakeca1f4262000-09-21 20:10:23 +0000540 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000541 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000542
Tim Peters954eef72000-09-22 06:01:11 +0000543 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000544
Fred Drakeca1f4262000-09-21 20:10:23 +0000545 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000546 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000547
Fred Drake0582df92000-07-12 04:49:00 +0000548 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000549 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000550 PyErr_Format(PyExc_TypeError,
551 "read() did not return a string object (type=%.400s)",
552 str->ob_type->tp_name);
553 goto finally;
554 }
555 len = PyString_GET_SIZE(str);
556 if (len > buf_size) {
557 PyErr_Format(PyExc_ValueError,
558 "read() returned too much data: "
559 "%i bytes requested, %i returned",
560 buf_size, len);
561 Py_DECREF(str);
562 goto finally;
563 }
564 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000565finally:
Fred Drake0582df92000-07-12 04:49:00 +0000566 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000567 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000568 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000569}
570
571static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000572"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000573Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000574
575static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000576xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000577{
Fred Drake0582df92000-07-12 04:49:00 +0000578 int rv = 1;
579 PyObject *f;
580 FILE *fp;
581 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000582
Fred Drake0582df92000-07-12 04:49:00 +0000583 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
584 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000585
Fred Drake0582df92000-07-12 04:49:00 +0000586 if (PyFile_Check(f)) {
587 fp = PyFile_AsFile(f);
588 }
589 else{
590 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000591 readmethod = PyObject_GetAttrString(f, "read");
592 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000593 PyErr_Clear();
594 PyErr_SetString(PyExc_TypeError,
595 "argument must have 'read' attribute");
596 return 0;
597 }
598 }
599 for (;;) {
600 int bytes_read;
601 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
602 if (buf == NULL)
603 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000604
Fred Drake0582df92000-07-12 04:49:00 +0000605 if (fp) {
606 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
607 if (bytes_read < 0) {
608 PyErr_SetFromErrno(PyExc_IOError);
609 return NULL;
610 }
611 }
612 else {
613 bytes_read = readinst(buf, BUF_SIZE, readmethod);
614 if (bytes_read < 0)
615 return NULL;
616 }
617 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
618 if (PyErr_Occurred())
619 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000620
Fred Drake0582df92000-07-12 04:49:00 +0000621 if (!rv || bytes_read == 0)
622 break;
623 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000624 if (rv == 0) {
625 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
626 XML_ErrorString(XML_GetErrorCode(self->itself)),
627 XML_GetErrorLineNumber(self->itself),
628 XML_GetErrorColumnNumber(self->itself));
629 return NULL;
630 }
Fred Drake0582df92000-07-12 04:49:00 +0000631 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000632}
633
634static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000635"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000636Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000637
638static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000639xmlparse_SetBase(xmlparseobject *self, PyObject *args)
640{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000641 char *base;
642
Fred Drake0582df92000-07-12 04:49:00 +0000643 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000644 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000645 if (!XML_SetBase(self->itself, base)) {
646 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000647 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000648 Py_INCREF(Py_None);
649 return Py_None;
650}
651
652static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000653"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000654Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000655
656static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000657xmlparse_GetBase(xmlparseobject *self, PyObject *args)
658{
659 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000660 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000661
Fred Drake0582df92000-07-12 04:49:00 +0000662 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000663}
664
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000665static char xmlparse_ExternalEntityParserCreate__doc__[] =
Fred Drake2d4ac202001-01-03 15:36:25 +0000666"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000667Create a parser for parsing an external entity based on the\n\
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000668information passed to the ExternalEntityRefHandler.";
669
670static PyObject *
671xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
672{
673 char *context;
674 char *encoding = NULL;
675 xmlparseobject *new_parser;
676 int i;
677
678 if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
679 &encoding)) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000680 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000681 }
682
683#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
684 new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
685 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000686 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000687
688 new_parser->returns_unicode = 0;
689#else
690 /* Code for versions 1.6 and later */
691 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
692 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000693 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000694
695 new_parser->returns_unicode = 1;
696#endif
697
698 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000699 encoding);
700 new_parser->handlers = 0;
701 PyObject_GC_Init(new_parser);
702
703 if (!new_parser->itself) {
704 Py_DECREF(new_parser);
705 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000706 }
707
708 XML_SetUserData(new_parser->itself, (void *)new_parser);
709
710 /* allocate and clear handlers first */
711 for(i = 0; handler_info[i].name != NULL; i++)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000712 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000713
714 new_parser->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000715 if (!new_parser->handlers) {
716 Py_DECREF(new_parser);
717 return PyErr_NoMemory();
718 }
719 clear_handlers(new_parser, 0);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000720
721 /* then copy handlers from self */
722 for (i = 0; handler_info[i].name != NULL; i++) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000723 if (self->handlers[i]) {
724 Py_INCREF(self->handlers[i]);
725 new_parser->handlers[i] = self->handlers[i];
726 handler_info[i].setter(new_parser->itself,
727 handler_info[i].handler);
728 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000729 }
730
Fred Drake28adf522000-09-24 22:07:59 +0000731 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000732}
733
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000734#if EXPAT_VERSION >= 0x010200
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000735
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000736static char xmlparse_SetParamEntityParsing__doc__[] =
737"SetParamEntityParsing(flag) -> success\n\
738Controls parsing of parameter entities (including the external DTD\n\
739subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
740XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
741XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
742was successful.";
743
744static PyObject*
745xmlparse_SetParamEntityParsing(PyObject *p, PyObject* args)
746{
747 int flag;
748 if (!PyArg_ParseTuple(args, "i", &flag))
749 return NULL;
750 flag = XML_SetParamEntityParsing(((xmlparseobject*)p)->itself,
751 flag);
752 return PyInt_FromLong(flag);
753}
754
755#endif /* EXPAT_VERSION >= 0x010200 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000756
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000757static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000758 {"Parse", (PyCFunction)xmlparse_Parse,
759 METH_VARARGS, xmlparse_Parse__doc__},
760 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
761 METH_VARARGS, xmlparse_ParseFile__doc__},
762 {"SetBase", (PyCFunction)xmlparse_SetBase,
763 METH_VARARGS, xmlparse_SetBase__doc__},
764 {"GetBase", (PyCFunction)xmlparse_GetBase,
765 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000766 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
767 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000768#if EXPAT_VERSION >= 0x010200
769 {"SetParamEntityParsing", xmlparse_SetParamEntityParsing,
770 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
771#endif
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000772 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000773};
774
775/* ---------- */
776
777
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000778#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
779
780/*
781 pyexpat international encoding support.
782 Make it as simple as possible.
783*/
784
Martin v. Löwis3af7cc02001-01-22 08:19:10 +0000785static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000786PyObject * template_string=NULL;
787
788static void
789init_template_buffer(void)
790{
791 int i;
792 for (i=0;i<256;i++) {
793 template_buffer[i]=i;
794 };
795 template_buffer[256]=0;
796};
797
798int
799PyUnknownEncodingHandler(void *encodingHandlerData,
800const XML_Char *name,
801XML_Encoding * info)
802{
803 PyUnicodeObject * _u_string=NULL;
804 int result=0;
805 int i;
806
807 _u_string=(PyUnicodeObject *) PyUnicode_Decode(template_buffer, 256, name, "replace"); // Yes, supports only 8bit encodings
808
809 if (_u_string==NULL) {
810 return result;
811 };
812
813 for (i=0; i<256; i++) {
814 Py_UNICODE c = _u_string->str[i] ; // Stupid to access directly, but fast
815 if (c==Py_UNICODE_REPLACEMENT_CHARACTER) {
816 info->map[i] = -1;
817 } else {
818 info->map[i] = c;
819 };
820 };
821
822 info->data = NULL;
823 info->convert = NULL;
824 info->release = NULL;
825 result=1;
826
827 Py_DECREF(_u_string);
828 return result;
829}
830
831#endif
832
833static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000834newxmlparseobject(char *encoding, char *namespace_separator)
835{
836 int i;
837 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000838
839#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000840 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
841 if (self == NULL)
842 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000843
Fred Drake0582df92000-07-12 04:49:00 +0000844 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000845#else
Fred Drake0582df92000-07-12 04:49:00 +0000846 /* Code for versions 1.6 and later */
847 self = PyObject_New(xmlparseobject, &Xmlparsetype);
848 if (self == NULL)
849 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000850
Fred Drake0582df92000-07-12 04:49:00 +0000851 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000852#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000853 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000854 if (namespace_separator) {
855 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
856 }
857 else{
858 self->itself = XML_ParserCreate(encoding);
859 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000860 PyObject_GC_Init(self);
Fred Drake0582df92000-07-12 04:49:00 +0000861 if (self->itself == NULL) {
862 PyErr_SetString(PyExc_RuntimeError,
863 "XML_ParserCreate failed");
864 Py_DECREF(self);
865 return NULL;
866 }
867 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000868#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
869#else
870 XML_SetUnknownEncodingHandler(self->itself, (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
871#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000872
Fred Drake0582df92000-07-12 04:49:00 +0000873 for(i = 0; handler_info[i].name != NULL; i++)
874 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000875
Fred Drake0582df92000-07-12 04:49:00 +0000876 self->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000877 if (!self->handlers){
878 Py_DECREF(self);
879 return PyErr_NoMemory();
880 }
881 clear_handlers(self, 0);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000882
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000883 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000884}
885
886
887static void
Fred Drake0582df92000-07-12 04:49:00 +0000888xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000889{
Fred Drake0582df92000-07-12 04:49:00 +0000890 int i;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000891 PyObject_GC_Fini(self);
Fred Drake0582df92000-07-12 04:49:00 +0000892 if (self->itself)
893 XML_ParserFree(self->itself);
894 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000895
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000896 if(self->handlers){
897 for (i=0; handler_info[i].name != NULL; i++) {
898 Py_XDECREF(self->handlers[i]);
899 }
900 free (self->handlers);
Fred Drake0582df92000-07-12 04:49:00 +0000901 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000902#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000903 /* Code for versions before 1.6 */
904 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000905#else
Fred Drake0582df92000-07-12 04:49:00 +0000906 /* Code for versions 1.6 and later */
907 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000908#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000909}
910
Fred Drake0582df92000-07-12 04:49:00 +0000911static int
912handlername2int(const char *name)
913{
914 int i;
915 for (i=0; handler_info[i].name != NULL; i++) {
916 if (strcmp(name, handler_info[i].name) == 0) {
917 return i;
918 }
919 }
920 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000921}
922
923static PyObject *
924xmlparse_getattr(xmlparseobject *self, char *name)
925{
Fred Drake0582df92000-07-12 04:49:00 +0000926 int handlernum;
927 if (strcmp(name, "ErrorCode") == 0)
928 return Py_BuildValue("l",
929 (long)XML_GetErrorCode(self->itself));
930 if (strcmp(name, "ErrorLineNumber") == 0)
931 return Py_BuildValue("l",
932 (long)XML_GetErrorLineNumber(self->itself));
933 if (strcmp(name, "ErrorColumnNumber") == 0)
934 return Py_BuildValue("l",
935 (long)XML_GetErrorColumnNumber(self->itself));
936 if (strcmp(name, "ErrorByteIndex") == 0)
937 return Py_BuildValue("l",
938 XML_GetErrorByteIndex(self->itself));
939 if (strcmp(name, "returns_unicode") == 0)
940 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000941
Fred Drake0582df92000-07-12 04:49:00 +0000942 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000943
Fred Drake0582df92000-07-12 04:49:00 +0000944 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
945 Py_INCREF(self->handlers[handlernum]);
946 return self->handlers[handlernum];
947 }
948 if (strcmp(name, "__members__") == 0) {
949 int i;
950 PyObject *rc = PyList_New(0);
Fred Drakee8f3ad52000-12-16 01:48:29 +0000951 for(i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +0000952 PyList_Append(rc,
953 PyString_FromString(handler_info[i].name));
954 }
955 PyList_Append(rc, PyString_FromString("ErrorCode"));
956 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
957 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
958 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Fred Drakee8f3ad52000-12-16 01:48:29 +0000959 PyList_Append(rc, PyString_FromString("returns_unicode"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000960
Fred Drake0582df92000-07-12 04:49:00 +0000961 return rc;
962 }
963 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000964}
965
Fred Drake6f987622000-08-25 18:03:30 +0000966static int
967sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000968{
969 int handlernum = handlername2int(name);
970 if (handlernum != -1) {
971 Py_INCREF(v);
972 Py_XDECREF(self->handlers[handlernum]);
973 self->handlers[handlernum] = v;
974 handler_info[handlernum].setter(self->itself,
975 handler_info[handlernum].handler);
976 return 1;
977 }
978 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000979}
980
981static int
Fred Drake6f987622000-08-25 18:03:30 +0000982xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000983{
Fred Drake6f987622000-08-25 18:03:30 +0000984 /* Set attribute 'name' to value 'v'. v==NULL means delete */
985 if (v==NULL) {
986 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
987 return -1;
988 }
989 if (strcmp(name, "returns_unicode") == 0) {
990 PyObject *intobj = PyNumber_Int(v);
991 if (intobj == NULL) return -1;
992 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000993#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000994 PyErr_SetString(PyExc_ValueError,
995 "Cannot return Unicode strings in Python 1.5");
996 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000997#else
Fred Drake6f987622000-08-25 18:03:30 +0000998 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000999#endif
Fred Drake6f987622000-08-25 18:03:30 +00001000 }
1001 else
1002 self->returns_unicode = 0;
1003 Py_DECREF(intobj);
1004 return 0;
1005 }
1006 if (sethandler(self, name, v)) {
1007 return 0;
1008 }
1009 PyErr_SetString(PyExc_AttributeError, name);
1010 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001011}
1012
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001013#ifdef WITH_CYCLE_GC
1014static int
1015xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1016{
1017 int i, err;
1018 for (i = 0; handler_info[i].name != NULL; i++) {
1019 if (!op->handlers[i])
1020 continue;
1021 err = visit(op->handlers[i], arg);
1022 if (err)
1023 return err;
1024 }
1025 return 0;
1026}
1027
1028static int
1029xmlparse_clear(xmlparseobject *op)
1030{
1031 clear_handlers(op, 1);
1032 return 0;
1033}
1034#endif
1035
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001036static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001037"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001038
1039static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001040 PyObject_HEAD_INIT(NULL)
1041 0, /*ob_size*/
1042 "xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001043 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001044 0, /*tp_itemsize*/
1045 /* methods */
1046 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1047 (printfunc)0, /*tp_print*/
1048 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1049 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1050 (cmpfunc)0, /*tp_compare*/
1051 (reprfunc)0, /*tp_repr*/
1052 0, /*tp_as_number*/
1053 0, /*tp_as_sequence*/
1054 0, /*tp_as_mapping*/
1055 (hashfunc)0, /*tp_hash*/
1056 (ternaryfunc)0, /*tp_call*/
1057 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001058 0, /* tp_getattro */
1059 0, /* tp_setattro */
1060 0, /* tp_as_buffer */
1061 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
1062 Xmlparsetype__doc__, /* Documentation string */
1063#ifdef WITH_CYCLE_GC
1064 (traverseproc)xmlparse_traverse, /* tp_traverse */
1065 (inquiry)xmlparse_clear /* tp_clear */
1066#else
1067 0, 0
1068#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001069};
1070
1071/* End of code for xmlparser objects */
1072/* -------------------------------------------------------- */
1073
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001074static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001075"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
1076Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001077
1078static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001079pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1080{
1081 char *encoding = NULL;
1082 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001083 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001084
Fred Drake0582df92000-07-12 04:49:00 +00001085 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001086 &encoding, &namespace_separator))
1087 return NULL;
Fred Drake4ba298c2000-10-29 04:57:53 +00001088 if (namespace_separator != NULL
1089 && strlen(namespace_separator) != 1) {
1090 PyErr_SetString(PyExc_ValueError,
1091 "namespace_separator must be one character,"
1092 " omitted, or None");
1093 return NULL;
1094 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001095 return newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001096}
1097
1098static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001099"ErrorString(errno) -> string\n\
1100Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001101
1102static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001103pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001104{
Fred Drake0582df92000-07-12 04:49:00 +00001105 long code = 0;
1106
1107 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1108 return NULL;
1109 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001110}
1111
1112/* List of methods defined in the module */
1113
1114static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001115 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1116 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1117 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1118 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001119
Fred Drake0582df92000-07-12 04:49:00 +00001120 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001121};
1122
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001123/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001124
1125static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +00001126"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001127
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001128/* Initialization function for the module */
1129
Fred Drake93adb692000-09-23 04:55:48 +00001130void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +00001131
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001132#if PY_VERSION_HEX < 0x20000F0
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001133
1134/* 1.5 compatibility: PyModule_AddObject */
1135static int
1136PyModule_AddObject(PyObject *m, char *name, PyObject *o)
1137{
1138 PyObject *dict;
1139 if (!PyModule_Check(m) || o == NULL)
1140 return -1;
1141 dict = PyModule_GetDict(m);
1142 if (dict == NULL)
1143 return -1;
1144 if (PyDict_SetItemString(dict, name, o))
1145 return -1;
1146 Py_DECREF(o);
1147 return 0;
1148}
1149
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001150int
1151PyModule_AddIntConstant(PyObject *m, char *name, long value)
1152{
1153 return PyModule_AddObject(m, name, PyInt_FromLong(value));
1154}
1155
Fred Drakea77254a2000-09-29 19:23:29 +00001156static int
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001157PyModule_AddStringConstant(PyObject *m, char *name, char *value)
1158{
1159 return PyModule_AddObject(m, name, PyString_FromString(value));
1160}
1161
1162#endif
1163
Fred Drake6f987622000-08-25 18:03:30 +00001164DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +00001165initpyexpat(void)
1166{
1167 PyObject *m, *d;
1168 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +00001169 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +00001170 PyObject *errors_module, *errors_dict;
1171 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001172
Fred Drake6f987622000-08-25 18:03:30 +00001173 if (errmod_name == NULL)
1174 return;
1175
Fred Drake0582df92000-07-12 04:49:00 +00001176 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001177
Fred Drake0582df92000-07-12 04:49:00 +00001178 /* Create the module and add the functions */
1179 m = Py_InitModule4("pyexpat", pyexpat_methods,
1180 pyexpat_module_documentation,
1181 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001182
Fred Drake0582df92000-07-12 04:49:00 +00001183 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +00001184 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +00001185 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
1186 NULL, NULL);
1187 PyModule_AddObject(m, "error", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001188 Py_INCREF(&Xmlparsetype);
1189 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001190
Fred Drake93adb692000-09-23 04:55:48 +00001191 PyModule_AddObject(m, "__version__",
1192 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Fred Drake738293d2000-12-21 17:25:07 +00001193#ifdef XML_MAJOR_VERSION
1194 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1195 (char *) XML_ExpatVersion());
1196 PyModule_AddObject(m, "version_info",
1197 Py_BuildValue("(iii)", XML_MAJOR_VERSION,
1198 XML_MINOR_VERSION, XML_MICRO_VERSION));
1199#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001200
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001201#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
1202#else
1203 init_template_buffer();
1204#endif
Fred Drake0582df92000-07-12 04:49:00 +00001205 /* XXX When Expat supports some way of figuring out how it was
1206 compiled, this should check and set native_encoding
1207 appropriately.
1208 */
Fred Drake93adb692000-09-23 04:55:48 +00001209 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001210
Fred Drake93adb692000-09-23 04:55:48 +00001211 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001212 errors_module = PyDict_GetItem(d, errmod_name);
1213 if (errors_module == NULL) {
1214 errors_module = PyModule_New("pyexpat.errors");
1215 if (errors_module != NULL) {
1216 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +00001217 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001218 /* gives away the reference to errors_module */
1219 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001220 }
1221 }
Fred Drake6f987622000-08-25 18:03:30 +00001222 Py_DECREF(errmod_name);
1223 if (errors_module == NULL)
1224 /* Don't code dump later! */
1225 return;
1226
Fred Drake0582df92000-07-12 04:49:00 +00001227 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001228
1229#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001230 PyModule_AddStringConstant(errors_module, #name, \
1231 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001232
Fred Drake0582df92000-07-12 04:49:00 +00001233 MYCONST(XML_ERROR_NO_MEMORY);
1234 MYCONST(XML_ERROR_SYNTAX);
1235 MYCONST(XML_ERROR_NO_ELEMENTS);
1236 MYCONST(XML_ERROR_INVALID_TOKEN);
1237 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1238 MYCONST(XML_ERROR_PARTIAL_CHAR);
1239 MYCONST(XML_ERROR_TAG_MISMATCH);
1240 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1241 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1242 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1243 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1244 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1245 MYCONST(XML_ERROR_ASYNC_ENTITY);
1246 MYCONST(XML_ERROR_BAD_CHAR_REF);
1247 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1248 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1249 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1250 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1251 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001252 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1253 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1254 MYCONST(XML_ERROR_NOT_STANDALONE);
1255
Fred Drake93adb692000-09-23 04:55:48 +00001256#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001257#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
1258
1259#if EXPAT_VERSION >= 0x010200
1260 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1261 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1262 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
1263#endif
1264
1265#undef MYCONST
1266
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001267}
1268
Fred Drake6f987622000-08-25 18:03:30 +00001269static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001270clear_handlers(xmlparseobject *self, int decref)
Fred Drake0582df92000-07-12 04:49:00 +00001271{
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001272 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001273
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001274 for (; handler_info[i].name!=NULL; i++) {
1275 if (decref){
1276 Py_XDECREF(self->handlers[i]);
1277 }
1278 self->handlers[i]=NULL;
1279 handler_info[i].setter(self->itself, NULL);
1280 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001281}
1282
Fred Drake6f987622000-08-25 18:03:30 +00001283typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001284
Fred Drake6f987622000-08-25 18:03:30 +00001285static void
1286pyxml_UpdatePairedHandlers(xmlparseobject *self,
1287 int startHandler,
1288 int endHandler,
1289 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +00001290{
1291 void *start_handler=NULL;
1292 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001293
Fred Drake0582df92000-07-12 04:49:00 +00001294 if (self->handlers[startHandler]
1295 && self->handlers[endHandler]!=Py_None) {
1296 start_handler=handler_info[startHandler].handler;
1297 }
1298 if (self->handlers[EndElement]
1299 && self->handlers[EndElement] !=Py_None) {
1300 end_handler=handler_info[endHandler].handler;
1301 }
1302 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001303}
1304
Fred Drake6f987622000-08-25 18:03:30 +00001305static void
1306pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001307{
1308 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1309 StartElement, EndElement,
1310 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001311}
1312
Fred Drake6f987622000-08-25 18:03:30 +00001313static void
1314pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001315{
1316 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1317 StartElement, EndElement,
1318 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001319}
1320
Fred Drake6f987622000-08-25 18:03:30 +00001321static void
1322pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001323{
1324 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1325 StartNamespaceDecl, EndNamespaceDecl,
1326 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001327}
1328
Fred Drake6f987622000-08-25 18:03:30 +00001329static void
1330pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001331{
1332 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1333 StartNamespaceDecl, EndNamespaceDecl,
1334 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001335}
1336
Fred Drake6f987622000-08-25 18:03:30 +00001337static void
1338pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001339{
1340 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1341 StartCdataSection, EndCdataSection,
1342 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001343}
1344
Fred Drake6f987622000-08-25 18:03:30 +00001345static void
1346pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001347{
1348 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1349 StartCdataSection, EndCdataSection,
1350 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001351}
1352
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001353#if EXPAT_VERSION >= 0x010200
1354
1355static void
1356pyxml_SetStartDoctypeDeclHandler(XML_Parser *parser, void *junk)
1357{
1358 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1359 StartDoctypeDecl, EndDoctypeDecl,
1360 (pairsetter)XML_SetDoctypeDeclHandler);
1361}
1362
1363static void
1364pyxml_SetEndDoctypeDeclHandler(XML_Parser *parser, void *junk)
1365{
1366 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1367 StartDoctypeDecl, EndDoctypeDecl,
1368 (pairsetter)XML_SetDoctypeDeclHandler);
1369}
1370
1371#endif
1372
Fred Drake0582df92000-07-12 04:49:00 +00001373statichere struct HandlerInfo handler_info[] = {
1374 {"StartElementHandler",
1375 pyxml_SetStartElementHandler,
1376 (xmlhandler)my_StartElementHandler},
1377 {"EndElementHandler",
1378 pyxml_SetEndElementHandler,
1379 (xmlhandler)my_EndElementHandler},
1380 {"ProcessingInstructionHandler",
1381 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1382 (xmlhandler)my_ProcessingInstructionHandler},
1383 {"CharacterDataHandler",
1384 (xmlhandlersetter)XML_SetCharacterDataHandler,
1385 (xmlhandler)my_CharacterDataHandler},
1386 {"UnparsedEntityDeclHandler",
1387 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1388 (xmlhandler)my_UnparsedEntityDeclHandler },
1389 {"NotationDeclHandler",
1390 (xmlhandlersetter)XML_SetNotationDeclHandler,
1391 (xmlhandler)my_NotationDeclHandler },
1392 {"StartNamespaceDeclHandler",
1393 pyxml_SetStartNamespaceDeclHandler,
1394 (xmlhandler)my_StartNamespaceDeclHandler },
1395 {"EndNamespaceDeclHandler",
1396 pyxml_SetEndNamespaceDeclHandler,
1397 (xmlhandler)my_EndNamespaceDeclHandler },
1398 {"CommentHandler",
1399 (xmlhandlersetter)XML_SetCommentHandler,
1400 (xmlhandler)my_CommentHandler},
1401 {"StartCdataSectionHandler",
1402 pyxml_SetStartCdataSection,
1403 (xmlhandler)my_StartCdataSectionHandler},
1404 {"EndCdataSectionHandler",
1405 pyxml_SetEndCdataSection,
1406 (xmlhandler)my_EndCdataSectionHandler},
1407 {"DefaultHandler",
1408 (xmlhandlersetter)XML_SetDefaultHandler,
1409 (xmlhandler)my_DefaultHandler},
1410 {"DefaultHandlerExpand",
1411 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1412 (xmlhandler)my_DefaultHandlerExpandHandler},
1413 {"NotStandaloneHandler",
1414 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1415 (xmlhandler)my_NotStandaloneHandler},
1416 {"ExternalEntityRefHandler",
1417 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1418 (xmlhandler)my_ExternalEntityRefHandler },
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001419#if EXPAT_VERSION >= 0x010200
1420 {"StartDoctypeDeclHandler",
1421 pyxml_SetStartDoctypeDeclHandler,
1422 (xmlhandler)my_StartDoctypeDeclHandler},
1423 {"EndDoctypeDeclHandler",
1424 pyxml_SetEndDoctypeDeclHandler,
1425 (xmlhandler)my_EndDoctypeDeclHandler},
1426 {"ExternalParsedEntityDeclHandler",
1427 (xmlhandlersetter)XML_SetExternalParsedEntityDeclHandler,
1428 (xmlhandler)my_ExternalParsedEntityDeclHandler},
1429 {"InternalParsedEntityDeclHandler",
1430 (xmlhandlersetter)XML_SetInternalParsedEntityDeclHandler,
1431 (xmlhandler)my_InternalParsedEntityDeclHandler},
1432#endif /* EXPAT_VERSION >=0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001433
Fred Drake0582df92000-07-12 04:49:00 +00001434 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001435};