blob: cbe0a6eea965db5260cfecb7130dbf49980aacdc [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 */
260 filename, /* filename */
261 name, /* name */
262 lineno, /* firstlineno */
263 code /* lnotab */
264 );
265 if (handler_info[slot].tb_code == NULL)
266 goto failed;
267 Py_DECREF(code);
268 Py_DECREF(nulltuple);
269 Py_DECREF(filename);
270 Py_DECREF(name);
271 }
272 return handler_info[slot].tb_code;
273 failed:
274 Py_XDECREF(code);
275 Py_XDECREF(name);
276 return NULL;
277}
278
279static PyObject*
280call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
281{
282 PyThreadState *tstate = PyThreadState_GET();
283 PyFrameObject *f;
284 PyObject *res;
285 if (c == NULL)
286 return NULL;
287 f = PyFrame_New(
288 tstate, /*back*/
289 c, /*code*/
290 tstate->frame->f_globals, /*globals*/
291 NULL); /*locals*/
292 if (f == NULL)
293 return NULL;
294 tstate->frame = f;
295 res = PyEval_CallObject(func, args);
296 if (res == NULL && tstate->curexc_traceback == NULL)
297 PyTraceBack_Here(f);
298 tstate->frame = f->f_back;
299 Py_DECREF(f);
300 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000301}
302
Fred Drake6f987622000-08-25 18:03:30 +0000303#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000304 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000305\
306static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000307 xmlparseobject *self = GETUSERDATA ; \
308 PyObject *args=NULL; \
309 PyObject *rv=NULL; \
310 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000311\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000312 if (self->handlers[NAME] \
313 && self->handlers[NAME] != Py_None) { \
314 args = Py_BuildValue PARAM_FORMAT ;\
315 if (!args) return RETURN; \
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000316 rv = call_with_frame(getcode(NAME,#NAME,__LINE__),self->handlers[NAME], args); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000317 Py_DECREF(args); \
318 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000319 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000320 return RETURN; \
321 } \
322 CONVERSION \
323 Py_DECREF(rv); \
324 } \
325 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000326}
327
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000328#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
329#define STRING_CONV_FUNC conv_string_to_utf8
330#else
331/* Python 1.6 and later versions */
332#define STRING_CONV_FUNC (self->returns_unicode \
333 ? conv_string_to_unicode : conv_string_to_utf8)
334#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000335
Fred Drake6f987622000-08-25 18:03:30 +0000336#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
337 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
338 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000339
Fred Drake6f987622000-08-25 18:03:30 +0000340#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
341 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
342 rc = PyInt_AsLong(rv);, rc, \
343 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000344
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000345#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000346VOID_HANDLER(StartElement,
347 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348 ("(O&O&)", STRING_CONV_FUNC, name,
349 conv_atts_using_string, atts ) )
350#else
351/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000352VOID_HANDLER(StartElement,
353 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000354 ("(O&O&)", STRING_CONV_FUNC, name,
355 (self->returns_unicode
356 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000357 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000358#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000359
Fred Drake6f987622000-08-25 18:03:30 +0000360VOID_HANDLER(EndElement,
361 (void *userData, const XML_Char *name),
362 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000363
Fred Drake6f987622000-08-25 18:03:30 +0000364VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000365 (void *userData,
366 const XML_Char *target,
367 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000368 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000369
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000370#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000371VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000372 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000373 ("(N)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000374#else
Fred Drake6f987622000-08-25 18:03:30 +0000375VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000376 (void *userData, const XML_Char *data, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000377 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000378 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000379 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000380#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000381
Fred Drake6f987622000-08-25 18:03:30 +0000382VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000383 (void *userData,
384 const XML_Char *entityName,
385 const XML_Char *base,
386 const XML_Char *systemId,
387 const XML_Char *publicId,
388 const XML_Char *notationName),
389 ("(O&O&O&O&O&)",
390 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
391 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
392 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000393
Fred Drake6f987622000-08-25 18:03:30 +0000394VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000395 (void *userData,
396 const XML_Char *notationName,
397 const XML_Char *base,
398 const XML_Char *systemId,
399 const XML_Char *publicId),
400 ("(O&O&O&O&)",
401 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
402 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000403
Fred Drake6f987622000-08-25 18:03:30 +0000404VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000405 (void *userData,
406 const XML_Char *prefix,
407 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000408 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000409
Fred Drake6f987622000-08-25 18:03:30 +0000410VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000411 (void *userData,
412 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000413 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000414
Fred Drake6f987622000-08-25 18:03:30 +0000415VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000416 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000417 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000418
Fred Drake6f987622000-08-25 18:03:30 +0000419VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000420 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000421 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000422
Fred Drake6f987622000-08-25 18:03:30 +0000423VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000424 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000425 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000426
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000427#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000428VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000429 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000430 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000431
Fred Drake6f987622000-08-25 18:03:30 +0000432VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000433 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000434 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000435#else
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)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000439 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000440 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000441
Fred Drake6f987622000-08-25 18:03:30 +0000442VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000443 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000444 ("(N)", (self->returns_unicode
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000445 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000446 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000447#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000448
Fred Drake6f987622000-08-25 18:03:30 +0000449INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000450 (void *userData),
451 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000452
Fred Drake6f987622000-08-25 18:03:30 +0000453RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000454 (XML_Parser parser,
455 const XML_Char *context,
456 const XML_Char *base,
457 const XML_Char *systemId,
458 const XML_Char *publicId),
459 int rc=0;,
460 ("(O&O&O&O&)",
461 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000462 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
463 rc = PyInt_AsLong(rv);, rc,
464 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000465
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000466/* XXX UnknownEncodingHandler */
467
468#if EXPAT_VERSION >= 0x010200
469
470VOID_HANDLER(StartDoctypeDecl,
471 (void *userData, const XML_Char *doctypeName),
472 ("(O&)", STRING_CONV_FUNC, doctypeName))
473
474VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
475
476VOID_HANDLER(ExternalParsedEntityDecl,
477 (void *userData, const XML_Char *entityName,
478 const XML_Char *base, const XML_Char *systemId,
479 const XML_Char *publicId),
480 ("(O&O&O&O&)", STRING_CONV_FUNC, entityName,
481 STRING_CONV_FUNC, base, STRING_CONV_FUNC, systemId,
482 STRING_CONV_FUNC, publicId))
483
484VOID_HANDLER(InternalParsedEntityDecl,
485 (void *userData, const XML_Char *entityName,
486 const XML_Char *replacementText, int replacementTextLength),
487 ("(O&O&i)", STRING_CONV_FUNC, entityName,
488 STRING_CONV_FUNC, replacementText, replacementTextLength))
489
490#endif /* EXPAT_VERSION >= 0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000491
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000492/* ---------------------------------------------------------------- */
493
494static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000495"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000496Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000497
498static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000499xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000500{
Fred Drake0582df92000-07-12 04:49:00 +0000501 char *s;
502 int slen;
503 int isFinal = 0;
504 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505
Fred Drake0582df92000-07-12 04:49:00 +0000506 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
507 return NULL;
508 rv = XML_Parse(self->itself, s, slen, isFinal);
509 if (PyErr_Occurred()) {
510 return NULL;
511 }
512 else if (rv == 0) {
513 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
514 XML_ErrorString(XML_GetErrorCode(self->itself)),
515 XML_GetErrorLineNumber(self->itself),
516 XML_GetErrorColumnNumber(self->itself));
517 return NULL;
518 }
519 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000520}
521
Fred Drakeca1f4262000-09-21 20:10:23 +0000522/* File reading copied from cPickle */
523
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000524#define BUF_SIZE 2048
525
Fred Drake0582df92000-07-12 04:49:00 +0000526static int
527readinst(char *buf, int buf_size, PyObject *meth)
528{
529 PyObject *arg = NULL;
530 PyObject *bytes = NULL;
531 PyObject *str = NULL;
532 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000533
Fred Drake676940b2000-09-22 15:21:31 +0000534 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000535 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000536
Fred Drakeca1f4262000-09-21 20:10:23 +0000537 if ((arg = PyTuple_New(1)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000538 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000539
Tim Peters954eef72000-09-22 06:01:11 +0000540 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000541
Fred Drakeca1f4262000-09-21 20:10:23 +0000542 if ((str = PyObject_CallObject(meth, arg)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000543 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000544
Fred Drake0582df92000-07-12 04:49:00 +0000545 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000546 if (!PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000547 PyErr_Format(PyExc_TypeError,
548 "read() did not return a string object (type=%.400s)",
549 str->ob_type->tp_name);
550 goto finally;
551 }
552 len = PyString_GET_SIZE(str);
553 if (len > buf_size) {
554 PyErr_Format(PyExc_ValueError,
555 "read() returned too much data: "
556 "%i bytes requested, %i returned",
557 buf_size, len);
558 Py_DECREF(str);
559 goto finally;
560 }
561 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000562finally:
Fred Drake0582df92000-07-12 04:49:00 +0000563 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000564 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000565 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000566}
567
568static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000569"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000570Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000571
572static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000573xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000574{
Fred Drake0582df92000-07-12 04:49:00 +0000575 int rv = 1;
576 PyObject *f;
577 FILE *fp;
578 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000579
Fred Drake0582df92000-07-12 04:49:00 +0000580 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
581 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000582
Fred Drake0582df92000-07-12 04:49:00 +0000583 if (PyFile_Check(f)) {
584 fp = PyFile_AsFile(f);
585 }
586 else{
587 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000588 readmethod = PyObject_GetAttrString(f, "read");
589 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000590 PyErr_Clear();
591 PyErr_SetString(PyExc_TypeError,
592 "argument must have 'read' attribute");
593 return 0;
594 }
595 }
596 for (;;) {
597 int bytes_read;
598 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
599 if (buf == NULL)
600 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000601
Fred Drake0582df92000-07-12 04:49:00 +0000602 if (fp) {
603 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
604 if (bytes_read < 0) {
605 PyErr_SetFromErrno(PyExc_IOError);
606 return NULL;
607 }
608 }
609 else {
610 bytes_read = readinst(buf, BUF_SIZE, readmethod);
611 if (bytes_read < 0)
612 return NULL;
613 }
614 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
615 if (PyErr_Occurred())
616 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000617
Fred Drake0582df92000-07-12 04:49:00 +0000618 if (!rv || bytes_read == 0)
619 break;
620 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000621 if (rv == 0) {
622 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
623 XML_ErrorString(XML_GetErrorCode(self->itself)),
624 XML_GetErrorLineNumber(self->itself),
625 XML_GetErrorColumnNumber(self->itself));
626 return NULL;
627 }
Fred Drake0582df92000-07-12 04:49:00 +0000628 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000629}
630
631static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000632"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000633Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000634
635static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000636xmlparse_SetBase(xmlparseobject *self, PyObject *args)
637{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000638 char *base;
639
Fred Drake0582df92000-07-12 04:49:00 +0000640 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000641 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000642 if (!XML_SetBase(self->itself, base)) {
643 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000644 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000645 Py_INCREF(Py_None);
646 return Py_None;
647}
648
649static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000650"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000651Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000652
653static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000654xmlparse_GetBase(xmlparseobject *self, PyObject *args)
655{
656 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000657 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000658
Fred Drake0582df92000-07-12 04:49:00 +0000659 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000660}
661
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000662static char xmlparse_ExternalEntityParserCreate__doc__[] =
Fred Drake2d4ac202001-01-03 15:36:25 +0000663"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000664Create a parser for parsing an external entity based on the\n\
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000665information passed to the ExternalEntityRefHandler.";
666
667static PyObject *
668xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
669{
670 char *context;
671 char *encoding = NULL;
672 xmlparseobject *new_parser;
673 int i;
674
675 if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
676 &encoding)) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000677 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000678 }
679
680#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
681 new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
682 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000683 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000684
685 new_parser->returns_unicode = 0;
686#else
687 /* Code for versions 1.6 and later */
688 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
689 if (new_parser == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000690 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000691
692 new_parser->returns_unicode = 1;
693#endif
694
695 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000696 encoding);
697 new_parser->handlers = 0;
698 PyObject_GC_Init(new_parser);
699
700 if (!new_parser->itself) {
701 Py_DECREF(new_parser);
702 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000703 }
704
705 XML_SetUserData(new_parser->itself, (void *)new_parser);
706
707 /* allocate and clear handlers first */
708 for(i = 0; handler_info[i].name != NULL; i++)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000709 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000710
711 new_parser->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000712 if (!new_parser->handlers) {
713 Py_DECREF(new_parser);
714 return PyErr_NoMemory();
715 }
716 clear_handlers(new_parser, 0);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000717
718 /* then copy handlers from self */
719 for (i = 0; handler_info[i].name != NULL; i++) {
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000720 if (self->handlers[i]) {
721 Py_INCREF(self->handlers[i]);
722 new_parser->handlers[i] = self->handlers[i];
723 handler_info[i].setter(new_parser->itself,
724 handler_info[i].handler);
725 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000726 }
727
Fred Drake28adf522000-09-24 22:07:59 +0000728 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000729}
730
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000731#if EXPAT_VERSION >= 0x010200
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000732
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000733static char xmlparse_SetParamEntityParsing__doc__[] =
734"SetParamEntityParsing(flag) -> success\n\
735Controls parsing of parameter entities (including the external DTD\n\
736subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
737XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
738XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
739was successful.";
740
741static PyObject*
742xmlparse_SetParamEntityParsing(PyObject *p, PyObject* args)
743{
744 int flag;
745 if (!PyArg_ParseTuple(args, "i", &flag))
746 return NULL;
747 flag = XML_SetParamEntityParsing(((xmlparseobject*)p)->itself,
748 flag);
749 return PyInt_FromLong(flag);
750}
751
752#endif /* EXPAT_VERSION >= 0x010200 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000753
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000754static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000755 {"Parse", (PyCFunction)xmlparse_Parse,
756 METH_VARARGS, xmlparse_Parse__doc__},
757 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
758 METH_VARARGS, xmlparse_ParseFile__doc__},
759 {"SetBase", (PyCFunction)xmlparse_SetBase,
760 METH_VARARGS, xmlparse_SetBase__doc__},
761 {"GetBase", (PyCFunction)xmlparse_GetBase,
762 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000763 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
764 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000765#if EXPAT_VERSION >= 0x010200
766 {"SetParamEntityParsing", xmlparse_SetParamEntityParsing,
767 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
768#endif
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000769 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000770};
771
772/* ---------- */
773
774
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000775#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
776
777/*
778 pyexpat international encoding support.
779 Make it as simple as possible.
780*/
781
Martin v. Löwis3af7cc02001-01-22 08:19:10 +0000782static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000783PyObject * template_string=NULL;
784
785static void
786init_template_buffer(void)
787{
788 int i;
789 for (i=0;i<256;i++) {
790 template_buffer[i]=i;
791 };
792 template_buffer[256]=0;
793};
794
795int
796PyUnknownEncodingHandler(void *encodingHandlerData,
797const XML_Char *name,
798XML_Encoding * info)
799{
800 PyUnicodeObject * _u_string=NULL;
801 int result=0;
802 int i;
803
804 _u_string=(PyUnicodeObject *) PyUnicode_Decode(template_buffer, 256, name, "replace"); // Yes, supports only 8bit encodings
805
806 if (_u_string==NULL) {
807 return result;
808 };
809
810 for (i=0; i<256; i++) {
811 Py_UNICODE c = _u_string->str[i] ; // Stupid to access directly, but fast
812 if (c==Py_UNICODE_REPLACEMENT_CHARACTER) {
813 info->map[i] = -1;
814 } else {
815 info->map[i] = c;
816 };
817 };
818
819 info->data = NULL;
820 info->convert = NULL;
821 info->release = NULL;
822 result=1;
823
824 Py_DECREF(_u_string);
825 return result;
826}
827
828#endif
829
830static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000831newxmlparseobject(char *encoding, char *namespace_separator)
832{
833 int i;
834 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000835
836#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000837 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
838 if (self == NULL)
839 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000840
Fred Drake0582df92000-07-12 04:49:00 +0000841 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000842#else
Fred Drake0582df92000-07-12 04:49:00 +0000843 /* Code for versions 1.6 and later */
844 self = PyObject_New(xmlparseobject, &Xmlparsetype);
845 if (self == NULL)
846 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000847
Fred Drake0582df92000-07-12 04:49:00 +0000848 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000849#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000850 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000851 if (namespace_separator) {
852 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
853 }
854 else{
855 self->itself = XML_ParserCreate(encoding);
856 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000857 PyObject_GC_Init(self);
Fred Drake0582df92000-07-12 04:49:00 +0000858 if (self->itself == NULL) {
859 PyErr_SetString(PyExc_RuntimeError,
860 "XML_ParserCreate failed");
861 Py_DECREF(self);
862 return NULL;
863 }
864 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000865#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
866#else
867 XML_SetUnknownEncodingHandler(self->itself, (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
868#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000869
Fred Drake0582df92000-07-12 04:49:00 +0000870 for(i = 0; handler_info[i].name != NULL; i++)
871 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000872
Fred Drake0582df92000-07-12 04:49:00 +0000873 self->handlers = malloc(sizeof(PyObject *)*i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000874 if (!self->handlers){
875 Py_DECREF(self);
876 return PyErr_NoMemory();
877 }
878 clear_handlers(self, 0);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000879
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000880 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000881}
882
883
884static void
Fred Drake0582df92000-07-12 04:49:00 +0000885xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000886{
Fred Drake0582df92000-07-12 04:49:00 +0000887 int i;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000888 PyObject_GC_Fini(self);
Fred Drake0582df92000-07-12 04:49:00 +0000889 if (self->itself)
890 XML_ParserFree(self->itself);
891 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000892
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000893 if(self->handlers){
894 for (i=0; handler_info[i].name != NULL; i++) {
895 Py_XDECREF(self->handlers[i]);
896 }
897 free (self->handlers);
Fred Drake0582df92000-07-12 04:49:00 +0000898 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000899#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000900 /* Code for versions before 1.6 */
901 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000902#else
Fred Drake0582df92000-07-12 04:49:00 +0000903 /* Code for versions 1.6 and later */
904 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000905#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000906}
907
Fred Drake0582df92000-07-12 04:49:00 +0000908static int
909handlername2int(const char *name)
910{
911 int i;
912 for (i=0; handler_info[i].name != NULL; i++) {
913 if (strcmp(name, handler_info[i].name) == 0) {
914 return i;
915 }
916 }
917 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000918}
919
920static PyObject *
921xmlparse_getattr(xmlparseobject *self, char *name)
922{
Fred Drake0582df92000-07-12 04:49:00 +0000923 int handlernum;
924 if (strcmp(name, "ErrorCode") == 0)
925 return Py_BuildValue("l",
926 (long)XML_GetErrorCode(self->itself));
927 if (strcmp(name, "ErrorLineNumber") == 0)
928 return Py_BuildValue("l",
929 (long)XML_GetErrorLineNumber(self->itself));
930 if (strcmp(name, "ErrorColumnNumber") == 0)
931 return Py_BuildValue("l",
932 (long)XML_GetErrorColumnNumber(self->itself));
933 if (strcmp(name, "ErrorByteIndex") == 0)
934 return Py_BuildValue("l",
935 XML_GetErrorByteIndex(self->itself));
936 if (strcmp(name, "returns_unicode") == 0)
937 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000938
Fred Drake0582df92000-07-12 04:49:00 +0000939 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000940
Fred Drake0582df92000-07-12 04:49:00 +0000941 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
942 Py_INCREF(self->handlers[handlernum]);
943 return self->handlers[handlernum];
944 }
945 if (strcmp(name, "__members__") == 0) {
946 int i;
947 PyObject *rc = PyList_New(0);
Fred Drakee8f3ad52000-12-16 01:48:29 +0000948 for(i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +0000949 PyList_Append(rc,
950 PyString_FromString(handler_info[i].name));
951 }
952 PyList_Append(rc, PyString_FromString("ErrorCode"));
953 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
954 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
955 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Fred Drakee8f3ad52000-12-16 01:48:29 +0000956 PyList_Append(rc, PyString_FromString("returns_unicode"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000957
Fred Drake0582df92000-07-12 04:49:00 +0000958 return rc;
959 }
960 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000961}
962
Fred Drake6f987622000-08-25 18:03:30 +0000963static int
964sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000965{
966 int handlernum = handlername2int(name);
967 if (handlernum != -1) {
968 Py_INCREF(v);
969 Py_XDECREF(self->handlers[handlernum]);
970 self->handlers[handlernum] = v;
971 handler_info[handlernum].setter(self->itself,
972 handler_info[handlernum].handler);
973 return 1;
974 }
975 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000976}
977
978static int
Fred Drake6f987622000-08-25 18:03:30 +0000979xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000980{
Fred Drake6f987622000-08-25 18:03:30 +0000981 /* Set attribute 'name' to value 'v'. v==NULL means delete */
982 if (v==NULL) {
983 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
984 return -1;
985 }
986 if (strcmp(name, "returns_unicode") == 0) {
987 PyObject *intobj = PyNumber_Int(v);
988 if (intobj == NULL) return -1;
989 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000990#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000991 PyErr_SetString(PyExc_ValueError,
992 "Cannot return Unicode strings in Python 1.5");
993 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000994#else
Fred Drake6f987622000-08-25 18:03:30 +0000995 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000996#endif
Fred Drake6f987622000-08-25 18:03:30 +0000997 }
998 else
999 self->returns_unicode = 0;
1000 Py_DECREF(intobj);
1001 return 0;
1002 }
1003 if (sethandler(self, name, v)) {
1004 return 0;
1005 }
1006 PyErr_SetString(PyExc_AttributeError, name);
1007 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001008}
1009
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001010#ifdef WITH_CYCLE_GC
1011static int
1012xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1013{
1014 int i, err;
1015 for (i = 0; handler_info[i].name != NULL; i++) {
1016 if (!op->handlers[i])
1017 continue;
1018 err = visit(op->handlers[i], arg);
1019 if (err)
1020 return err;
1021 }
1022 return 0;
1023}
1024
1025static int
1026xmlparse_clear(xmlparseobject *op)
1027{
1028 clear_handlers(op, 1);
1029 return 0;
1030}
1031#endif
1032
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001033static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001034"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001035
1036static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001037 PyObject_HEAD_INIT(NULL)
1038 0, /*ob_size*/
1039 "xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001040 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001041 0, /*tp_itemsize*/
1042 /* methods */
1043 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1044 (printfunc)0, /*tp_print*/
1045 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1046 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1047 (cmpfunc)0, /*tp_compare*/
1048 (reprfunc)0, /*tp_repr*/
1049 0, /*tp_as_number*/
1050 0, /*tp_as_sequence*/
1051 0, /*tp_as_mapping*/
1052 (hashfunc)0, /*tp_hash*/
1053 (ternaryfunc)0, /*tp_call*/
1054 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001055 0, /* tp_getattro */
1056 0, /* tp_setattro */
1057 0, /* tp_as_buffer */
1058 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
1059 Xmlparsetype__doc__, /* Documentation string */
1060#ifdef WITH_CYCLE_GC
1061 (traverseproc)xmlparse_traverse, /* tp_traverse */
1062 (inquiry)xmlparse_clear /* tp_clear */
1063#else
1064 0, 0
1065#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001066};
1067
1068/* End of code for xmlparser objects */
1069/* -------------------------------------------------------- */
1070
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001071static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001072"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
1073Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001074
1075static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001076pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1077{
1078 char *encoding = NULL;
1079 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001080 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001081
Fred Drake0582df92000-07-12 04:49:00 +00001082 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001083 &encoding, &namespace_separator))
1084 return NULL;
Fred Drake4ba298c2000-10-29 04:57:53 +00001085 if (namespace_separator != NULL
1086 && strlen(namespace_separator) != 1) {
1087 PyErr_SetString(PyExc_ValueError,
1088 "namespace_separator must be one character,"
1089 " omitted, or None");
1090 return NULL;
1091 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001092 return newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001093}
1094
1095static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +00001096"ErrorString(errno) -> string\n\
1097Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001098
1099static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001100pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001101{
Fred Drake0582df92000-07-12 04:49:00 +00001102 long code = 0;
1103
1104 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1105 return NULL;
1106 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001107}
1108
1109/* List of methods defined in the module */
1110
1111static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001112 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1113 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1114 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1115 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001116
Fred Drake0582df92000-07-12 04:49:00 +00001117 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001118};
1119
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001120/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001121
1122static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +00001123"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001124
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001125/* Initialization function for the module */
1126
Fred Drake93adb692000-09-23 04:55:48 +00001127void initpyexpat(void); /* avoid compiler warnings */
Fred Drake6f987622000-08-25 18:03:30 +00001128
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001129#if PY_VERSION_HEX < 0x20000F0
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001130
1131/* 1.5 compatibility: PyModule_AddObject */
1132static int
1133PyModule_AddObject(PyObject *m, char *name, PyObject *o)
1134{
1135 PyObject *dict;
1136 if (!PyModule_Check(m) || o == NULL)
1137 return -1;
1138 dict = PyModule_GetDict(m);
1139 if (dict == NULL)
1140 return -1;
1141 if (PyDict_SetItemString(dict, name, o))
1142 return -1;
1143 Py_DECREF(o);
1144 return 0;
1145}
1146
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001147int
1148PyModule_AddIntConstant(PyObject *m, char *name, long value)
1149{
1150 return PyModule_AddObject(m, name, PyInt_FromLong(value));
1151}
1152
Fred Drakea77254a2000-09-29 19:23:29 +00001153static int
Martin v. Löwisc0718eb2000-09-29 19:05:48 +00001154PyModule_AddStringConstant(PyObject *m, char *name, char *value)
1155{
1156 return PyModule_AddObject(m, name, PyString_FromString(value));
1157}
1158
1159#endif
1160
Fred Drake6f987622000-08-25 18:03:30 +00001161DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +00001162initpyexpat(void)
1163{
1164 PyObject *m, *d;
1165 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +00001166 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +00001167 PyObject *errors_module, *errors_dict;
1168 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001169
Fred Drake6f987622000-08-25 18:03:30 +00001170 if (errmod_name == NULL)
1171 return;
1172
Fred Drake0582df92000-07-12 04:49:00 +00001173 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001174
Fred Drake0582df92000-07-12 04:49:00 +00001175 /* Create the module and add the functions */
1176 m = Py_InitModule4("pyexpat", pyexpat_methods,
1177 pyexpat_module_documentation,
1178 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001179
Fred Drake0582df92000-07-12 04:49:00 +00001180 /* Add some symbolic constants to the module */
Fred Drakec23b5232000-08-24 21:57:43 +00001181 if (ErrorObject == NULL)
Fred Drake93adb692000-09-23 04:55:48 +00001182 ErrorObject = PyErr_NewException("xml.parsers.expat.error",
1183 NULL, NULL);
1184 PyModule_AddObject(m, "error", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001185 Py_INCREF(&Xmlparsetype);
1186 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001187
Fred Drake93adb692000-09-23 04:55:48 +00001188 PyModule_AddObject(m, "__version__",
1189 PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
Fred Drake738293d2000-12-21 17:25:07 +00001190#ifdef XML_MAJOR_VERSION
1191 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1192 (char *) XML_ExpatVersion());
1193 PyModule_AddObject(m, "version_info",
1194 Py_BuildValue("(iii)", XML_MAJOR_VERSION,
1195 XML_MINOR_VERSION, XML_MICRO_VERSION));
1196#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001197
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001198#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
1199#else
1200 init_template_buffer();
1201#endif
Fred Drake0582df92000-07-12 04:49:00 +00001202 /* XXX When Expat supports some way of figuring out how it was
1203 compiled, this should check and set native_encoding
1204 appropriately.
1205 */
Fred Drake93adb692000-09-23 04:55:48 +00001206 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001207
Fred Drake93adb692000-09-23 04:55:48 +00001208 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001209 errors_module = PyDict_GetItem(d, errmod_name);
1210 if (errors_module == NULL) {
1211 errors_module = PyModule_New("pyexpat.errors");
1212 if (errors_module != NULL) {
1213 sys_modules = PySys_GetObject("modules");
Fred Drake6f987622000-08-25 18:03:30 +00001214 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001215 /* gives away the reference to errors_module */
1216 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001217 }
1218 }
Fred Drake6f987622000-08-25 18:03:30 +00001219 Py_DECREF(errmod_name);
1220 if (errors_module == NULL)
1221 /* Don't code dump later! */
1222 return;
1223
Fred Drake0582df92000-07-12 04:49:00 +00001224 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001225
1226#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001227 PyModule_AddStringConstant(errors_module, #name, \
1228 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001229
Fred Drake0582df92000-07-12 04:49:00 +00001230 MYCONST(XML_ERROR_NO_MEMORY);
1231 MYCONST(XML_ERROR_SYNTAX);
1232 MYCONST(XML_ERROR_NO_ELEMENTS);
1233 MYCONST(XML_ERROR_INVALID_TOKEN);
1234 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1235 MYCONST(XML_ERROR_PARTIAL_CHAR);
1236 MYCONST(XML_ERROR_TAG_MISMATCH);
1237 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1238 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1239 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1240 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1241 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1242 MYCONST(XML_ERROR_ASYNC_ENTITY);
1243 MYCONST(XML_ERROR_BAD_CHAR_REF);
1244 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1245 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1246 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1247 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1248 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001249 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1250 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1251 MYCONST(XML_ERROR_NOT_STANDALONE);
1252
Fred Drake93adb692000-09-23 04:55:48 +00001253#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001254#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
1255
1256#if EXPAT_VERSION >= 0x010200
1257 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1258 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1259 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
1260#endif
1261
1262#undef MYCONST
1263
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001264}
1265
Fred Drake6f987622000-08-25 18:03:30 +00001266static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001267clear_handlers(xmlparseobject *self, int decref)
Fred Drake0582df92000-07-12 04:49:00 +00001268{
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001269 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001270
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001271 for (; handler_info[i].name!=NULL; i++) {
1272 if (decref){
1273 Py_XDECREF(self->handlers[i]);
1274 }
1275 self->handlers[i]=NULL;
1276 handler_info[i].setter(self->itself, NULL);
1277 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001278}
1279
Fred Drake6f987622000-08-25 18:03:30 +00001280typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001281
Fred Drake6f987622000-08-25 18:03:30 +00001282static void
1283pyxml_UpdatePairedHandlers(xmlparseobject *self,
1284 int startHandler,
1285 int endHandler,
1286 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +00001287{
1288 void *start_handler=NULL;
1289 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001290
Fred Drake0582df92000-07-12 04:49:00 +00001291 if (self->handlers[startHandler]
1292 && self->handlers[endHandler]!=Py_None) {
1293 start_handler=handler_info[startHandler].handler;
1294 }
1295 if (self->handlers[EndElement]
1296 && self->handlers[EndElement] !=Py_None) {
1297 end_handler=handler_info[endHandler].handler;
1298 }
1299 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001300}
1301
Fred Drake6f987622000-08-25 18:03:30 +00001302static void
1303pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001304{
1305 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1306 StartElement, EndElement,
1307 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001308}
1309
Fred Drake6f987622000-08-25 18:03:30 +00001310static void
1311pyxml_SetEndElementHandler(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_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001320{
1321 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1322 StartNamespaceDecl, EndNamespaceDecl,
1323 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001324}
1325
Fred Drake6f987622000-08-25 18:03:30 +00001326static void
1327pyxml_SetEndNamespaceDeclHandler(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_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001336{
1337 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1338 StartCdataSection, EndCdataSection,
1339 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001340}
1341
Fred Drake6f987622000-08-25 18:03:30 +00001342static void
1343pyxml_SetEndCdataSection(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
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001350#if EXPAT_VERSION >= 0x010200
1351
1352static void
1353pyxml_SetStartDoctypeDeclHandler(XML_Parser *parser, void *junk)
1354{
1355 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1356 StartDoctypeDecl, EndDoctypeDecl,
1357 (pairsetter)XML_SetDoctypeDeclHandler);
1358}
1359
1360static void
1361pyxml_SetEndDoctypeDeclHandler(XML_Parser *parser, void *junk)
1362{
1363 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1364 StartDoctypeDecl, EndDoctypeDecl,
1365 (pairsetter)XML_SetDoctypeDeclHandler);
1366}
1367
1368#endif
1369
Fred Drake0582df92000-07-12 04:49:00 +00001370statichere struct HandlerInfo handler_info[] = {
1371 {"StartElementHandler",
1372 pyxml_SetStartElementHandler,
1373 (xmlhandler)my_StartElementHandler},
1374 {"EndElementHandler",
1375 pyxml_SetEndElementHandler,
1376 (xmlhandler)my_EndElementHandler},
1377 {"ProcessingInstructionHandler",
1378 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1379 (xmlhandler)my_ProcessingInstructionHandler},
1380 {"CharacterDataHandler",
1381 (xmlhandlersetter)XML_SetCharacterDataHandler,
1382 (xmlhandler)my_CharacterDataHandler},
1383 {"UnparsedEntityDeclHandler",
1384 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1385 (xmlhandler)my_UnparsedEntityDeclHandler },
1386 {"NotationDeclHandler",
1387 (xmlhandlersetter)XML_SetNotationDeclHandler,
1388 (xmlhandler)my_NotationDeclHandler },
1389 {"StartNamespaceDeclHandler",
1390 pyxml_SetStartNamespaceDeclHandler,
1391 (xmlhandler)my_StartNamespaceDeclHandler },
1392 {"EndNamespaceDeclHandler",
1393 pyxml_SetEndNamespaceDeclHandler,
1394 (xmlhandler)my_EndNamespaceDeclHandler },
1395 {"CommentHandler",
1396 (xmlhandlersetter)XML_SetCommentHandler,
1397 (xmlhandler)my_CommentHandler},
1398 {"StartCdataSectionHandler",
1399 pyxml_SetStartCdataSection,
1400 (xmlhandler)my_StartCdataSectionHandler},
1401 {"EndCdataSectionHandler",
1402 pyxml_SetEndCdataSection,
1403 (xmlhandler)my_EndCdataSectionHandler},
1404 {"DefaultHandler",
1405 (xmlhandlersetter)XML_SetDefaultHandler,
1406 (xmlhandler)my_DefaultHandler},
1407 {"DefaultHandlerExpand",
1408 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1409 (xmlhandler)my_DefaultHandlerExpandHandler},
1410 {"NotStandaloneHandler",
1411 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1412 (xmlhandler)my_NotStandaloneHandler},
1413 {"ExternalEntityRefHandler",
1414 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1415 (xmlhandler)my_ExternalEntityRefHandler },
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001416#if EXPAT_VERSION >= 0x010200
1417 {"StartDoctypeDeclHandler",
1418 pyxml_SetStartDoctypeDeclHandler,
1419 (xmlhandler)my_StartDoctypeDeclHandler},
1420 {"EndDoctypeDeclHandler",
1421 pyxml_SetEndDoctypeDeclHandler,
1422 (xmlhandler)my_EndDoctypeDeclHandler},
1423 {"ExternalParsedEntityDeclHandler",
1424 (xmlhandlersetter)XML_SetExternalParsedEntityDeclHandler,
1425 (xmlhandler)my_ExternalParsedEntityDeclHandler},
1426 {"InternalParsedEntityDeclHandler",
1427 (xmlhandlersetter)XML_SetInternalParsedEntityDeclHandler,
1428 (xmlhandler)my_InternalParsedEntityDeclHandler},
1429#endif /* EXPAT_VERSION >=0x010200 */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001430
Fred Drake0582df92000-07-12 04:49:00 +00001431 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001432};