blob: 00e4e9e133d11689940c6a87f1a4617f46429c5a [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 */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000260#if PYTHON_API_VERSION >= 1010
Jeremy Hylton903f6542001-01-25 20:07:56 +0000261 nulltuple, /* freevars */
262 nulltuple, /* cellvars */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000263#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000264 filename, /* filename */
265 name, /* name */
266 lineno, /* firstlineno */
267 code /* lnotab */
268 );
269 if (handler_info[slot].tb_code == NULL)
270 goto failed;
271 Py_DECREF(code);
272 Py_DECREF(nulltuple);
273 Py_DECREF(filename);
274 Py_DECREF(name);
275 }
276 return handler_info[slot].tb_code;
277 failed:
278 Py_XDECREF(code);
279 Py_XDECREF(name);
280 return NULL;
281}
282
283static PyObject*
284call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
285{
286 PyThreadState *tstate = PyThreadState_GET();
287 PyFrameObject *f;
288 PyObject *res;
289 if (c == NULL)
290 return NULL;
291 f = PyFrame_New(
292 tstate, /*back*/
293 c, /*code*/
294 tstate->frame->f_globals, /*globals*/
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000295 NULL /*locals*/
296#if PYTHON_API_VERSION >= 1010
297 ,NULL /*closure*/
298#endif
299 );
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000300 if (f == NULL)
301 return NULL;
302 tstate->frame = f;
303 res = PyEval_CallObject(func, args);
304 if (res == NULL && tstate->curexc_traceback == NULL)
305 PyTraceBack_Here(f);
306 tstate->frame = f->f_back;
307 Py_DECREF(f);
308 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000309}
310
Fred Drake6f987622000-08-25 18:03:30 +0000311#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000312 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000313\
314static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000315 xmlparseobject *self = GETUSERDATA ; \
316 PyObject *args=NULL; \
317 PyObject *rv=NULL; \
318 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000319\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000320 if (self->handlers[NAME] \
321 && self->handlers[NAME] != Py_None) { \
322 args = Py_BuildValue PARAM_FORMAT ;\
323 if (!args) return RETURN; \
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000324 rv = call_with_frame(getcode(NAME,#NAME,__LINE__),self->handlers[NAME], args); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000325 Py_DECREF(args); \
326 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000327 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000328 return RETURN; \
329 } \
330 CONVERSION \
331 Py_DECREF(rv); \
332 } \
333 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000334}
335
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000336#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
337#define STRING_CONV_FUNC conv_string_to_utf8
338#else
339/* Python 1.6 and later versions */
340#define STRING_CONV_FUNC (self->returns_unicode \
341 ? conv_string_to_unicode : conv_string_to_utf8)
342#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000343
Fred Drake6f987622000-08-25 18:03:30 +0000344#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
345 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
346 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000347
Fred Drake6f987622000-08-25 18:03:30 +0000348#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
349 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
350 rc = PyInt_AsLong(rv);, rc, \
351 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000352
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000353#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000354VOID_HANDLER(StartElement,
355 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000356 ("(O&O&)", STRING_CONV_FUNC, name,
357 conv_atts_using_string, atts ) )
358#else
359/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000360VOID_HANDLER(StartElement,
361 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000362 ("(O&O&)", STRING_CONV_FUNC, name,
363 (self->returns_unicode
364 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000365 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000366#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000367
Fred Drake6f987622000-08-25 18:03:30 +0000368VOID_HANDLER(EndElement,
369 (void *userData, const XML_Char *name),
370 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000371
Fred Drake6f987622000-08-25 18:03:30 +0000372VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000373 (void *userData,
374 const XML_Char *target,
375 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000376 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000377
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000378#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000379VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000380 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000381 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000382#else
Fred Drake6f987622000-08-25 18:03:30 +0000383VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000384 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000385 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000386 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000387 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000388#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000389
Fred Drake6f987622000-08-25 18:03:30 +0000390VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000391 (void *userData,
392 const XML_Char *entityName,
393 const XML_Char *base,
394 const XML_Char *systemId,
395 const XML_Char *publicId,
396 const XML_Char *notationName),
397 ("(O&O&O&O&O&)",
398 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
399 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
400 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000401
Fred Drake6f987622000-08-25 18:03:30 +0000402VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000403 (void *userData,
404 const XML_Char *notationName,
405 const XML_Char *base,
406 const XML_Char *systemId,
407 const XML_Char *publicId),
408 ("(O&O&O&O&)",
409 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
410 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000411
Fred Drake6f987622000-08-25 18:03:30 +0000412VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000413 (void *userData,
414 const XML_Char *prefix,
415 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000416 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000417
Fred Drake6f987622000-08-25 18:03:30 +0000418VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000419 (void *userData,
420 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000421 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000422
Fred Drake6f987622000-08-25 18:03:30 +0000423VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000425 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000426
Fred Drake6f987622000-08-25 18:03:30 +0000427VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000428 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000429 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000430
Fred Drake6f987622000-08-25 18:03:30 +0000431VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000432 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000433 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000434
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000435#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000436VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000437 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000438 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000439
Fred Drake6f987622000-08-25 18:03:30 +0000440VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000441 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000442 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000443#else
Fred Drake6f987622000-08-25 18:03:30 +0000444VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000445 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000446 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000447 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000448 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000449
Fred Drake6f987622000-08-25 18:03:30 +0000450VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000451 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000452 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000453 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000454 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000455#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000456
Fred Drake6f987622000-08-25 18:03:30 +0000457INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000458 (void *userData),
459 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000460
Fred Drake6f987622000-08-25 18:03:30 +0000461RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000462 (XML_Parser parser,
463 const XML_Char *context,
464 const XML_Char *base,
465 const XML_Char *systemId,
466 const XML_Char *publicId),
467 int rc=0;,
468 ("(O&O&O&O&)",
469 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000470 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
471 rc = PyInt_AsLong(rv);, rc,
472 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000473
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000474/* XXX UnknownEncodingHandler */
475
476#if EXPAT_VERSION >= 0x010200
477
478VOID_HANDLER(StartDoctypeDecl,
479 (void *userData, const XML_Char *doctypeName),
480 ("(O&)", STRING_CONV_FUNC, doctypeName))
481
482VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
483
484VOID_HANDLER(ExternalParsedEntityDecl,
485 (void *userData, const XML_Char *entityName,
486 const XML_Char *base, const XML_Char *systemId,
487 const XML_Char *publicId),
488 ("(O&O&O&O&)", STRING_CONV_FUNC, entityName,
489 STRING_CONV_FUNC, base, STRING_CONV_FUNC, systemId,
490 STRING_CONV_FUNC, publicId))
491
492VOID_HANDLER(InternalParsedEntityDecl,
493 (void *userData, const XML_Char *entityName,
494 const XML_Char *replacementText, int replacementTextLength),
495 ("(O&O&i)", STRING_CONV_FUNC, entityName,
496 STRING_CONV_FUNC, replacementText, replacementTextLength))
497
498#endif /* EXPAT_VERSION >= 0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000499
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500/* ---------------------------------------------------------------- */
501
502static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000503"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000504Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505
506static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000507xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000508{
Fred Drake0582df92000-07-12 04:49:00 +0000509 char *s;
510 int slen;
511 int isFinal = 0;
512 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000513
Fred Drake0582df92000-07-12 04:49:00 +0000514 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
515 return NULL;
516 rv = XML_Parse(self->itself, s, slen, isFinal);
517 if (PyErr_Occurred()) {
518 return NULL;
519 }
520 else if (rv == 0) {
521 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
522 XML_ErrorString(XML_GetErrorCode(self->itself)),
523 XML_GetErrorLineNumber(self->itself),
524 XML_GetErrorColumnNumber(self->itself));
525 return NULL;
526 }
527 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000528}
529
Fred Drakeca1f4262000-09-21 20:10:23 +0000530/* File reading copied from cPickle */
531
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000532#define BUF_SIZE 2048
533
Fred Drake0582df92000-07-12 04:49:00 +0000534static int
535readinst(char *buf, int buf_size, PyObject *meth)
536{
537 PyObject *arg = NULL;
538 PyObject *bytes = NULL;
539 PyObject *str = NULL;
540 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000541
Fred Drake676940b2000-09-22 15:21:31 +0000542 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000543 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000544
Fred Drakeca1f4262000-09-21 20:10:23 +0000545 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000546 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000547
Tim Peters954eef72000-09-22 06:01:11 +0000548 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000549
Fred Drakeca1f4262000-09-21 20:10:23 +0000550 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000551 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000552
Fred Drake0582df92000-07-12 04:49:00 +0000553 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000554 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000555 PyErr_Format(PyExc_TypeError,
556 "read() did not return a string object (type=%.400s)",
557 str->ob_type->tp_name);
558 goto finally;
559 }
560 len = PyString_GET_SIZE(str);
561 if (len > buf_size) {
562 PyErr_Format(PyExc_ValueError,
563 "read() returned too much data: "
564 "%i bytes requested, %i returned",
565 buf_size, len);
566 Py_DECREF(str);
567 goto finally;
568 }
569 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000570finally:
Fred Drake0582df92000-07-12 04:49:00 +0000571 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000572 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000573 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000574}
575
576static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000577"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000578Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000579
580static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000581xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000582{
Fred Drake0582df92000-07-12 04:49:00 +0000583 int rv = 1;
584 PyObject *f;
585 FILE *fp;
586 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000587
Fred Drake0582df92000-07-12 04:49:00 +0000588 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
589 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000590
Fred Drake0582df92000-07-12 04:49:00 +0000591 if (PyFile_Check(f)) {
592 fp = PyFile_AsFile(f);
593 }
594 else{
595 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000596 readmethod = PyObject_GetAttrString(f, "read");
597 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000598 PyErr_Clear();
599 PyErr_SetString(PyExc_TypeError,
600 "argument must have 'read' attribute");
601 return 0;
602 }
603 }
604 for (;;) {
605 int bytes_read;
606 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
607 if (buf == NULL)
608 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000609
Fred Drake0582df92000-07-12 04:49:00 +0000610 if (fp) {
611 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
612 if (bytes_read < 0) {
613 PyErr_SetFromErrno(PyExc_IOError);
614 return NULL;
615 }
616 }
617 else {
618 bytes_read = readinst(buf, BUF_SIZE, readmethod);
619 if (bytes_read < 0)
620 return NULL;
621 }
622 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
623 if (PyErr_Occurred())
624 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000625
Fred Drake0582df92000-07-12 04:49:00 +0000626 if (!rv || bytes_read == 0)
627 break;
628 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000629 if (rv == 0) {
630 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
631 XML_ErrorString(XML_GetErrorCode(self->itself)),
632 XML_GetErrorLineNumber(self->itself),
633 XML_GetErrorColumnNumber(self->itself));
634 return NULL;
635 }
Fred Drake0582df92000-07-12 04:49:00 +0000636 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000637}
638
639static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000640"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000641Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000642
643static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000644xmlparse_SetBase(xmlparseobject *self, PyObject *args)
645{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000646 char *base;
647
Fred Drake0582df92000-07-12 04:49:00 +0000648 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000650 if (!XML_SetBase(self->itself, base)) {
651 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000652 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000653 Py_INCREF(Py_None);
654 return Py_None;
655}
656
657static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000658"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000659Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000660
661static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000662xmlparse_GetBase(xmlparseobject *self, PyObject *args)
663{
664 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000665 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000666
Fred Drake0582df92000-07-12 04:49:00 +0000667 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000668}
669
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000670static char xmlparse_ExternalEntityParserCreate__doc__[] =
Fred Drake2d4ac202001-01-03 15:36:25 +0000671"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000672Create a parser for parsing an external entity based on the\n\
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000673information passed to the ExternalEntityRefHandler.";
674
675static PyObject *
676xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
677{
678 char *context;
679 char *encoding = NULL;
680 xmlparseobject *new_parser;
681 int i;
682
683 if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
684 &encoding)) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000685 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000686 }
687
688#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
689 new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
690 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000691 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000692
693 new_parser->returns_unicode = 0;
694#else
695 /* Code for versions 1.6 and later */
696 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
697 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000698 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000699
700 new_parser->returns_unicode = 1;
701#endif
702
703 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000704 encoding);
705 new_parser->handlers = 0;
706 PyObject_GC_Init(new_parser);
707
708 if (!new_parser->itself) {
709 Py_DECREF(new_parser);
710 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000711 }
712
713 XML_SetUserData(new_parser->itself, (void *)new_parser);
714
715 /* allocate and clear handlers first */
716 for(i = 0; handler_info[i].name != NULL; i++)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000717 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000718
719 new_parser->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000720 if (!new_parser->handlers) {
721 Py_DECREF(new_parser);
722 return PyErr_NoMemory();
723 }
724 clear_handlers(new_parser, 0);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000725
726 /* then copy handlers from self */
727 for (i = 0; handler_info[i].name != NULL; i++) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000728 if (self->handlers[i]) {
729 Py_INCREF(self->handlers[i]);
730 new_parser->handlers[i] = self->handlers[i];
731 handler_info[i].setter(new_parser->itself,
732 handler_info[i].handler);
733 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000734 }
735
Fred Drake28adf522000-09-24 22:07:59 +0000736 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000737}
738
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000739#if EXPAT_VERSION >= 0x010200
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000740
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000741static char xmlparse_SetParamEntityParsing__doc__[] =
742"SetParamEntityParsing(flag) -> success\n\
743Controls parsing of parameter entities (including the external DTD\n\
744subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
745XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
746XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
747was successful.";
748
749static PyObject*
750xmlparse_SetParamEntityParsing(PyObject *p, PyObject* args)
751{
752 int flag;
753 if (!PyArg_ParseTuple(args, "i", &flag))
754 return NULL;
755 flag = XML_SetParamEntityParsing(((xmlparseobject*)p)->itself,
756 flag);
757 return PyInt_FromLong(flag);
758}
759
760#endif /* EXPAT_VERSION >= 0x010200 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000761
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000762static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000763 {"Parse", (PyCFunction)xmlparse_Parse,
764 METH_VARARGS, xmlparse_Parse__doc__},
765 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
766 METH_VARARGS, xmlparse_ParseFile__doc__},
767 {"SetBase", (PyCFunction)xmlparse_SetBase,
768 METH_VARARGS, xmlparse_SetBase__doc__},
769 {"GetBase", (PyCFunction)xmlparse_GetBase,
770 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000771 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
772 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000773#if EXPAT_VERSION >= 0x010200
774 {"SetParamEntityParsing", xmlparse_SetParamEntityParsing,
775 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
776#endif
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000777 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000778};
779
780/* ---------- */
781
782
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000783#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
784
785/*
786 pyexpat international encoding support.
787 Make it as simple as possible.
788*/
789
Martin v. Löwis3af7cc02001-01-22 08:19:10 +0000790static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000791PyObject * template_string=NULL;
792
793static void
794init_template_buffer(void)
795{
796 int i;
797 for (i=0;i<256;i++) {
798 template_buffer[i]=i;
799 };
800 template_buffer[256]=0;
801};
802
803int
804PyUnknownEncodingHandler(void *encodingHandlerData,
805const XML_Char *name,
806XML_Encoding * info)
807{
808 PyUnicodeObject * _u_string=NULL;
809 int result=0;
810 int i;
811
812 _u_string=(PyUnicodeObject *) PyUnicode_Decode(template_buffer, 256, name, "replace"); // Yes, supports only 8bit encodings
813
814 if (_u_string==NULL) {
815 return result;
816 };
817
818 for (i=0; i<256; i++) {
819 Py_UNICODE c = _u_string->str[i] ; // Stupid to access directly, but fast
820 if (c==Py_UNICODE_REPLACEMENT_CHARACTER) {
821 info->map[i] = -1;
822 } else {
823 info->map[i] = c;
824 };
825 };
826
827 info->data = NULL;
828 info->convert = NULL;
829 info->release = NULL;
830 result=1;
831
832 Py_DECREF(_u_string);
833 return result;
834}
835
836#endif
837
838static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000839newxmlparseobject(char *encoding, char *namespace_separator)
840{
841 int i;
842 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000843
844#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000845 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
846 if (self == NULL)
847 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000848
Fred Drake0582df92000-07-12 04:49:00 +0000849 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000850#else
Fred Drake0582df92000-07-12 04:49:00 +0000851 /* Code for versions 1.6 and later */
852 self = PyObject_New(xmlparseobject, &Xmlparsetype);
853 if (self == NULL)
854 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000855
Fred Drake0582df92000-07-12 04:49:00 +0000856 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000857#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000858 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000859 if (namespace_separator) {
860 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
861 }
862 else{
863 self->itself = XML_ParserCreate(encoding);
864 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000865 PyObject_GC_Init(self);
Fred Drake0582df92000-07-12 04:49:00 +0000866 if (self->itself == NULL) {
867 PyErr_SetString(PyExc_RuntimeError,
868 "XML_ParserCreate failed");
869 Py_DECREF(self);
870 return NULL;
871 }
872 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000873#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
874#else
875 XML_SetUnknownEncodingHandler(self->itself, (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
876#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000877
Fred Drake0582df92000-07-12 04:49:00 +0000878 for(i = 0; handler_info[i].name != NULL; i++)
879 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880
Fred Drake0582df92000-07-12 04:49:00 +0000881 self->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000882 if (!self->handlers){
883 Py_DECREF(self);
884 return PyErr_NoMemory();
885 }
886 clear_handlers(self, 0);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000887
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000888 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000889}
890
891
892static void
Fred Drake0582df92000-07-12 04:49:00 +0000893xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000894{
Fred Drake0582df92000-07-12 04:49:00 +0000895 int i;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000896 PyObject_GC_Fini(self);
Fred Drake0582df92000-07-12 04:49:00 +0000897 if (self->itself)
898 XML_ParserFree(self->itself);
899 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000900
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000901 if(self->handlers){
902 for (i=0; handler_info[i].name != NULL; i++) {
903 Py_XDECREF(self->handlers[i]);
904 }
905 free (self->handlers);
Fred Drake0582df92000-07-12 04:49:00 +0000906 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000907#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000908 /* Code for versions before 1.6 */
909 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000910#else
Fred Drake0582df92000-07-12 04:49:00 +0000911 /* Code for versions 1.6 and later */
912 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000913#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000914}
915
Fred Drake0582df92000-07-12 04:49:00 +0000916static int
917handlername2int(const char *name)
918{
919 int i;
920 for (i=0; handler_info[i].name != NULL; i++) {
921 if (strcmp(name, handler_info[i].name) == 0) {
922 return i;
923 }
924 }
925 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000926}
927
928static PyObject *
929xmlparse_getattr(xmlparseobject *self, char *name)
930{
Fred Drake0582df92000-07-12 04:49:00 +0000931 int handlernum;
932 if (strcmp(name, "ErrorCode") == 0)
933 return Py_BuildValue("l",
934 (long)XML_GetErrorCode(self->itself));
935 if (strcmp(name, "ErrorLineNumber") == 0)
936 return Py_BuildValue("l",
937 (long)XML_GetErrorLineNumber(self->itself));
938 if (strcmp(name, "ErrorColumnNumber") == 0)
939 return Py_BuildValue("l",
940 (long)XML_GetErrorColumnNumber(self->itself));
941 if (strcmp(name, "ErrorByteIndex") == 0)
942 return Py_BuildValue("l",
943 XML_GetErrorByteIndex(self->itself));
944 if (strcmp(name, "returns_unicode") == 0)
945 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000946
Fred Drake0582df92000-07-12 04:49:00 +0000947 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000948
Fred Drake0582df92000-07-12 04:49:00 +0000949 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
950 Py_INCREF(self->handlers[handlernum]);
951 return self->handlers[handlernum];
952 }
953 if (strcmp(name, "__members__") == 0) {
954 int i;
955 PyObject *rc = PyList_New(0);
Fred Drakee8f3ad52000-12-16 01:48:29 +0000956 for(i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +0000957 PyList_Append(rc,
958 PyString_FromString(handler_info[i].name));
959 }
960 PyList_Append(rc, PyString_FromString("ErrorCode"));
961 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
962 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
963 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Fred Drakee8f3ad52000-12-16 01:48:29 +0000964 PyList_Append(rc, PyString_FromString("returns_unicode"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000965
Fred Drake0582df92000-07-12 04:49:00 +0000966 return rc;
967 }
968 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000969}
970
Fred Drake6f987622000-08-25 18:03:30 +0000971static int
972sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000973{
974 int handlernum = handlername2int(name);
975 if (handlernum != -1) {
976 Py_INCREF(v);
977 Py_XDECREF(self->handlers[handlernum]);
978 self->handlers[handlernum] = v;
979 handler_info[handlernum].setter(self->itself,
980 handler_info[handlernum].handler);
981 return 1;
982 }
983 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000984}
985
986static int
Fred Drake6f987622000-08-25 18:03:30 +0000987xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000988{
Fred Drake6f987622000-08-25 18:03:30 +0000989 /* Set attribute 'name' to value 'v'. v==NULL means delete */
990 if (v==NULL) {
991 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
992 return -1;
993 }
994 if (strcmp(name, "returns_unicode") == 0) {
995 PyObject *intobj = PyNumber_Int(v);
996 if (intobj == NULL) return -1;
997 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000998#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000999 PyErr_SetString(PyExc_ValueError,
1000 "Cannot return Unicode strings in Python 1.5");
1001 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001002#else
Fred Drake6f987622000-08-25 18:03:30 +00001003 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001004#endif
Fred Drake6f987622000-08-25 18:03:30 +00001005 }
1006 else
1007 self->returns_unicode = 0;
1008 Py_DECREF(intobj);
1009 return 0;
1010 }
1011 if (sethandler(self, name, v)) {
1012 return 0;
1013 }
1014 PyErr_SetString(PyExc_AttributeError, name);
1015 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001016}
1017
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001018#ifdef WITH_CYCLE_GC
1019static int
1020xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1021{
1022 int i, err;
1023 for (i = 0; handler_info[i].name != NULL; i++) {
1024 if (!op->handlers[i])
1025 continue;
1026 err = visit(op->handlers[i], arg);
1027 if (err)
1028 return err;
1029 }
1030 return 0;
1031}
1032
1033static int
1034xmlparse_clear(xmlparseobject *op)
1035{
1036 clear_handlers(op, 1);
1037 return 0;
1038}
1039#endif
1040
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001041static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001042"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001043
1044static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001045 PyObject_HEAD_INIT(NULL)
1046 0, /*ob_size*/
1047 "xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001048 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001049 0, /*tp_itemsize*/
1050 /* methods */
1051 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1052 (printfunc)0, /*tp_print*/
1053 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1054 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1055 (cmpfunc)0, /*tp_compare*/
1056 (reprfunc)0, /*tp_repr*/
1057 0, /*tp_as_number*/
1058 0, /*tp_as_sequence*/
1059 0, /*tp_as_mapping*/
1060 (hashfunc)0, /*tp_hash*/
1061 (ternaryfunc)0, /*tp_call*/
1062 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001063 0, /* tp_getattro */
1064 0, /* tp_setattro */
1065 0, /* tp_as_buffer */
1066 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
1067 Xmlparsetype__doc__, /* Documentation string */
1068#ifdef WITH_CYCLE_GC
1069 (traverseproc)xmlparse_traverse, /* tp_traverse */
1070 (inquiry)xmlparse_clear /* tp_clear */
1071#else
1072 0, 0
1073#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001074};
1075
1076/* End of code for xmlparser objects */
1077/* -------------------------------------------------------- */
1078
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001079static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001080"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
1081Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001082
1083static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001084pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1085{
1086 char *encoding = NULL;
1087 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001088 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001089
Fred Drake0582df92000-07-12 04:49:00 +00001090 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001091 &encoding, &namespace_separator))
1092 return NULL;
Fred Drake4ba298c2000-10-29 04:57:53 +00001093 if (namespace_separator != NULL
1094 && strlen(namespace_separator) != 1) {
1095 PyErr_SetString(PyExc_ValueError,
1096 "namespace_separator must be one character,"
1097 " omitted, or None");
1098 return NULL;
1099 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001100 return newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001101}
1102
1103static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001104"ErrorString(errno) -> string\n\
1105Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001106
1107static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001108pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001109{
Fred Drake0582df92000-07-12 04:49:00 +00001110 long code = 0;
1111
1112 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1113 return NULL;
1114 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001115}
1116
1117/* List of methods defined in the module */
1118
1119static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001120 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1121 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1122 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1123 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001124
Fred Drake0582df92000-07-12 04:49:00 +00001125 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001126};
1127
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001128/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001129
1130static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +00001131"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001132
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001133/* Initialization function for the module */
1134
Fred Drake93adb692000-09-23 04:55:48 +00001135void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +00001136
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001137#if PY_VERSION_HEX < 0x20000F0
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001138
1139/* 1.5 compatibility: PyModule_AddObject */
1140static int
1141PyModule_AddObject(PyObject *m, char *name, PyObject *o)
1142{
1143 PyObject *dict;
1144 if (!PyModule_Check(m) || o == NULL)
1145 return -1;
1146 dict = PyModule_GetDict(m);
1147 if (dict == NULL)
1148 return -1;
1149 if (PyDict_SetItemString(dict, name, o))
1150 return -1;
1151 Py_DECREF(o);
1152 return 0;
1153}
1154
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001155int
1156PyModule_AddIntConstant(PyObject *m, char *name, long value)
1157{
1158 return PyModule_AddObject(m, name, PyInt_FromLong(value));
1159}
1160
Fred Drakea77254a2000-09-29 19:23:29 +00001161static int
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001162PyModule_AddStringConstant(PyObject *m, char *name, char *value)
1163{
1164 return PyModule_AddObject(m, name, PyString_FromString(value));
1165}
1166
1167#endif
1168
Fred Drake6f987622000-08-25 18:03:30 +00001169DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +00001170initpyexpat(void)
1171{
1172 PyObject *m, *d;
1173 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +00001174 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +00001175 PyObject *errors_module, *errors_dict;
1176 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001177
Fred Drake6f987622000-08-25 18:03:30 +00001178 if (errmod_name == NULL)
1179 return;
1180
Fred Drake0582df92000-07-12 04:49:00 +00001181 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001182
Fred Drake0582df92000-07-12 04:49:00 +00001183 /* Create the module and add the functions */
1184 m = Py_InitModule4("pyexpat", pyexpat_methods,
1185 pyexpat_module_documentation,
1186 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001187
Fred Drake0582df92000-07-12 04:49:00 +00001188 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +00001189 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +00001190 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
1191 NULL, NULL);
1192 PyModule_AddObject(m, "error", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001193 Py_INCREF(&Xmlparsetype);
1194 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001195
Fred Drake93adb692000-09-23 04:55:48 +00001196 PyModule_AddObject(m, "__version__",
1197 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Fred Drake738293d2000-12-21 17:25:07 +00001198#ifdef XML_MAJOR_VERSION
1199 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1200 (char *) XML_ExpatVersion());
1201 PyModule_AddObject(m, "version_info",
1202 Py_BuildValue("(iii)", XML_MAJOR_VERSION,
1203 XML_MINOR_VERSION, XML_MICRO_VERSION));
1204#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001205
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001206#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
1207#else
1208 init_template_buffer();
1209#endif
Fred Drake0582df92000-07-12 04:49:00 +00001210 /* XXX When Expat supports some way of figuring out how it was
1211 compiled, this should check and set native_encoding
1212 appropriately.
1213 */
Fred Drake93adb692000-09-23 04:55:48 +00001214 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001215
Fred Drake93adb692000-09-23 04:55:48 +00001216 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001217 errors_module = PyDict_GetItem(d, errmod_name);
1218 if (errors_module == NULL) {
1219 errors_module = PyModule_New("pyexpat.errors");
1220 if (errors_module != NULL) {
1221 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +00001222 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001223 /* gives away the reference to errors_module */
1224 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001225 }
1226 }
Fred Drake6f987622000-08-25 18:03:30 +00001227 Py_DECREF(errmod_name);
1228 if (errors_module == NULL)
1229 /* Don't code dump later! */
1230 return;
1231
Fred Drake0582df92000-07-12 04:49:00 +00001232 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001233
1234#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001235 PyModule_AddStringConstant(errors_module, #name, \
1236 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001237
Fred Drake0582df92000-07-12 04:49:00 +00001238 MYCONST(XML_ERROR_NO_MEMORY);
1239 MYCONST(XML_ERROR_SYNTAX);
1240 MYCONST(XML_ERROR_NO_ELEMENTS);
1241 MYCONST(XML_ERROR_INVALID_TOKEN);
1242 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1243 MYCONST(XML_ERROR_PARTIAL_CHAR);
1244 MYCONST(XML_ERROR_TAG_MISMATCH);
1245 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1246 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1247 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1248 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1249 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1250 MYCONST(XML_ERROR_ASYNC_ENTITY);
1251 MYCONST(XML_ERROR_BAD_CHAR_REF);
1252 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1253 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1254 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1255 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1256 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001257 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1258 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1259 MYCONST(XML_ERROR_NOT_STANDALONE);
1260
Fred Drake93adb692000-09-23 04:55:48 +00001261#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001262#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
1263
1264#if EXPAT_VERSION >= 0x010200
1265 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1266 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1267 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
1268#endif
1269
1270#undef MYCONST
1271
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001272}
1273
Fred Drake6f987622000-08-25 18:03:30 +00001274static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001275clear_handlers(xmlparseobject *self, int decref)
Fred Drake0582df92000-07-12 04:49:00 +00001276{
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001277 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001278
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001279 for (; handler_info[i].name!=NULL; i++) {
1280 if (decref){
1281 Py_XDECREF(self->handlers[i]);
1282 }
1283 self->handlers[i]=NULL;
1284 handler_info[i].setter(self->itself, NULL);
1285 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001286}
1287
Fred Drake6f987622000-08-25 18:03:30 +00001288typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001289
Fred Drake6f987622000-08-25 18:03:30 +00001290static void
1291pyxml_UpdatePairedHandlers(xmlparseobject *self,
1292 int startHandler,
1293 int endHandler,
1294 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +00001295{
1296 void *start_handler=NULL;
1297 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001298
Fred Drake0582df92000-07-12 04:49:00 +00001299 if (self->handlers[startHandler]
1300 && self->handlers[endHandler]!=Py_None) {
1301 start_handler=handler_info[startHandler].handler;
1302 }
1303 if (self->handlers[EndElement]
1304 && self->handlers[EndElement] !=Py_None) {
1305 end_handler=handler_info[endHandler].handler;
1306 }
1307 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001308}
1309
Fred Drake6f987622000-08-25 18:03:30 +00001310static void
1311pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001312{
1313 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1314 StartElement, EndElement,
1315 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001316}
1317
Fred Drake6f987622000-08-25 18:03:30 +00001318static void
1319pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001320{
1321 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1322 StartElement, EndElement,
1323 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001324}
1325
Fred Drake6f987622000-08-25 18:03:30 +00001326static void
1327pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001328{
1329 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1330 StartNamespaceDecl, EndNamespaceDecl,
1331 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001332}
1333
Fred Drake6f987622000-08-25 18:03:30 +00001334static void
1335pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001336{
1337 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1338 StartNamespaceDecl, EndNamespaceDecl,
1339 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001340}
1341
Fred Drake6f987622000-08-25 18:03:30 +00001342static void
1343pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001344{
1345 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1346 StartCdataSection, EndCdataSection,
1347 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001348}
1349
Fred Drake6f987622000-08-25 18:03:30 +00001350static void
1351pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001352{
1353 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1354 StartCdataSection, EndCdataSection,
1355 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001356}
1357
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001358#if EXPAT_VERSION >= 0x010200
1359
1360static void
1361pyxml_SetStartDoctypeDeclHandler(XML_Parser *parser, void *junk)
1362{
1363 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1364 StartDoctypeDecl, EndDoctypeDecl,
1365 (pairsetter)XML_SetDoctypeDeclHandler);
1366}
1367
1368static void
1369pyxml_SetEndDoctypeDeclHandler(XML_Parser *parser, void *junk)
1370{
1371 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1372 StartDoctypeDecl, EndDoctypeDecl,
1373 (pairsetter)XML_SetDoctypeDeclHandler);
1374}
1375
1376#endif
1377
Fred Drake0582df92000-07-12 04:49:00 +00001378statichere struct HandlerInfo handler_info[] = {
1379 {"StartElementHandler",
1380 pyxml_SetStartElementHandler,
1381 (xmlhandler)my_StartElementHandler},
1382 {"EndElementHandler",
1383 pyxml_SetEndElementHandler,
1384 (xmlhandler)my_EndElementHandler},
1385 {"ProcessingInstructionHandler",
1386 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1387 (xmlhandler)my_ProcessingInstructionHandler},
1388 {"CharacterDataHandler",
1389 (xmlhandlersetter)XML_SetCharacterDataHandler,
1390 (xmlhandler)my_CharacterDataHandler},
1391 {"UnparsedEntityDeclHandler",
1392 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1393 (xmlhandler)my_UnparsedEntityDeclHandler },
1394 {"NotationDeclHandler",
1395 (xmlhandlersetter)XML_SetNotationDeclHandler,
1396 (xmlhandler)my_NotationDeclHandler },
1397 {"StartNamespaceDeclHandler",
1398 pyxml_SetStartNamespaceDeclHandler,
1399 (xmlhandler)my_StartNamespaceDeclHandler },
1400 {"EndNamespaceDeclHandler",
1401 pyxml_SetEndNamespaceDeclHandler,
1402 (xmlhandler)my_EndNamespaceDeclHandler },
1403 {"CommentHandler",
1404 (xmlhandlersetter)XML_SetCommentHandler,
1405 (xmlhandler)my_CommentHandler},
1406 {"StartCdataSectionHandler",
1407 pyxml_SetStartCdataSection,
1408 (xmlhandler)my_StartCdataSectionHandler},
1409 {"EndCdataSectionHandler",
1410 pyxml_SetEndCdataSection,
1411 (xmlhandler)my_EndCdataSectionHandler},
1412 {"DefaultHandler",
1413 (xmlhandlersetter)XML_SetDefaultHandler,
1414 (xmlhandler)my_DefaultHandler},
1415 {"DefaultHandlerExpand",
1416 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1417 (xmlhandler)my_DefaultHandlerExpandHandler},
1418 {"NotStandaloneHandler",
1419 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1420 (xmlhandler)my_NotStandaloneHandler},
1421 {"ExternalEntityRefHandler",
1422 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1423 (xmlhandler)my_ExternalEntityRefHandler },
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001424#if EXPAT_VERSION >= 0x010200
1425 {"StartDoctypeDeclHandler",
1426 pyxml_SetStartDoctypeDeclHandler,
1427 (xmlhandler)my_StartDoctypeDeclHandler},
1428 {"EndDoctypeDeclHandler",
1429 pyxml_SetEndDoctypeDeclHandler,
1430 (xmlhandler)my_EndDoctypeDeclHandler},
1431 {"ExternalParsedEntityDeclHandler",
1432 (xmlhandlersetter)XML_SetExternalParsedEntityDeclHandler,
1433 (xmlhandler)my_ExternalParsedEntityDeclHandler},
1434 {"InternalParsedEntityDeclHandler",
1435 (xmlhandlersetter)XML_SetInternalParsedEntityDeclHandler,
1436 (xmlhandler)my_InternalParsedEntityDeclHandler},
1437#endif /* EXPAT_VERSION >=0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001438
Fred Drake0582df92000-07-12 04:49:00 +00001439 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001440};