blob: 8a10babde3bc6e7c81c7834ddfe491d70d484f82 [file] [log] [blame]
Martin v. Löwis7090ed12001-09-19 10:37:50 +00001#include "Python.h"
Fred Drake4113b132001-03-24 19:58:26 +00002#include <ctype.h>
3
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00004#include "frameobject.h"
Fred Drakea77254a2000-09-29 19:23:29 +00005#include "expat.h"
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00006
Fredrik Lundhc3345042005-12-13 19:49:55 +00007#include "pyexpat.h"
8
Martin v. Löwisc847f402003-01-21 11:09:21 +00009#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
10
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000011#ifndef PyDoc_STRVAR
Martin v. Löwis069dde22003-01-21 10:58:18 +000012
13/*
14 * fdrake says:
15 * Don't change the PyDoc_STR macro definition to (str), because
16 * '''the parentheses cause compile failures
17 * ("non-constant static initializer" or something like that)
18 * on some platforms (Irix?)'''
19 */
Fred Drakef57b22a2002-09-02 15:54:06 +000020#define PyDoc_STR(str) str
Fred Drake7c75bf22002-07-01 14:02:31 +000021#define PyDoc_VAR(name) static char name[]
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000022#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000023#endif
24
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000025#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
26/* In Python 2.0 and 2.1, disabling Unicode was not possible. */
Martin v. Löwis339d0f72001-08-17 18:39:25 +000027#define Py_USING_UNICODE
Jeremy Hylton9263f572003-06-27 16:13:17 +000028#else
29#define FIX_TRACE
Martin v. Löwis339d0f72001-08-17 18:39:25 +000030#endif
31
Fred Drake0582df92000-07-12 04:49:00 +000032enum HandlerTypes {
33 StartElement,
34 EndElement,
35 ProcessingInstruction,
36 CharacterData,
37 UnparsedEntityDecl,
38 NotationDecl,
39 StartNamespaceDecl,
40 EndNamespaceDecl,
41 Comment,
42 StartCdataSection,
43 EndCdataSection,
44 Default,
45 DefaultHandlerExpand,
46 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000047 ExternalEntityRef,
48 StartDoctypeDecl,
49 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000050 EntityDecl,
51 XmlDecl,
52 ElementDecl,
53 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000054#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000055 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000056#endif
Fred Drake85d835f2001-02-08 15:39:08 +000057 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000058};
59
60static PyObject *ErrorObject;
61
62/* ----------------------------------------------------- */
63
64/* Declarations for objects of type xmlparser */
65
66typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000067 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000068
Fred Drake0582df92000-07-12 04:49:00 +000069 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000070 int returns_unicode; /* True if Unicode strings are returned;
71 if false, UTF-8 strings are returned */
72 int ordered_attributes; /* Return attributes as a list. */
73 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000074 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000075 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000076 XML_Char *buffer; /* Buffer used when accumulating characters */
77 /* NULL if not enabled */
78 int buffer_size; /* Size of buffer, in XML_Char units */
79 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000080 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000081 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000082} xmlparseobject;
83
Fred Drake2a3d7db2002-06-28 22:56:48 +000084#define CHARACTER_DATA_BUFFER_SIZE 8192
85
Jeremy Hylton938ace62002-07-17 16:30:39 +000086static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000087
Fred Drake117ac852002-09-24 16:24:54 +000088typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000089typedef void* xmlhandler;
90
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000091struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000092 const char *name;
93 xmlhandlersetter setter;
94 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000095 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000096 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000097};
98
Jeremy Hylton938ace62002-07-17 16:30:39 +000099static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000100
Fred Drakebd6101c2001-02-14 18:29:45 +0000101/* Set an integer attribute on the error object; return true on success,
102 * false on an exception.
103 */
104static int
105set_error_attr(PyObject *err, char *name, int value)
106{
107 PyObject *v = PyInt_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +0000108
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000109 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
110 Py_XDECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000111 return 0;
112 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000113 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000114 return 1;
115}
116
117/* Build and set an Expat exception, including positioning
118 * information. Always returns NULL.
119 */
Fred Drake85d835f2001-02-08 15:39:08 +0000120static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000121set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000122{
123 PyObject *err;
124 char buffer[256];
125 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000126 int lineno = XML_GetErrorLineNumber(parser);
127 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000128
Martin v. Löwis6b2cf0e2002-06-30 06:03:35 +0000129 /* There is no risk of overflowing this buffer, since
130 even for 64-bit integers, there is sufficient space. */
131 sprintf(buffer, "%.200s: line %i, column %i",
Fred Drakebd6101c2001-02-14 18:29:45 +0000132 XML_ErrorString(code), lineno, column);
Fred Drake85d835f2001-02-08 15:39:08 +0000133 err = PyObject_CallFunction(ErrorObject, "s", buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000134 if ( err != NULL
135 && set_error_attr(err, "code", code)
136 && set_error_attr(err, "offset", column)
137 && set_error_attr(err, "lineno", lineno)) {
138 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000139 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000140 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000141 return NULL;
142}
143
Fred Drake71b63ff2002-06-28 22:29:01 +0000144static int
145have_handler(xmlparseobject *self, int type)
146{
147 PyObject *handler = self->handlers[type];
148 return handler != NULL;
149}
150
151static PyObject *
152get_handler_name(struct HandlerInfo *hinfo)
153{
154 PyObject *name = hinfo->nameobj;
155 if (name == NULL) {
156 name = PyString_FromString(hinfo->name);
157 hinfo->nameobj = name;
158 }
159 Py_XINCREF(name);
160 return name;
161}
162
Fred Drake85d835f2001-02-08 15:39:08 +0000163
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000164#ifdef Py_USING_UNICODE
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000165/* Convert a string of XML_Chars into a Unicode string.
166 Returns None if str is a null pointer. */
167
Fred Drake0582df92000-07-12 04:49:00 +0000168static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000169conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000170{
Fred Drake71b63ff2002-06-28 22:29:01 +0000171 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000172 and hence in UTF-8. */
173 /* UTF-8 from Expat, Unicode desired */
174 if (str == NULL) {
175 Py_INCREF(Py_None);
176 return Py_None;
177 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000178 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000179}
180
Fred Drake0582df92000-07-12 04:49:00 +0000181static PyObject *
182conv_string_len_to_unicode(const XML_Char *str, int len)
183{
Fred Drake71b63ff2002-06-28 22:29:01 +0000184 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000185 and hence in UTF-8. */
186 /* UTF-8 from Expat, Unicode desired */
187 if (str == NULL) {
188 Py_INCREF(Py_None);
189 return Py_None;
190 }
Fred Drake6f987622000-08-25 18:03:30 +0000191 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000192}
193#endif
194
195/* Convert a string of XML_Chars into an 8-bit Python string.
196 Returns None if str is a null pointer. */
197
Fred Drake6f987622000-08-25 18:03:30 +0000198static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000199conv_string_to_utf8(const XML_Char *str)
Fred Drake6f987622000-08-25 18:03:30 +0000200{
Fred Drake71b63ff2002-06-28 22:29:01 +0000201 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000202 and hence in UTF-8. */
203 /* UTF-8 from Expat, UTF-8 desired */
204 if (str == NULL) {
205 Py_INCREF(Py_None);
206 return Py_None;
207 }
Fred Drakeb91a36b2002-06-27 19:40:48 +0000208 return PyString_FromString(str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000209}
210
Fred Drake6f987622000-08-25 18:03:30 +0000211static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +0000212conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000213{
Fred Drake71b63ff2002-06-28 22:29:01 +0000214 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000215 and hence in UTF-8. */
216 /* UTF-8 from Expat, UTF-8 desired */
217 if (str == NULL) {
218 Py_INCREF(Py_None);
219 return Py_None;
220 }
221 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000222}
223
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000224/* Callback routines */
225
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000226static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000227
Martin v. Löwis069dde22003-01-21 10:58:18 +0000228/* This handler is used when an error has been detected, in the hope
229 that actual parsing can be terminated early. This will only help
230 if an external entity reference is encountered. */
231static int
232error_external_entity_ref_handler(XML_Parser parser,
233 const XML_Char *context,
234 const XML_Char *base,
235 const XML_Char *systemId,
236 const XML_Char *publicId)
237{
238 return 0;
239}
240
Fred Drake6f987622000-08-25 18:03:30 +0000241static void
242flag_error(xmlparseobject *self)
243{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000244 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000245 XML_SetExternalEntityRefHandler(self->itself,
246 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000247}
248
249static PyCodeObject*
250getcode(enum HandlerTypes slot, char* func_name, int lineno)
251{
Fred Drakebd6101c2001-02-14 18:29:45 +0000252 PyObject *code = NULL;
253 PyObject *name = NULL;
254 PyObject *nulltuple = NULL;
255 PyObject *filename = NULL;
256
257 if (handler_info[slot].tb_code == NULL) {
258 code = PyString_FromString("");
259 if (code == NULL)
260 goto failed;
261 name = PyString_FromString(func_name);
262 if (name == NULL)
263 goto failed;
264 nulltuple = PyTuple_New(0);
265 if (nulltuple == NULL)
266 goto failed;
267 filename = PyString_FromString(__FILE__);
268 handler_info[slot].tb_code =
269 PyCode_New(0, /* argcount */
270 0, /* nlocals */
271 0, /* stacksize */
272 0, /* flags */
273 code, /* code */
274 nulltuple, /* consts */
275 nulltuple, /* names */
276 nulltuple, /* varnames */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000277#if PYTHON_API_VERSION >= 1010
Fred Drakebd6101c2001-02-14 18:29:45 +0000278 nulltuple, /* freevars */
279 nulltuple, /* cellvars */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000280#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000281 filename, /* filename */
282 name, /* name */
283 lineno, /* firstlineno */
284 code /* lnotab */
285 );
286 if (handler_info[slot].tb_code == NULL)
287 goto failed;
288 Py_DECREF(code);
289 Py_DECREF(nulltuple);
290 Py_DECREF(filename);
291 Py_DECREF(name);
292 }
293 return handler_info[slot].tb_code;
294 failed:
295 Py_XDECREF(code);
296 Py_XDECREF(name);
297 return NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000298}
299
Jeremy Hylton9263f572003-06-27 16:13:17 +0000300#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000301static int
302trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
303{
304 int result = 0;
305 if (!tstate->use_tracing || tstate->tracing)
306 return 0;
307 if (tstate->c_profilefunc != NULL) {
308 tstate->tracing++;
309 result = tstate->c_profilefunc(tstate->c_profileobj,
310 f, code , val);
311 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
312 || (tstate->c_profilefunc != NULL));
313 tstate->tracing--;
314 if (result)
315 return result;
316 }
317 if (tstate->c_tracefunc != NULL) {
318 tstate->tracing++;
319 result = tstate->c_tracefunc(tstate->c_traceobj,
320 f, code , val);
321 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
322 || (tstate->c_profilefunc != NULL));
323 tstate->tracing--;
324 }
325 return result;
326}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000327
328static int
329trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
330{
331 PyObject *type, *value, *traceback, *arg;
332 int err;
333
334 if (tstate->c_tracefunc == NULL)
335 return 0;
336
337 PyErr_Fetch(&type, &value, &traceback);
338 if (value == NULL) {
339 value = Py_None;
340 Py_INCREF(value);
341 }
Martin v. Löwis9171f022004-10-13 19:50:11 +0000342#if PY_VERSION_HEX < 0x02040000
343 arg = Py_BuildValue("(OOO)", type, value, traceback);
344#else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000345 arg = PyTuple_Pack(3, type, value, traceback);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000346#endif
Jeremy Hylton9263f572003-06-27 16:13:17 +0000347 if (arg == NULL) {
348 PyErr_Restore(type, value, traceback);
349 return 0;
350 }
351 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
352 Py_DECREF(arg);
353 if (err == 0)
354 PyErr_Restore(type, value, traceback);
355 else {
356 Py_XDECREF(type);
357 Py_XDECREF(value);
358 Py_XDECREF(traceback);
359 }
360 return err;
361}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000362#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000363
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000364static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000365call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
366 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000367{
Fred Drakebd6101c2001-02-14 18:29:45 +0000368 PyThreadState *tstate = PyThreadState_GET();
369 PyFrameObject *f;
370 PyObject *res;
371
372 if (c == NULL)
373 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000374
Jeremy Hylton9263f572003-06-27 16:13:17 +0000375 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000376 if (f == NULL)
377 return NULL;
378 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000379#ifdef FIX_TRACE
380 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000381 return NULL;
382 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000383#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000384 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000385 if (res == NULL) {
386 if (tstate->curexc_traceback == NULL)
387 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000388 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000389#ifdef FIX_TRACE
390 if (trace_frame_exc(tstate, f) < 0) {
391 return NULL;
392 }
393 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000394 else {
Jeremy Hylton9263f572003-06-27 16:13:17 +0000395 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000396 Py_XDECREF(res);
397 res = NULL;
398 }
399 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000400#else
401 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000402#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000403 tstate->frame = f->f_back;
404 Py_DECREF(f);
405 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000406}
407
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000408#ifndef Py_USING_UNICODE
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000409#define STRING_CONV_FUNC conv_string_to_utf8
410#else
Martin v. Löwis069dde22003-01-21 10:58:18 +0000411/* Python 2.0 and later versions, when built with Unicode support */
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000412#define STRING_CONV_FUNC (self->returns_unicode \
413 ? conv_string_to_unicode : conv_string_to_utf8)
414#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000415
Fred Drakeb91a36b2002-06-27 19:40:48 +0000416static PyObject*
417string_intern(xmlparseobject *self, const char* str)
418{
419 PyObject *result = STRING_CONV_FUNC(str);
420 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000421 /* result can be NULL if the unicode conversion failed. */
422 if (!result)
423 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000424 if (!self->intern)
425 return result;
426 value = PyDict_GetItem(self->intern, result);
427 if (!value) {
428 if (PyDict_SetItem(self->intern, result, result) == 0)
429 return result;
430 else
431 return NULL;
432 }
433 Py_INCREF(value);
434 Py_DECREF(result);
435 return value;
436}
437
Fred Drake2a3d7db2002-06-28 22:56:48 +0000438/* Return 0 on success, -1 on exception.
439 * flag_error() will be called before return if needed.
440 */
441static int
442call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
443{
444 PyObject *args;
445 PyObject *temp;
446
447 args = PyTuple_New(1);
448 if (args == NULL)
449 return -1;
450#ifdef Py_USING_UNICODE
451 temp = (self->returns_unicode
452 ? conv_string_len_to_unicode(buffer, len)
453 : conv_string_len_to_utf8(buffer, len));
454#else
455 temp = conv_string_len_to_utf8(buffer, len);
456#endif
457 if (temp == NULL) {
458 Py_DECREF(args);
459 flag_error(self);
460 return -1;
461 }
462 PyTuple_SET_ITEM(args, 0, temp);
463 /* temp is now a borrowed reference; consider it unused. */
464 self->in_callback = 1;
465 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000466 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000467 /* temp is an owned reference again, or NULL */
468 self->in_callback = 0;
469 Py_DECREF(args);
470 if (temp == NULL) {
471 flag_error(self);
472 return -1;
473 }
474 Py_DECREF(temp);
475 return 0;
476}
477
478static int
479flush_character_buffer(xmlparseobject *self)
480{
481 int rc;
482 if (self->buffer == NULL || self->buffer_used == 0)
483 return 0;
484 rc = call_character_handler(self, self->buffer, self->buffer_used);
485 self->buffer_used = 0;
486 return rc;
487}
488
489static void
490my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
491{
492 xmlparseobject *self = (xmlparseobject *) userData;
493 if (self->buffer == NULL)
494 call_character_handler(self, data, len);
495 else {
496 if ((self->buffer_used + len) > self->buffer_size) {
497 if (flush_character_buffer(self) < 0)
498 return;
499 /* handler might have changed; drop the rest on the floor
500 * if there isn't a handler anymore
501 */
502 if (!have_handler(self, CharacterData))
503 return;
504 }
505 if (len > self->buffer_size) {
506 call_character_handler(self, data, len);
507 self->buffer_used = 0;
508 }
509 else {
510 memcpy(self->buffer + self->buffer_used,
511 data, len * sizeof(XML_Char));
512 self->buffer_used += len;
513 }
514 }
515}
516
Fred Drake85d835f2001-02-08 15:39:08 +0000517static void
518my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000519 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000520{
521 xmlparseobject *self = (xmlparseobject *)userData;
522
Fred Drake71b63ff2002-06-28 22:29:01 +0000523 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000524 PyObject *container, *rv, *args;
525 int i, max;
526
Fred Drake2a3d7db2002-06-28 22:56:48 +0000527 if (flush_character_buffer(self) < 0)
528 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000529 /* Set max to the number of slots filled in atts[]; max/2 is
530 * the number of attributes we need to process.
531 */
532 if (self->specified_attributes) {
533 max = XML_GetSpecifiedAttributeCount(self->itself);
534 }
535 else {
536 max = 0;
537 while (atts[max] != NULL)
538 max += 2;
539 }
540 /* Build the container. */
541 if (self->ordered_attributes)
542 container = PyList_New(max);
543 else
544 container = PyDict_New();
545 if (container == NULL) {
546 flag_error(self);
547 return;
548 }
549 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000550 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000551 PyObject *v;
552 if (n == NULL) {
553 flag_error(self);
554 Py_DECREF(container);
555 return;
556 }
557 v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
558 if (v == NULL) {
559 flag_error(self);
560 Py_DECREF(container);
561 Py_DECREF(n);
562 return;
563 }
564 if (self->ordered_attributes) {
565 PyList_SET_ITEM(container, i, n);
566 PyList_SET_ITEM(container, i+1, v);
567 }
568 else if (PyDict_SetItem(container, n, v)) {
569 flag_error(self);
570 Py_DECREF(n);
571 Py_DECREF(v);
572 return;
573 }
574 else {
575 Py_DECREF(n);
576 Py_DECREF(v);
577 }
578 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000579 args = string_intern(self, name);
580 if (args != NULL)
581 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000582 if (args == NULL) {
583 Py_DECREF(container);
584 return;
585 }
586 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000587 self->in_callback = 1;
588 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000589 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000590 self->in_callback = 0;
591 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000592 if (rv == NULL) {
593 flag_error(self);
594 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000595 }
Fred Drake85d835f2001-02-08 15:39:08 +0000596 Py_DECREF(rv);
597 }
598}
599
600#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
601 RETURN, GETUSERDATA) \
602static RC \
603my_##NAME##Handler PARAMS {\
604 xmlparseobject *self = GETUSERDATA ; \
605 PyObject *args = NULL; \
606 PyObject *rv = NULL; \
607 INIT \
608\
Fred Drake71b63ff2002-06-28 22:29:01 +0000609 if (have_handler(self, NAME)) { \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000610 if (flush_character_buffer(self) < 0) \
611 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000612 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000613 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000614 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000615 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
Fred Drake39689c52004-08-13 03:12:57 +0000616 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000617 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000618 Py_DECREF(args); \
619 if (rv == NULL) { \
620 flag_error(self); \
621 return RETURN; \
622 } \
623 CONVERSION \
624 Py_DECREF(rv); \
625 } \
626 return RETURN; \
627}
628
Fred Drake6f987622000-08-25 18:03:30 +0000629#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
630 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
631 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000632
Fred Drake6f987622000-08-25 18:03:30 +0000633#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
634 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
635 rc = PyInt_AsLong(rv);, rc, \
636 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000637
Fred Drake71b63ff2002-06-28 22:29:01 +0000638VOID_HANDLER(EndElement,
639 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000640 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000641
Fred Drake6f987622000-08-25 18:03:30 +0000642VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000643 (void *userData,
644 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000645 const XML_Char *data),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000646 ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000647
Fred Drake6f987622000-08-25 18:03:30 +0000648VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000649 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000650 const XML_Char *entityName,
651 const XML_Char *base,
652 const XML_Char *systemId,
653 const XML_Char *publicId,
654 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000655 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000656 string_intern(self, entityName), string_intern(self, base),
657 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000658 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000659
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000660#ifndef Py_USING_UNICODE
Fred Drake85d835f2001-02-08 15:39:08 +0000661VOID_HANDLER(EntityDecl,
662 (void *userData,
663 const XML_Char *entityName,
664 int is_parameter_entity,
665 const XML_Char *value,
666 int value_length,
667 const XML_Char *base,
668 const XML_Char *systemId,
669 const XML_Char *publicId,
670 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000671 ("NiNNNNN",
672 string_intern(self, entityName), is_parameter_entity,
Fred Drake85d835f2001-02-08 15:39:08 +0000673 conv_string_len_to_utf8(value, value_length),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000674 string_intern(self, base), string_intern(self, systemId),
675 string_intern(self, publicId),
676 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000677#else
678VOID_HANDLER(EntityDecl,
679 (void *userData,
680 const XML_Char *entityName,
681 int is_parameter_entity,
682 const XML_Char *value,
683 int value_length,
684 const XML_Char *base,
685 const XML_Char *systemId,
686 const XML_Char *publicId,
687 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000688 ("NiNNNNN",
689 string_intern(self, entityName), is_parameter_entity,
Fred Drake71b63ff2002-06-28 22:29:01 +0000690 (self->returns_unicode
691 ? conv_string_len_to_unicode(value, value_length)
Fred Drake85d835f2001-02-08 15:39:08 +0000692 : conv_string_len_to_utf8(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000693 string_intern(self, base), string_intern(self, systemId),
694 string_intern(self, publicId),
695 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000696#endif
697
698VOID_HANDLER(XmlDecl,
699 (void *userData,
700 const XML_Char *version,
701 const XML_Char *encoding,
702 int standalone),
703 ("(O&O&i)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000704 STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000705 standalone))
706
707static PyObject *
708conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000709 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000710{
711 PyObject *result = NULL;
712 PyObject *children = PyTuple_New(model->numchildren);
713 int i;
714
715 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000716 assert(model->numchildren < INT_MAX);
717 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000718 PyObject *child = conv_content_model(&model->children[i],
719 conv_string);
720 if (child == NULL) {
721 Py_XDECREF(children);
722 return NULL;
723 }
724 PyTuple_SET_ITEM(children, i, child);
725 }
726 result = Py_BuildValue("(iiO&N)",
727 model->type, model->quant,
728 conv_string,model->name, children);
729 }
730 return result;
731}
732
Fred Drake06dd8cf2003-02-02 03:54:17 +0000733static void
734my_ElementDeclHandler(void *userData,
735 const XML_Char *name,
736 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000737{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000738 xmlparseobject *self = (xmlparseobject *)userData;
739 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000740
Fred Drake06dd8cf2003-02-02 03:54:17 +0000741 if (have_handler(self, ElementDecl)) {
742 PyObject *rv = NULL;
743 PyObject *modelobj, *nameobj;
744
745 if (flush_character_buffer(self) < 0)
746 goto finally;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000747#ifdef Py_USING_UNICODE
Fred Drake06dd8cf2003-02-02 03:54:17 +0000748 modelobj = conv_content_model(model,
749 (self->returns_unicode
750 ? conv_string_to_unicode
751 : conv_string_to_utf8));
Fred Drake85d835f2001-02-08 15:39:08 +0000752#else
Fred Drake06dd8cf2003-02-02 03:54:17 +0000753 modelobj = conv_content_model(model, conv_string_to_utf8);
Fred Drake85d835f2001-02-08 15:39:08 +0000754#endif
Fred Drake06dd8cf2003-02-02 03:54:17 +0000755 if (modelobj == NULL) {
756 flag_error(self);
757 goto finally;
758 }
759 nameobj = string_intern(self, name);
760 if (nameobj == NULL) {
761 Py_DECREF(modelobj);
762 flag_error(self);
763 goto finally;
764 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000765 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000766 if (args == NULL) {
767 Py_DECREF(modelobj);
768 flag_error(self);
769 goto finally;
770 }
771 self->in_callback = 1;
772 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000773 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000774 self->in_callback = 0;
775 if (rv == NULL) {
776 flag_error(self);
777 goto finally;
778 }
779 Py_DECREF(rv);
780 }
781 finally:
782 Py_XDECREF(args);
783 XML_FreeContentModel(self->itself, model);
784 return;
785}
Fred Drake85d835f2001-02-08 15:39:08 +0000786
787VOID_HANDLER(AttlistDecl,
788 (void *userData,
789 const XML_Char *elname,
790 const XML_Char *attname,
791 const XML_Char *att_type,
792 const XML_Char *dflt,
793 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000794 ("(NNO&O&i)",
795 string_intern(self, elname), string_intern(self, attname),
Fred Drake85d835f2001-02-08 15:39:08 +0000796 STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
797 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000798
Martin v. Löwisc847f402003-01-21 11:09:21 +0000799#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000800VOID_HANDLER(SkippedEntity,
801 (void *userData,
802 const XML_Char *entityName,
803 int is_parameter_entity),
804 ("Ni",
805 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000806#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000807
Fred Drake71b63ff2002-06-28 22:29:01 +0000808VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000809 (void *userData,
810 const XML_Char *notationName,
811 const XML_Char *base,
812 const XML_Char *systemId,
813 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000814 ("(NNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000815 string_intern(self, notationName), string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000816 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000817
Fred Drake6f987622000-08-25 18:03:30 +0000818VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000819 (void *userData,
820 const XML_Char *prefix,
821 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000822 ("(NN)",
823 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000824
Fred Drake6f987622000-08-25 18:03:30 +0000825VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000826 (void *userData,
827 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000828 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000829
Fred Drake6f987622000-08-25 18:03:30 +0000830VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000831 (void *userData, const XML_Char *data),
832 ("(O&)", STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000833
Fred Drake6f987622000-08-25 18:03:30 +0000834VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000835 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000836 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000837
Fred Drake6f987622000-08-25 18:03:30 +0000838VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000839 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000840 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000841
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000842#ifndef Py_USING_UNICODE
Fred Drake6f987622000-08-25 18:03:30 +0000843VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000844 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000845 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846
Fred Drake6f987622000-08-25 18:03:30 +0000847VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000848 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000849 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000850#else
Fred Drake6f987622000-08-25 18:03:30 +0000851VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000852 (void *userData, const XML_Char *s, int len),
853 ("(N)", (self->returns_unicode
854 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000855 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000856
Fred Drake6f987622000-08-25 18:03:30 +0000857VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000858 (void *userData, const XML_Char *s, int len),
859 ("(N)", (self->returns_unicode
860 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000861 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000862#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000863
Fred Drake71b63ff2002-06-28 22:29:01 +0000864INT_HANDLER(NotStandalone,
865 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000866 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000867
Fred Drake6f987622000-08-25 18:03:30 +0000868RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000869 (XML_Parser parser,
870 const XML_Char *context,
871 const XML_Char *base,
872 const XML_Char *systemId,
873 const XML_Char *publicId),
874 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000875 ("(O&NNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000876 STRING_CONV_FUNC,context, string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000877 string_intern(self, systemId), string_intern(self, publicId)),
Fred Drake6f987622000-08-25 18:03:30 +0000878 rc = PyInt_AsLong(rv);, rc,
879 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000881/* XXX UnknownEncodingHandler */
882
Fred Drake85d835f2001-02-08 15:39:08 +0000883VOID_HANDLER(StartDoctypeDecl,
884 (void *userData, const XML_Char *doctypeName,
885 const XML_Char *sysid, const XML_Char *pubid,
886 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000887 ("(NNNi)", string_intern(self, doctypeName),
888 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000889 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000890
891VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000892
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000893/* ---------------------------------------------------------------- */
894
Fred Drake71b63ff2002-06-28 22:29:01 +0000895static PyObject *
896get_parse_result(xmlparseobject *self, int rv)
897{
898 if (PyErr_Occurred()) {
899 return NULL;
900 }
901 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000902 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000903 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000904 if (flush_character_buffer(self) < 0) {
905 return NULL;
906 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000907 return PyInt_FromLong(rv);
908}
909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000910PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000911"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000912Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000913
914static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000915xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000916{
Fred Drake0582df92000-07-12 04:49:00 +0000917 char *s;
918 int slen;
919 int isFinal = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000920
Fred Drake0582df92000-07-12 04:49:00 +0000921 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
922 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000923
924 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000925}
926
Fred Drakeca1f4262000-09-21 20:10:23 +0000927/* File reading copied from cPickle */
928
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000929#define BUF_SIZE 2048
930
Fred Drake0582df92000-07-12 04:49:00 +0000931static int
932readinst(char *buf, int buf_size, PyObject *meth)
933{
934 PyObject *arg = NULL;
935 PyObject *bytes = NULL;
936 PyObject *str = NULL;
937 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000938
Fred Drake676940b2000-09-22 15:21:31 +0000939 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000940 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000941
Fred Drake7b6caff2003-07-21 17:05:56 +0000942 if ((arg = PyTuple_New(1)) == NULL) {
943 Py_DECREF(bytes);
Fred Drake0582df92000-07-12 04:49:00 +0000944 goto finally;
Fred Drake7b6caff2003-07-21 17:05:56 +0000945 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000946
Tim Peters954eef72000-09-22 06:01:11 +0000947 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000948
Martin v. Löwis9171f022004-10-13 19:50:11 +0000949#if PY_VERSION_HEX < 0x02020000
950 str = PyObject_CallObject(meth, arg);
951#else
952 str = PyObject_Call(meth, arg, NULL);
953#endif
954 if (str == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000955 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000956
Fred Drake0582df92000-07-12 04:49:00 +0000957 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000958 if (!PyString_Check(str)) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000959 PyErr_Format(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000960 "read() did not return a string object (type=%.400s)",
961 str->ob_type->tp_name);
962 goto finally;
963 }
964 len = PyString_GET_SIZE(str);
965 if (len > buf_size) {
966 PyErr_Format(PyExc_ValueError,
967 "read() returned too much data: "
968 "%i bytes requested, %i returned",
969 buf_size, len);
Fred Drake0582df92000-07-12 04:49:00 +0000970 goto finally;
971 }
972 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000973finally:
Fred Drake0582df92000-07-12 04:49:00 +0000974 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000975 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000976 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000977}
978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000979PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000980"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000981Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000982
983static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000984xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000985{
Fred Drake0582df92000-07-12 04:49:00 +0000986 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000987 FILE *fp;
988 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000989
Fred Drake0582df92000-07-12 04:49:00 +0000990 if (PyFile_Check(f)) {
991 fp = PyFile_AsFile(f);
992 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000993 else {
Fred Drake0582df92000-07-12 04:49:00 +0000994 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000995 readmethod = PyObject_GetAttrString(f, "read");
996 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000997 PyErr_Clear();
Fred Drake71b63ff2002-06-28 22:29:01 +0000998 PyErr_SetString(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000999 "argument must have 'read' attribute");
Fred Drake814f9fe2002-07-19 22:03:03 +00001000 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001001 }
1002 }
1003 for (;;) {
1004 int bytes_read;
1005 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +00001006 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +00001007 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001008 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +00001009 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001010
Fred Drake0582df92000-07-12 04:49:00 +00001011 if (fp) {
1012 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
1013 if (bytes_read < 0) {
1014 PyErr_SetFromErrno(PyExc_IOError);
1015 return NULL;
1016 }
1017 }
1018 else {
1019 bytes_read = readinst(buf, BUF_SIZE, readmethod);
Fred Drake7b6caff2003-07-21 17:05:56 +00001020 if (bytes_read < 0) {
1021 Py_DECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001022 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001023 }
Fred Drake0582df92000-07-12 04:49:00 +00001024 }
1025 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +00001026 if (PyErr_Occurred()) {
1027 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001028 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001029 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001030
Fred Drake0582df92000-07-12 04:49:00 +00001031 if (!rv || bytes_read == 0)
1032 break;
1033 }
Fred Drake7b6caff2003-07-21 17:05:56 +00001034 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +00001035 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001036}
1037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001038PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001039"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001040Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001041
1042static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001043xmlparse_SetBase(xmlparseobject *self, PyObject *args)
1044{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001045 char *base;
1046
Fred Drake0582df92000-07-12 04:49:00 +00001047 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001048 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001049 if (!XML_SetBase(self->itself, base)) {
1050 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001051 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001052 Py_INCREF(Py_None);
1053 return Py_None;
1054}
1055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001056PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001057"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001058Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001059
1060static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001061xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +00001062{
Fred Drake0582df92000-07-12 04:49:00 +00001063 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001064}
1065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001066PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +00001067"GetInputContext() -> string\n\
1068Return the untranslated text of the input that caused the current event.\n\
1069If the event was generated by a large amount of text (such as a start tag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001070for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +00001071
1072static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001073xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +00001074{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001075 if (self->in_callback) {
1076 int offset, size;
1077 const char *buffer
1078 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +00001079
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 if (buffer != NULL)
1081 return PyString_FromStringAndSize(buffer + offset,
1082 size - offset);
1083 else
1084 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001085 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001086 else
1087 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001088}
Fred Drakebd6101c2001-02-14 18:29:45 +00001089
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001090PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +00001091"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +00001092Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001093information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001094
1095static PyObject *
1096xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
1097{
1098 char *context;
1099 char *encoding = NULL;
1100 xmlparseobject *new_parser;
1101 int i;
1102
Martin v. Löwisc57428d2001-09-19 09:55:09 +00001103 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +00001104 &context, &encoding)) {
1105 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001106 }
1107
Martin v. Löwis894258c2001-09-23 10:20:10 +00001108#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001109 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001110 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001111#else
1112 /* Python versions 2.2 and later */
1113 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1114#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001115
1116 if (new_parser == NULL)
1117 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001118 new_parser->buffer_size = self->buffer_size;
1119 new_parser->buffer_used = 0;
1120 if (self->buffer != NULL) {
1121 new_parser->buffer = malloc(new_parser->buffer_size);
1122 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +00001123#ifndef Py_TPFLAGS_HAVE_GC
1124 /* Code for versions 2.0 and 2.1 */
1125 PyObject_Del(new_parser);
1126#else
1127 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001128 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +00001129#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +00001130 return PyErr_NoMemory();
1131 }
1132 }
1133 else
1134 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001135 new_parser->returns_unicode = self->returns_unicode;
1136 new_parser->ordered_attributes = self->ordered_attributes;
1137 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001138 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001139 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001140 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001141 encoding);
1142 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001143 new_parser->intern = self->intern;
1144 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001145#ifdef Py_TPFLAGS_HAVE_GC
1146 PyObject_GC_Track(new_parser);
1147#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001148 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001149#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001150
1151 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001152 Py_DECREF(new_parser);
1153 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001154 }
1155
1156 XML_SetUserData(new_parser->itself, (void *)new_parser);
1157
1158 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001159 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001160 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001161
Fred Drake2a3d7db2002-06-28 22:56:48 +00001162 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001163 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001164 Py_DECREF(new_parser);
1165 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001166 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001167 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001168
1169 /* then copy handlers from self */
1170 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001171 PyObject *handler = self->handlers[i];
1172 if (handler != NULL) {
1173 Py_INCREF(handler);
1174 new_parser->handlers[i] = handler;
1175 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001176 handler_info[i].handler);
1177 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001178 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001179 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001180}
1181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001182PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001183"SetParamEntityParsing(flag) -> success\n\
1184Controls parsing of parameter entities (including the external DTD\n\
1185subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1186XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1187XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001188was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001189
1190static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001191xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001192{
Fred Drake85d835f2001-02-08 15:39:08 +00001193 int flag;
1194 if (!PyArg_ParseTuple(args, "i", &flag))
1195 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001196 flag = XML_SetParamEntityParsing(p->itself, flag);
Fred Drake85d835f2001-02-08 15:39:08 +00001197 return PyInt_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001198}
1199
Martin v. Löwisc847f402003-01-21 11:09:21 +00001200
1201#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001202PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1203"UseForeignDTD([flag])\n\
1204Allows the application to provide an artificial external subset if one is\n\
1205not specified as part of the document instance. This readily allows the\n\
1206use of a 'default' document type controlled by the application, while still\n\
1207getting the advantage of providing document type information to the parser.\n\
1208'flag' defaults to True if not provided.");
1209
1210static PyObject *
1211xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1212{
1213 PyObject *flagobj = NULL;
1214 XML_Bool flag = XML_TRUE;
1215 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001216 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001217 return NULL;
1218 if (flagobj != NULL)
1219 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1220 rc = XML_UseForeignDTD(self->itself, flag);
1221 if (rc != XML_ERROR_NONE) {
1222 return set_error(self, rc);
1223 }
1224 Py_INCREF(Py_None);
1225 return Py_None;
1226}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001227#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001228
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001229static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001230 {"Parse", (PyCFunction)xmlparse_Parse,
Fred Drakebd6101c2001-02-14 18:29:45 +00001231 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001232 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001233 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001234 {"SetBase", (PyCFunction)xmlparse_SetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001235 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001236 {"GetBase", (PyCFunction)xmlparse_GetBase,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001237 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001238 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001239 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001240 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
1241 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001242 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001243 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001244#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001245 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
1246 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001247#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001248 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001249};
1250
1251/* ---------- */
1252
1253
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001254#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001255
Fred Drake71b63ff2002-06-28 22:29:01 +00001256/* pyexpat international encoding support.
1257 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001258*/
1259
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001260static char template_buffer[257];
Fred Drakebb66a202001-03-01 20:48:17 +00001261PyObject *template_string = NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001262
Fred Drake71b63ff2002-06-28 22:29:01 +00001263static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001264init_template_buffer(void)
1265{
1266 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001267 for (i = 0; i < 256; i++) {
1268 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001269 }
Fred Drakebb66a202001-03-01 20:48:17 +00001270 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001271}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001272
Fred Drake71b63ff2002-06-28 22:29:01 +00001273static int
1274PyUnknownEncodingHandler(void *encodingHandlerData,
1275 const XML_Char *name,
1276 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001277{
Fred Drakebb66a202001-03-01 20:48:17 +00001278 PyUnicodeObject *_u_string = NULL;
1279 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001280 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001281
Fred Drakebb66a202001-03-01 20:48:17 +00001282 /* Yes, supports only 8bit encodings */
1283 _u_string = (PyUnicodeObject *)
1284 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001285
Fred Drakebb66a202001-03-01 20:48:17 +00001286 if (_u_string == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001287 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001288
Fred Drakebb66a202001-03-01 20:48:17 +00001289 for (i = 0; i < 256; i++) {
1290 /* Stupid to access directly, but fast */
1291 Py_UNICODE c = _u_string->str[i];
1292 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001293 info->map[i] = -1;
Fred Drakebb66a202001-03-01 20:48:17 +00001294 else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001295 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001296 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001297 info->data = NULL;
1298 info->convert = NULL;
1299 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001300 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001301 Py_DECREF(_u_string);
1302 return result;
1303}
1304
1305#endif
1306
1307static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001308newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001309{
1310 int i;
1311 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001312
Martin v. Löwis894258c2001-09-23 10:20:10 +00001313#ifdef Py_TPFLAGS_HAVE_GC
1314 /* Code for versions 2.2 and later */
1315 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1316#else
Fred Drake0582df92000-07-12 04:49:00 +00001317 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001318#endif
Fred Drake0582df92000-07-12 04:49:00 +00001319 if (self == NULL)
1320 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001321
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001322#ifdef Py_USING_UNICODE
Fred Drake0582df92000-07-12 04:49:00 +00001323 self->returns_unicode = 1;
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001324#else
1325 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001326#endif
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001327
Fred Drake2a3d7db2002-06-28 22:56:48 +00001328 self->buffer = NULL;
1329 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1330 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001331 self->ordered_attributes = 0;
1332 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001333 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001334 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001335 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001336 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001337 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1338 }
Fred Drake85d835f2001-02-08 15:39:08 +00001339 else {
Fred Drake0582df92000-07-12 04:49:00 +00001340 self->itself = XML_ParserCreate(encoding);
1341 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001342 self->intern = intern;
1343 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001344#ifdef Py_TPFLAGS_HAVE_GC
1345 PyObject_GC_Track(self);
1346#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001347 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001348#endif
Fred Drake0582df92000-07-12 04:49:00 +00001349 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001350 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001351 "XML_ParserCreate failed");
1352 Py_DECREF(self);
1353 return NULL;
1354 }
1355 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001356#ifdef Py_USING_UNICODE
Fred Drake7c75bf22002-07-01 14:02:31 +00001357 XML_SetUnknownEncodingHandler(self->itself,
1358 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001359#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001360
Fred Drake2a3d7db2002-06-28 22:56:48 +00001361 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001362 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001363
Fred Drake7c75bf22002-07-01 14:02:31 +00001364 self->handlers = malloc(sizeof(PyObject *) * i);
1365 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001366 Py_DECREF(self);
1367 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001368 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001369 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001370
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001371 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001372}
1373
1374
1375static void
Fred Drake0582df92000-07-12 04:49:00 +00001376xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001377{
Fred Drake0582df92000-07-12 04:49:00 +00001378 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001379#ifdef Py_TPFLAGS_HAVE_GC
1380 PyObject_GC_UnTrack(self);
1381#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001382 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001383#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001384 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001385 XML_ParserFree(self->itself);
1386 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001387
Fred Drake85d835f2001-02-08 15:39:08 +00001388 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001389 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001390 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001391 temp = self->handlers[i];
1392 self->handlers[i] = NULL;
1393 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001394 }
1395 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001396 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001397 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001398 if (self->buffer != NULL) {
1399 free(self->buffer);
1400 self->buffer = NULL;
1401 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001402 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001403#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001404 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001405 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001406#else
1407 /* Code for versions 2.2 and later. */
1408 PyObject_GC_Del(self);
1409#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001410}
1411
Fred Drake0582df92000-07-12 04:49:00 +00001412static int
1413handlername2int(const char *name)
1414{
1415 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001416 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001417 if (strcmp(name, handler_info[i].name) == 0) {
1418 return i;
1419 }
1420 }
1421 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001422}
1423
1424static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001425get_pybool(int istrue)
1426{
1427 PyObject *result = istrue ? Py_True : Py_False;
1428 Py_INCREF(result);
1429 return result;
1430}
1431
1432static PyObject *
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001433xmlparse_getattr(xmlparseobject *self, char *name)
1434{
Fred Drake71b63ff2002-06-28 22:29:01 +00001435 int handlernum = handlername2int(name);
1436
1437 if (handlernum != -1) {
1438 PyObject *result = self->handlers[handlernum];
1439 if (result == NULL)
1440 result = Py_None;
1441 Py_INCREF(result);
1442 return result;
1443 }
1444 if (name[0] == 'E') {
1445 if (strcmp(name, "ErrorCode") == 0)
1446 return PyInt_FromLong((long)
1447 XML_GetErrorCode(self->itself));
1448 if (strcmp(name, "ErrorLineNumber") == 0)
1449 return PyInt_FromLong((long)
1450 XML_GetErrorLineNumber(self->itself));
1451 if (strcmp(name, "ErrorColumnNumber") == 0)
1452 return PyInt_FromLong((long)
1453 XML_GetErrorColumnNumber(self->itself));
1454 if (strcmp(name, "ErrorByteIndex") == 0)
1455 return PyInt_FromLong((long)
1456 XML_GetErrorByteIndex(self->itself));
1457 }
Dave Cole3203efb2004-08-26 00:37:31 +00001458 if (name[0] == 'C') {
1459 if (strcmp(name, "CurrentLineNumber") == 0)
1460 return PyInt_FromLong((long)
1461 XML_GetCurrentLineNumber(self->itself));
1462 if (strcmp(name, "CurrentColumnNumber") == 0)
1463 return PyInt_FromLong((long)
1464 XML_GetCurrentColumnNumber(self->itself));
1465 if (strcmp(name, "CurrentByteIndex") == 0)
1466 return PyInt_FromLong((long)
1467 XML_GetCurrentByteIndex(self->itself));
1468 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001469 if (name[0] == 'b') {
1470 if (strcmp(name, "buffer_size") == 0)
1471 return PyInt_FromLong((long) self->buffer_size);
1472 if (strcmp(name, "buffer_text") == 0)
1473 return get_pybool(self->buffer != NULL);
1474 if (strcmp(name, "buffer_used") == 0)
1475 return PyInt_FromLong((long) self->buffer_used);
1476 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001477 if (strcmp(name, "namespace_prefixes") == 0)
1478 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001479 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001480 return get_pybool(self->ordered_attributes);
Fred Drake0582df92000-07-12 04:49:00 +00001481 if (strcmp(name, "returns_unicode") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001482 return get_pybool((long) self->returns_unicode);
Fred Drake85d835f2001-02-08 15:39:08 +00001483 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001484 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001485 if (strcmp(name, "intern") == 0) {
1486 if (self->intern == NULL) {
1487 Py_INCREF(Py_None);
1488 return Py_None;
1489 }
1490 else {
1491 Py_INCREF(self->intern);
1492 return self->intern;
1493 }
1494 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001495
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001496#define APPEND(list, str) \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001497 do { \
1498 PyObject *o = PyString_FromString(str); \
1499 if (o != NULL) \
1500 PyList_Append(list, o); \
1501 Py_XDECREF(o); \
1502 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001503
Fred Drake0582df92000-07-12 04:49:00 +00001504 if (strcmp(name, "__members__") == 0) {
1505 int i;
1506 PyObject *rc = PyList_New(0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001507 if (!rc)
1508 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001509 for (i = 0; handler_info[i].name != NULL; i++) {
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001510 PyObject *o = get_handler_name(&handler_info[i]);
1511 if (o != NULL)
1512 PyList_Append(rc, o);
1513 Py_XDECREF(o);
Fred Drake0582df92000-07-12 04:49:00 +00001514 }
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001515 APPEND(rc, "ErrorCode");
1516 APPEND(rc, "ErrorLineNumber");
1517 APPEND(rc, "ErrorColumnNumber");
1518 APPEND(rc, "ErrorByteIndex");
Dave Cole3203efb2004-08-26 00:37:31 +00001519 APPEND(rc, "CurrentLineNumber");
1520 APPEND(rc, "CurrentColumnNumber");
1521 APPEND(rc, "CurrentByteIndex");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001522 APPEND(rc, "buffer_size");
1523 APPEND(rc, "buffer_text");
1524 APPEND(rc, "buffer_used");
Martin v. Löwis069dde22003-01-21 10:58:18 +00001525 APPEND(rc, "namespace_prefixes");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001526 APPEND(rc, "ordered_attributes");
1527 APPEND(rc, "returns_unicode");
1528 APPEND(rc, "specified_attributes");
1529 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001530
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001531#undef APPEND
Fred Drake0582df92000-07-12 04:49:00 +00001532 return rc;
1533 }
1534 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001535}
1536
Fred Drake6f987622000-08-25 18:03:30 +00001537static int
1538sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001539{
1540 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001541 if (handlernum >= 0) {
1542 xmlhandler c_handler = NULL;
1543 PyObject *temp = self->handlers[handlernum];
1544
1545 if (v == Py_None)
1546 v = NULL;
1547 else if (v != NULL) {
1548 Py_INCREF(v);
1549 c_handler = handler_info[handlernum].handler;
1550 }
Fred Drake0582df92000-07-12 04:49:00 +00001551 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001552 Py_XDECREF(temp);
1553 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001554 return 1;
1555 }
1556 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001557}
1558
1559static int
Fred Drake6f987622000-08-25 18:03:30 +00001560xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001561{
Fred Drake6f987622000-08-25 18:03:30 +00001562 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001563 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001564 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1565 return -1;
1566 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001567 if (strcmp(name, "buffer_text") == 0) {
1568 if (PyObject_IsTrue(v)) {
1569 if (self->buffer == NULL) {
1570 self->buffer = malloc(self->buffer_size);
1571 if (self->buffer == NULL) {
1572 PyErr_NoMemory();
1573 return -1;
1574 }
1575 self->buffer_used = 0;
1576 }
1577 }
1578 else if (self->buffer != NULL) {
1579 if (flush_character_buffer(self) < 0)
1580 return -1;
1581 free(self->buffer);
1582 self->buffer = NULL;
1583 }
1584 return 0;
1585 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001586 if (strcmp(name, "namespace_prefixes") == 0) {
1587 if (PyObject_IsTrue(v))
1588 self->ns_prefixes = 1;
1589 else
1590 self->ns_prefixes = 0;
1591 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1592 return 0;
1593 }
Fred Drake85d835f2001-02-08 15:39:08 +00001594 if (strcmp(name, "ordered_attributes") == 0) {
1595 if (PyObject_IsTrue(v))
1596 self->ordered_attributes = 1;
1597 else
1598 self->ordered_attributes = 0;
1599 return 0;
1600 }
Fred Drake6f987622000-08-25 18:03:30 +00001601 if (strcmp(name, "returns_unicode") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001602 if (PyObject_IsTrue(v)) {
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001603#ifndef Py_USING_UNICODE
Fred Drake71b63ff2002-06-28 22:29:01 +00001604 PyErr_SetString(PyExc_ValueError,
1605 "Unicode support not available");
Fred Drake6f987622000-08-25 18:03:30 +00001606 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001607#else
Fred Drake6f987622000-08-25 18:03:30 +00001608 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001609#endif
Fred Drake6f987622000-08-25 18:03:30 +00001610 }
1611 else
1612 self->returns_unicode = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001613 return 0;
1614 }
1615 if (strcmp(name, "specified_attributes") == 0) {
1616 if (PyObject_IsTrue(v))
1617 self->specified_attributes = 1;
1618 else
1619 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001620 return 0;
1621 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001622 if (strcmp(name, "CharacterDataHandler") == 0) {
1623 /* If we're changing the character data handler, flush all
1624 * cached data with the old handler. Not sure there's a
1625 * "right" thing to do, though, but this probably won't
1626 * happen.
1627 */
1628 if (flush_character_buffer(self) < 0)
1629 return -1;
1630 }
Fred Drake6f987622000-08-25 18:03:30 +00001631 if (sethandler(self, name, v)) {
1632 return 0;
1633 }
1634 PyErr_SetString(PyExc_AttributeError, name);
1635 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001636}
1637
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001638#ifdef WITH_CYCLE_GC
1639static int
1640xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1641{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001642 int i;
1643 for (i = 0; handler_info[i].name != NULL; i++)
1644 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001645 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001646}
1647
1648static int
1649xmlparse_clear(xmlparseobject *op)
1650{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001651 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001652 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001653 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001654}
1655#endif
1656
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001657PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001658
1659static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001660 PyObject_HEAD_INIT(NULL)
1661 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001662 "pyexpat.xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001663 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001664 0, /*tp_itemsize*/
1665 /* methods */
1666 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1667 (printfunc)0, /*tp_print*/
1668 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1669 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1670 (cmpfunc)0, /*tp_compare*/
1671 (reprfunc)0, /*tp_repr*/
1672 0, /*tp_as_number*/
1673 0, /*tp_as_sequence*/
1674 0, /*tp_as_mapping*/
1675 (hashfunc)0, /*tp_hash*/
1676 (ternaryfunc)0, /*tp_call*/
1677 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001678 0, /* tp_getattro */
1679 0, /* tp_setattro */
1680 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001681#ifdef Py_TPFLAGS_HAVE_GC
Fred Drake71b63ff2002-06-28 22:29:01 +00001682 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001683#else
Fred Drake71b63ff2002-06-28 22:29:01 +00001684 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001685#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001686 Xmlparsetype__doc__, /* tp_doc - Documentation string */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001687#ifdef WITH_CYCLE_GC
1688 (traverseproc)xmlparse_traverse, /* tp_traverse */
1689 (inquiry)xmlparse_clear /* tp_clear */
1690#else
1691 0, 0
1692#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001693};
1694
1695/* End of code for xmlparser objects */
1696/* -------------------------------------------------------- */
1697
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001698PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001699"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001700Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001701
1702static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001703pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1704{
Fred Drakecde79132001-04-25 16:01:30 +00001705 char *encoding = NULL;
1706 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001707 PyObject *intern = NULL;
1708 PyObject *result;
1709 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001710 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001711 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001712
Fred Drakeb91a36b2002-06-27 19:40:48 +00001713 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1714 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001715 return NULL;
1716 if (namespace_separator != NULL
1717 && strlen(namespace_separator) > 1) {
1718 PyErr_SetString(PyExc_ValueError,
1719 "namespace_separator must be at most one"
1720 " character, omitted, or None");
1721 return NULL;
1722 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001723 /* Explicitly passing None means no interning is desired.
1724 Not passing anything means that a new dictionary is used. */
1725 if (intern == Py_None)
1726 intern = NULL;
1727 else if (intern == NULL) {
1728 intern = PyDict_New();
1729 if (!intern)
1730 return NULL;
1731 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001732 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001733 else if (!PyDict_Check(intern)) {
1734 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1735 return NULL;
1736 }
1737
1738 result = newxmlparseobject(encoding, namespace_separator, intern);
1739 if (intern_decref) {
1740 Py_DECREF(intern);
1741 }
1742 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001743}
1744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001746"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001747Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001748
1749static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001750pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001751{
Fred Drake0582df92000-07-12 04:49:00 +00001752 long code = 0;
1753
1754 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1755 return NULL;
1756 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001757}
1758
1759/* List of methods defined in the module */
1760
1761static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001762 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1763 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1764 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1765 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001766
Fred Drake0582df92000-07-12 04:49:00 +00001767 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001768};
1769
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001770/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001771
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001772PyDoc_STRVAR(pyexpat_module_documentation,
1773"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001774
Fred Drake4113b132001-03-24 19:58:26 +00001775/* Return a Python string that represents the version number without the
1776 * extra cruft added by revision control, even if the right options were
1777 * given to the "cvs export" command to make it not include the extra
1778 * cruft.
1779 */
1780static PyObject *
1781get_version_string(void)
1782{
1783 static char *rcsid = "$Revision$";
1784 char *rev = rcsid;
1785 int i = 0;
1786
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001787 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001788 ++rev;
1789 while (rev[i] != ' ' && rev[i] != '\0')
1790 ++i;
1791
1792 return PyString_FromStringAndSize(rev, i);
1793}
1794
Fred Drakecde79132001-04-25 16:01:30 +00001795/* Initialization function for the module */
1796
1797#ifndef MODULE_NAME
1798#define MODULE_NAME "pyexpat"
1799#endif
1800
1801#ifndef MODULE_INITFUNC
1802#define MODULE_INITFUNC initpyexpat
1803#endif
1804
Martin v. Löwis069dde22003-01-21 10:58:18 +00001805#ifndef PyMODINIT_FUNC
1806# ifdef MS_WINDOWS
1807# define PyMODINIT_FUNC __declspec(dllexport) void
1808# else
1809# define PyMODINIT_FUNC void
1810# endif
1811#endif
1812
Mark Hammond8235ea12002-07-19 06:55:41 +00001813PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001814
Martin v. Löwis069dde22003-01-21 10:58:18 +00001815PyMODINIT_FUNC
1816MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001817{
1818 PyObject *m, *d;
Fred Drakecde79132001-04-25 16:01:30 +00001819 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001820 PyObject *errors_module;
1821 PyObject *modelmod_name;
1822 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001823 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001824 static struct PyExpat_CAPI capi;
1825 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001826
Fred Drake6f987622000-08-25 18:03:30 +00001827 if (errmod_name == NULL)
1828 return;
Fred Drakecde79132001-04-25 16:01:30 +00001829 modelmod_name = PyString_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001830 if (modelmod_name == NULL)
1831 return;
Fred Drake6f987622000-08-25 18:03:30 +00001832
Fred Drake0582df92000-07-12 04:49:00 +00001833 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001834
Fred Drake0582df92000-07-12 04:49:00 +00001835 /* Create the module and add the functions */
Fred Drakecde79132001-04-25 16:01:30 +00001836 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
Fred Drake85d835f2001-02-08 15:39:08 +00001837 pyexpat_module_documentation);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001838 if (m == NULL)
1839 return;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001840
Fred Drake0582df92000-07-12 04:49:00 +00001841 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001842 if (ErrorObject == NULL) {
1843 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001844 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001845 if (ErrorObject == NULL)
1846 return;
1847 }
1848 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001849 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001850 Py_INCREF(ErrorObject);
1851 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001852 Py_INCREF(&Xmlparsetype);
1853 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001854
Fred Drake4113b132001-03-24 19:58:26 +00001855 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001856 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1857 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001858 {
1859 XML_Expat_Version info = XML_ExpatVersionInfo();
1860 PyModule_AddObject(m, "version_info",
1861 Py_BuildValue("(iii)", info.major,
1862 info.minor, info.micro));
1863 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001864#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001865 init_template_buffer();
1866#endif
Fred Drake0582df92000-07-12 04:49:00 +00001867 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001868 compiled, this should check and set native_encoding
1869 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001870 */
Fred Drake93adb692000-09-23 04:55:48 +00001871 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001872
Fred Drake85d835f2001-02-08 15:39:08 +00001873 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001874 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001875 errors_module = PyDict_GetItem(d, errmod_name);
1876 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001877 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001878 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001879 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001880 /* gives away the reference to errors_module */
1881 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001882 }
1883 }
Fred Drake6f987622000-08-25 18:03:30 +00001884 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001885 model_module = PyDict_GetItem(d, modelmod_name);
1886 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001887 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001888 if (model_module != NULL) {
1889 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1890 /* gives away the reference to model_module */
1891 PyModule_AddObject(m, "model", model_module);
1892 }
1893 }
1894 Py_DECREF(modelmod_name);
1895 if (errors_module == NULL || model_module == NULL)
1896 /* Don't core dump later! */
Fred Drake6f987622000-08-25 18:03:30 +00001897 return;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001898
Martin v. Löwisc847f402003-01-21 11:09:21 +00001899#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001900 {
1901 const XML_Feature *features = XML_GetFeatureList();
1902 PyObject *list = PyList_New(0);
1903 if (list == NULL)
1904 /* just ignore it */
1905 PyErr_Clear();
1906 else {
1907 int i = 0;
1908 for (; features[i].feature != XML_FEATURE_END; ++i) {
1909 int ok;
1910 PyObject *item = Py_BuildValue("si", features[i].name,
1911 features[i].value);
1912 if (item == NULL) {
1913 Py_DECREF(list);
1914 list = NULL;
1915 break;
1916 }
1917 ok = PyList_Append(list, item);
1918 Py_DECREF(item);
1919 if (ok < 0) {
1920 PyErr_Clear();
1921 break;
1922 }
1923 }
1924 if (list != NULL)
1925 PyModule_AddObject(m, "features", list);
1926 }
1927 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001928#endif
Fred Drake6f987622000-08-25 18:03:30 +00001929
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001930#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001931 PyModule_AddStringConstant(errors_module, #name, \
1932 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001933
Fred Drake0582df92000-07-12 04:49:00 +00001934 MYCONST(XML_ERROR_NO_MEMORY);
1935 MYCONST(XML_ERROR_SYNTAX);
1936 MYCONST(XML_ERROR_NO_ELEMENTS);
1937 MYCONST(XML_ERROR_INVALID_TOKEN);
1938 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1939 MYCONST(XML_ERROR_PARTIAL_CHAR);
1940 MYCONST(XML_ERROR_TAG_MISMATCH);
1941 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1942 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1943 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1944 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1945 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1946 MYCONST(XML_ERROR_ASYNC_ENTITY);
1947 MYCONST(XML_ERROR_BAD_CHAR_REF);
1948 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1949 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1950 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1951 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1952 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001953 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1954 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1955 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001956 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1957 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1958 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1959 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1960 /* Added in Expat 1.95.7. */
1961 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1962 /* Added in Expat 1.95.8. */
1963 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1964 MYCONST(XML_ERROR_INCOMPLETE_PE);
1965 MYCONST(XML_ERROR_XML_DECL);
1966 MYCONST(XML_ERROR_TEXT_DECL);
1967 MYCONST(XML_ERROR_PUBLICID);
1968 MYCONST(XML_ERROR_SUSPENDED);
1969 MYCONST(XML_ERROR_NOT_SUSPENDED);
1970 MYCONST(XML_ERROR_ABORTED);
1971 MYCONST(XML_ERROR_FINISHED);
1972 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001973
Fred Drake85d835f2001-02-08 15:39:08 +00001974 PyModule_AddStringConstant(errors_module, "__doc__",
1975 "Constants used to describe error conditions.");
1976
Fred Drake93adb692000-09-23 04:55:48 +00001977#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001978
Fred Drake85d835f2001-02-08 15:39:08 +00001979#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001980 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1981 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1982 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001983#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001984
Fred Drake85d835f2001-02-08 15:39:08 +00001985#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1986 PyModule_AddStringConstant(model_module, "__doc__",
1987 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001988
Fred Drake85d835f2001-02-08 15:39:08 +00001989 MYCONST(XML_CTYPE_EMPTY);
1990 MYCONST(XML_CTYPE_ANY);
1991 MYCONST(XML_CTYPE_MIXED);
1992 MYCONST(XML_CTYPE_NAME);
1993 MYCONST(XML_CTYPE_CHOICE);
1994 MYCONST(XML_CTYPE_SEQ);
1995
1996 MYCONST(XML_CQUANT_NONE);
1997 MYCONST(XML_CQUANT_OPT);
1998 MYCONST(XML_CQUANT_REP);
1999 MYCONST(XML_CQUANT_PLUS);
2000#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00002001
2002 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002003 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002004 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002005 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
2006 capi.MINOR_VERSION = XML_MINOR_VERSION;
2007 capi.MICRO_VERSION = XML_MICRO_VERSION;
2008 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002009 capi.GetErrorCode = XML_GetErrorCode;
2010 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
2011 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002012 capi.Parse = XML_Parse;
2013 capi.ParserCreate_MM = XML_ParserCreate_MM;
2014 capi.ParserFree = XML_ParserFree;
2015 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
2016 capi.SetCommentHandler = XML_SetCommentHandler;
2017 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
2018 capi.SetElementHandler = XML_SetElementHandler;
2019 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
2020 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
2021 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
2022 capi.SetUserData = XML_SetUserData;
Fredrik Lundhc3345042005-12-13 19:49:55 +00002023
2024 /* export as cobject */
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002025 capi_object = PyCObject_FromVoidPtr(&capi, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002026 if (capi_object)
2027 PyModule_AddObject(m, "expat_CAPI", capi_object);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002028}
2029
Fred Drake6f987622000-08-25 18:03:30 +00002030static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002031clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00002032{
Fred Drakecde79132001-04-25 16:01:30 +00002033 int i = 0;
2034 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002035
Fred Drake71b63ff2002-06-28 22:29:01 +00002036 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002037 if (initial)
Fred Drake71b63ff2002-06-28 22:29:01 +00002038 self->handlers[i] = NULL;
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002039 else {
Fred Drakecde79132001-04-25 16:01:30 +00002040 temp = self->handlers[i];
2041 self->handlers[i] = NULL;
2042 Py_XDECREF(temp);
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002043 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002044 }
Fred Drakecde79132001-04-25 16:01:30 +00002045 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002046}
2047
Tim Peters0c322792002-07-17 16:49:03 +00002048static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002049 {"StartElementHandler",
2050 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002051 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002052 {"EndElementHandler",
2053 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002054 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002055 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002056 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2057 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002058 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002059 (xmlhandlersetter)XML_SetCharacterDataHandler,
2060 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002061 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002062 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002063 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002064 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002065 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002066 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002067 {"StartNamespaceDeclHandler",
2068 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002069 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002070 {"EndNamespaceDeclHandler",
2071 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002072 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002073 {"CommentHandler",
2074 (xmlhandlersetter)XML_SetCommentHandler,
2075 (xmlhandler)my_CommentHandler},
2076 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002077 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002078 (xmlhandler)my_StartCdataSectionHandler},
2079 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002080 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002081 (xmlhandler)my_EndCdataSectionHandler},
2082 {"DefaultHandler",
2083 (xmlhandlersetter)XML_SetDefaultHandler,
2084 (xmlhandler)my_DefaultHandler},
2085 {"DefaultHandlerExpand",
2086 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2087 (xmlhandler)my_DefaultHandlerExpandHandler},
2088 {"NotStandaloneHandler",
2089 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2090 (xmlhandler)my_NotStandaloneHandler},
2091 {"ExternalEntityRefHandler",
2092 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002093 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002094 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002095 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002096 (xmlhandler)my_StartDoctypeDeclHandler},
2097 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002098 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002099 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002100 {"EntityDeclHandler",
2101 (xmlhandlersetter)XML_SetEntityDeclHandler,
2102 (xmlhandler)my_EntityDeclHandler},
2103 {"XmlDeclHandler",
2104 (xmlhandlersetter)XML_SetXmlDeclHandler,
2105 (xmlhandler)my_XmlDeclHandler},
2106 {"ElementDeclHandler",
2107 (xmlhandlersetter)XML_SetElementDeclHandler,
2108 (xmlhandler)my_ElementDeclHandler},
2109 {"AttlistDeclHandler",
2110 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2111 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002112#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002113 {"SkippedEntityHandler",
2114 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2115 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002116#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002117
Fred Drake0582df92000-07-12 04:49:00 +00002118 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002119};