blob: 87a16ef2c2016acdd399d39390a930aded22d5ec [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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000241/* Dummy character data handler used when an error (exception) has
242 been detected, and the actual parsing can be terminated early.
243 This is needed since character data handler can't be safely removed
244 from within the character data handler, but can be replaced. It is
245 used only from the character data handler trampoline, and must be
246 used right after `flag_error()` is called. */
247static void
248noop_character_data_handler(void *userData, const XML_Char *data, int len)
249{
250 /* Do nothing. */
251}
252
Fred Drake6f987622000-08-25 18:03:30 +0000253static void
254flag_error(xmlparseobject *self)
255{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000256 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000257 XML_SetExternalEntityRefHandler(self->itself,
258 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000259}
260
261static PyCodeObject*
262getcode(enum HandlerTypes slot, char* func_name, int lineno)
263{
Fred Drakebd6101c2001-02-14 18:29:45 +0000264 PyObject *code = NULL;
265 PyObject *name = NULL;
266 PyObject *nulltuple = NULL;
267 PyObject *filename = NULL;
268
269 if (handler_info[slot].tb_code == NULL) {
270 code = PyString_FromString("");
271 if (code == NULL)
272 goto failed;
273 name = PyString_FromString(func_name);
274 if (name == NULL)
275 goto failed;
276 nulltuple = PyTuple_New(0);
277 if (nulltuple == NULL)
278 goto failed;
279 filename = PyString_FromString(__FILE__);
280 handler_info[slot].tb_code =
281 PyCode_New(0, /* argcount */
Guido van Rossum4f72a782006-10-27 23:31:49 +0000282 0, /* kwonlyargcount */
Fred Drakebd6101c2001-02-14 18:29:45 +0000283 0, /* nlocals */
284 0, /* stacksize */
285 0, /* flags */
286 code, /* code */
287 nulltuple, /* consts */
288 nulltuple, /* names */
289 nulltuple, /* varnames */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000290#if PYTHON_API_VERSION >= 1010
Fred Drakebd6101c2001-02-14 18:29:45 +0000291 nulltuple, /* freevars */
292 nulltuple, /* cellvars */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000293#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000294 filename, /* filename */
295 name, /* name */
296 lineno, /* firstlineno */
297 code /* lnotab */
298 );
299 if (handler_info[slot].tb_code == NULL)
300 goto failed;
301 Py_DECREF(code);
302 Py_DECREF(nulltuple);
303 Py_DECREF(filename);
304 Py_DECREF(name);
305 }
306 return handler_info[slot].tb_code;
307 failed:
308 Py_XDECREF(code);
309 Py_XDECREF(name);
310 return NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000311}
312
Jeremy Hylton9263f572003-06-27 16:13:17 +0000313#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000314static int
315trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
316{
317 int result = 0;
318 if (!tstate->use_tracing || tstate->tracing)
319 return 0;
320 if (tstate->c_profilefunc != NULL) {
321 tstate->tracing++;
322 result = tstate->c_profilefunc(tstate->c_profileobj,
323 f, code , val);
324 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
325 || (tstate->c_profilefunc != NULL));
326 tstate->tracing--;
327 if (result)
328 return result;
329 }
330 if (tstate->c_tracefunc != NULL) {
331 tstate->tracing++;
332 result = tstate->c_tracefunc(tstate->c_traceobj,
333 f, code , val);
334 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
335 || (tstate->c_profilefunc != NULL));
336 tstate->tracing--;
337 }
338 return result;
339}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000340
341static int
342trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
343{
344 PyObject *type, *value, *traceback, *arg;
345 int err;
346
347 if (tstate->c_tracefunc == NULL)
348 return 0;
349
350 PyErr_Fetch(&type, &value, &traceback);
351 if (value == NULL) {
352 value = Py_None;
353 Py_INCREF(value);
354 }
Martin v. Löwis9171f022004-10-13 19:50:11 +0000355#if PY_VERSION_HEX < 0x02040000
356 arg = Py_BuildValue("(OOO)", type, value, traceback);
357#else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000358 arg = PyTuple_Pack(3, type, value, traceback);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000359#endif
Jeremy Hylton9263f572003-06-27 16:13:17 +0000360 if (arg == NULL) {
361 PyErr_Restore(type, value, traceback);
362 return 0;
363 }
364 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
365 Py_DECREF(arg);
366 if (err == 0)
367 PyErr_Restore(type, value, traceback);
368 else {
369 Py_XDECREF(type);
370 Py_XDECREF(value);
371 Py_XDECREF(traceback);
372 }
373 return err;
374}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000375#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000376
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000377static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000378call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
379 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000380{
Fred Drakebd6101c2001-02-14 18:29:45 +0000381 PyThreadState *tstate = PyThreadState_GET();
382 PyFrameObject *f;
383 PyObject *res;
384
385 if (c == NULL)
386 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000387
Jeremy Hylton9263f572003-06-27 16:13:17 +0000388 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000389 if (f == NULL)
390 return NULL;
391 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000392#ifdef FIX_TRACE
393 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000394 return NULL;
395 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000396#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000397 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000398 if (res == NULL) {
399 if (tstate->curexc_traceback == NULL)
400 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000401 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000402#ifdef FIX_TRACE
403 if (trace_frame_exc(tstate, f) < 0) {
404 return NULL;
405 }
406 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000407 else {
Jeremy Hylton9263f572003-06-27 16:13:17 +0000408 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000409 Py_XDECREF(res);
410 res = NULL;
411 }
412 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000413#else
414 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000415#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000416 tstate->frame = f->f_back;
417 Py_DECREF(f);
418 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000419}
420
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000421#ifndef Py_USING_UNICODE
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000422#define STRING_CONV_FUNC conv_string_to_utf8
423#else
Martin v. Löwis069dde22003-01-21 10:58:18 +0000424/* Python 2.0 and later versions, when built with Unicode support */
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000425#define STRING_CONV_FUNC (self->returns_unicode \
426 ? conv_string_to_unicode : conv_string_to_utf8)
427#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000428
Fred Drakeb91a36b2002-06-27 19:40:48 +0000429static PyObject*
430string_intern(xmlparseobject *self, const char* str)
431{
432 PyObject *result = STRING_CONV_FUNC(str);
433 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000434 /* result can be NULL if the unicode conversion failed. */
435 if (!result)
436 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000437 if (!self->intern)
438 return result;
439 value = PyDict_GetItem(self->intern, result);
440 if (!value) {
441 if (PyDict_SetItem(self->intern, result, result) == 0)
442 return result;
443 else
444 return NULL;
445 }
446 Py_INCREF(value);
447 Py_DECREF(result);
448 return value;
449}
450
Fred Drake2a3d7db2002-06-28 22:56:48 +0000451/* Return 0 on success, -1 on exception.
452 * flag_error() will be called before return if needed.
453 */
454static int
455call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
456{
457 PyObject *args;
458 PyObject *temp;
459
460 args = PyTuple_New(1);
461 if (args == NULL)
462 return -1;
463#ifdef Py_USING_UNICODE
464 temp = (self->returns_unicode
465 ? conv_string_len_to_unicode(buffer, len)
466 : conv_string_len_to_utf8(buffer, len));
467#else
468 temp = conv_string_len_to_utf8(buffer, len);
469#endif
470 if (temp == NULL) {
471 Py_DECREF(args);
472 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000473 XML_SetCharacterDataHandler(self->itself,
474 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000475 return -1;
476 }
477 PyTuple_SET_ITEM(args, 0, temp);
478 /* temp is now a borrowed reference; consider it unused. */
479 self->in_callback = 1;
480 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000481 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000482 /* temp is an owned reference again, or NULL */
483 self->in_callback = 0;
484 Py_DECREF(args);
485 if (temp == NULL) {
486 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000487 XML_SetCharacterDataHandler(self->itself,
488 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000489 return -1;
490 }
491 Py_DECREF(temp);
492 return 0;
493}
494
495static int
496flush_character_buffer(xmlparseobject *self)
497{
498 int rc;
499 if (self->buffer == NULL || self->buffer_used == 0)
500 return 0;
501 rc = call_character_handler(self, self->buffer, self->buffer_used);
502 self->buffer_used = 0;
503 return rc;
504}
505
506static void
507my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
508{
509 xmlparseobject *self = (xmlparseobject *) userData;
510 if (self->buffer == NULL)
511 call_character_handler(self, data, len);
512 else {
513 if ((self->buffer_used + len) > self->buffer_size) {
514 if (flush_character_buffer(self) < 0)
515 return;
516 /* handler might have changed; drop the rest on the floor
517 * if there isn't a handler anymore
518 */
519 if (!have_handler(self, CharacterData))
520 return;
521 }
522 if (len > self->buffer_size) {
523 call_character_handler(self, data, len);
524 self->buffer_used = 0;
525 }
526 else {
527 memcpy(self->buffer + self->buffer_used,
528 data, len * sizeof(XML_Char));
529 self->buffer_used += len;
530 }
531 }
532}
533
Fred Drake85d835f2001-02-08 15:39:08 +0000534static void
535my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000536 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000537{
538 xmlparseobject *self = (xmlparseobject *)userData;
539
Fred Drake71b63ff2002-06-28 22:29:01 +0000540 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000541 PyObject *container, *rv, *args;
542 int i, max;
543
Fred Drake2a3d7db2002-06-28 22:56:48 +0000544 if (flush_character_buffer(self) < 0)
545 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000546 /* Set max to the number of slots filled in atts[]; max/2 is
547 * the number of attributes we need to process.
548 */
549 if (self->specified_attributes) {
550 max = XML_GetSpecifiedAttributeCount(self->itself);
551 }
552 else {
553 max = 0;
554 while (atts[max] != NULL)
555 max += 2;
556 }
557 /* Build the container. */
558 if (self->ordered_attributes)
559 container = PyList_New(max);
560 else
561 container = PyDict_New();
562 if (container == NULL) {
563 flag_error(self);
564 return;
565 }
566 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000567 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000568 PyObject *v;
569 if (n == NULL) {
570 flag_error(self);
571 Py_DECREF(container);
572 return;
573 }
574 v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
575 if (v == NULL) {
576 flag_error(self);
577 Py_DECREF(container);
578 Py_DECREF(n);
579 return;
580 }
581 if (self->ordered_attributes) {
582 PyList_SET_ITEM(container, i, n);
583 PyList_SET_ITEM(container, i+1, v);
584 }
585 else if (PyDict_SetItem(container, n, v)) {
586 flag_error(self);
587 Py_DECREF(n);
588 Py_DECREF(v);
589 return;
590 }
591 else {
592 Py_DECREF(n);
593 Py_DECREF(v);
594 }
595 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000596 args = string_intern(self, name);
597 if (args != NULL)
598 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000599 if (args == NULL) {
600 Py_DECREF(container);
601 return;
602 }
603 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000604 self->in_callback = 1;
605 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000606 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000607 self->in_callback = 0;
608 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000609 if (rv == NULL) {
610 flag_error(self);
611 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000612 }
Fred Drake85d835f2001-02-08 15:39:08 +0000613 Py_DECREF(rv);
614 }
615}
616
617#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
618 RETURN, GETUSERDATA) \
619static RC \
620my_##NAME##Handler PARAMS {\
621 xmlparseobject *self = GETUSERDATA ; \
622 PyObject *args = NULL; \
623 PyObject *rv = NULL; \
624 INIT \
625\
Fred Drake71b63ff2002-06-28 22:29:01 +0000626 if (have_handler(self, NAME)) { \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000627 if (flush_character_buffer(self) < 0) \
628 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000629 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000630 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000631 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000632 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
Fred Drake39689c52004-08-13 03:12:57 +0000633 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000634 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000635 Py_DECREF(args); \
636 if (rv == NULL) { \
637 flag_error(self); \
638 return RETURN; \
639 } \
640 CONVERSION \
641 Py_DECREF(rv); \
642 } \
643 return RETURN; \
644}
645
Fred Drake6f987622000-08-25 18:03:30 +0000646#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
647 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
648 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649
Fred Drake6f987622000-08-25 18:03:30 +0000650#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
651 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
652 rc = PyInt_AsLong(rv);, rc, \
653 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000654
Fred Drake71b63ff2002-06-28 22:29:01 +0000655VOID_HANDLER(EndElement,
656 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000657 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000658
Fred Drake6f987622000-08-25 18:03:30 +0000659VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000660 (void *userData,
661 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000662 const XML_Char *data),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000663 ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000664
Fred Drake6f987622000-08-25 18:03:30 +0000665VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000666 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000667 const XML_Char *entityName,
668 const XML_Char *base,
669 const XML_Char *systemId,
670 const XML_Char *publicId,
671 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000672 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000673 string_intern(self, entityName), string_intern(self, base),
674 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000675 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000676
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000677#ifndef Py_USING_UNICODE
Fred Drake85d835f2001-02-08 15:39:08 +0000678VOID_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 Drake85d835f2001-02-08 15:39:08 +0000690 conv_string_len_to_utf8(value, value_length),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000691 string_intern(self, base), string_intern(self, systemId),
692 string_intern(self, publicId),
693 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000694#else
695VOID_HANDLER(EntityDecl,
696 (void *userData,
697 const XML_Char *entityName,
698 int is_parameter_entity,
699 const XML_Char *value,
700 int value_length,
701 const XML_Char *base,
702 const XML_Char *systemId,
703 const XML_Char *publicId,
704 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000705 ("NiNNNNN",
706 string_intern(self, entityName), is_parameter_entity,
Fred Drake71b63ff2002-06-28 22:29:01 +0000707 (self->returns_unicode
708 ? conv_string_len_to_unicode(value, value_length)
Fred Drake85d835f2001-02-08 15:39:08 +0000709 : conv_string_len_to_utf8(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000710 string_intern(self, base), string_intern(self, systemId),
711 string_intern(self, publicId),
712 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000713#endif
714
715VOID_HANDLER(XmlDecl,
716 (void *userData,
717 const XML_Char *version,
718 const XML_Char *encoding,
719 int standalone),
720 ("(O&O&i)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000721 STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000722 standalone))
723
724static PyObject *
725conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000726 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000727{
728 PyObject *result = NULL;
729 PyObject *children = PyTuple_New(model->numchildren);
730 int i;
731
732 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000733 assert(model->numchildren < INT_MAX);
734 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000735 PyObject *child = conv_content_model(&model->children[i],
736 conv_string);
737 if (child == NULL) {
738 Py_XDECREF(children);
739 return NULL;
740 }
741 PyTuple_SET_ITEM(children, i, child);
742 }
743 result = Py_BuildValue("(iiO&N)",
744 model->type, model->quant,
745 conv_string,model->name, children);
746 }
747 return result;
748}
749
Fred Drake06dd8cf2003-02-02 03:54:17 +0000750static void
751my_ElementDeclHandler(void *userData,
752 const XML_Char *name,
753 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000754{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000755 xmlparseobject *self = (xmlparseobject *)userData;
756 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000757
Fred Drake06dd8cf2003-02-02 03:54:17 +0000758 if (have_handler(self, ElementDecl)) {
759 PyObject *rv = NULL;
760 PyObject *modelobj, *nameobj;
761
762 if (flush_character_buffer(self) < 0)
763 goto finally;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000764#ifdef Py_USING_UNICODE
Fred Drake06dd8cf2003-02-02 03:54:17 +0000765 modelobj = conv_content_model(model,
766 (self->returns_unicode
767 ? conv_string_to_unicode
768 : conv_string_to_utf8));
Fred Drake85d835f2001-02-08 15:39:08 +0000769#else
Fred Drake06dd8cf2003-02-02 03:54:17 +0000770 modelobj = conv_content_model(model, conv_string_to_utf8);
Fred Drake85d835f2001-02-08 15:39:08 +0000771#endif
Fred Drake06dd8cf2003-02-02 03:54:17 +0000772 if (modelobj == NULL) {
773 flag_error(self);
774 goto finally;
775 }
776 nameobj = string_intern(self, name);
777 if (nameobj == NULL) {
778 Py_DECREF(modelobj);
779 flag_error(self);
780 goto finally;
781 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000782 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000783 if (args == NULL) {
784 Py_DECREF(modelobj);
785 flag_error(self);
786 goto finally;
787 }
788 self->in_callback = 1;
789 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000790 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000791 self->in_callback = 0;
792 if (rv == NULL) {
793 flag_error(self);
794 goto finally;
795 }
796 Py_DECREF(rv);
797 }
798 finally:
799 Py_XDECREF(args);
800 XML_FreeContentModel(self->itself, model);
801 return;
802}
Fred Drake85d835f2001-02-08 15:39:08 +0000803
804VOID_HANDLER(AttlistDecl,
805 (void *userData,
806 const XML_Char *elname,
807 const XML_Char *attname,
808 const XML_Char *att_type,
809 const XML_Char *dflt,
810 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000811 ("(NNO&O&i)",
812 string_intern(self, elname), string_intern(self, attname),
Fred Drake85d835f2001-02-08 15:39:08 +0000813 STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
814 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000815
Martin v. Löwisc847f402003-01-21 11:09:21 +0000816#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000817VOID_HANDLER(SkippedEntity,
818 (void *userData,
819 const XML_Char *entityName,
820 int is_parameter_entity),
821 ("Ni",
822 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000823#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000824
Fred Drake71b63ff2002-06-28 22:29:01 +0000825VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000826 (void *userData,
827 const XML_Char *notationName,
828 const XML_Char *base,
829 const XML_Char *systemId,
830 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000831 ("(NNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000832 string_intern(self, notationName), string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000833 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000834
Fred Drake6f987622000-08-25 18:03:30 +0000835VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000836 (void *userData,
837 const XML_Char *prefix,
838 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000839 ("(NN)",
840 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000841
Fred Drake6f987622000-08-25 18:03:30 +0000842VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000843 (void *userData,
844 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000845 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846
Fred Drake6f987622000-08-25 18:03:30 +0000847VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000848 (void *userData, const XML_Char *data),
849 ("(O&)", STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000850
Fred Drake6f987622000-08-25 18:03:30 +0000851VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000852 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000853 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000854
Fred Drake6f987622000-08-25 18:03:30 +0000855VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000856 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000857 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000858
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000859#ifndef Py_USING_UNICODE
Fred Drake6f987622000-08-25 18:03:30 +0000860VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000861 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000862 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000863
Fred Drake6f987622000-08-25 18:03:30 +0000864VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000865 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000866 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000867#else
Fred Drake6f987622000-08-25 18:03:30 +0000868VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000869 (void *userData, const XML_Char *s, int len),
870 ("(N)", (self->returns_unicode
871 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000872 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000873
Fred Drake6f987622000-08-25 18:03:30 +0000874VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000875 (void *userData, const XML_Char *s, int len),
876 ("(N)", (self->returns_unicode
877 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000878 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000879#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880
Fred Drake71b63ff2002-06-28 22:29:01 +0000881INT_HANDLER(NotStandalone,
882 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000883 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000884
Fred Drake6f987622000-08-25 18:03:30 +0000885RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000886 (XML_Parser parser,
887 const XML_Char *context,
888 const XML_Char *base,
889 const XML_Char *systemId,
890 const XML_Char *publicId),
891 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000892 ("(O&NNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000893 STRING_CONV_FUNC,context, string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000894 string_intern(self, systemId), string_intern(self, publicId)),
Fred Drake6f987622000-08-25 18:03:30 +0000895 rc = PyInt_AsLong(rv);, rc,
896 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000897
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000898/* XXX UnknownEncodingHandler */
899
Fred Drake85d835f2001-02-08 15:39:08 +0000900VOID_HANDLER(StartDoctypeDecl,
901 (void *userData, const XML_Char *doctypeName,
902 const XML_Char *sysid, const XML_Char *pubid,
903 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000904 ("(NNNi)", string_intern(self, doctypeName),
905 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000906 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000907
908VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000909
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000910/* ---------------------------------------------------------------- */
911
Fred Drake71b63ff2002-06-28 22:29:01 +0000912static PyObject *
913get_parse_result(xmlparseobject *self, int rv)
914{
915 if (PyErr_Occurred()) {
916 return NULL;
917 }
918 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000919 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000920 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000921 if (flush_character_buffer(self) < 0) {
922 return NULL;
923 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000924 return PyInt_FromLong(rv);
925}
926
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000927PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000928"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000929Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000930
931static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000932xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000933{
Fred Drake0582df92000-07-12 04:49:00 +0000934 char *s;
935 int slen;
936 int isFinal = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000937
Fred Drake0582df92000-07-12 04:49:00 +0000938 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
939 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000940
941 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000942}
943
Fred Drakeca1f4262000-09-21 20:10:23 +0000944/* File reading copied from cPickle */
945
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000946#define BUF_SIZE 2048
947
Fred Drake0582df92000-07-12 04:49:00 +0000948static int
949readinst(char *buf, int buf_size, PyObject *meth)
950{
951 PyObject *arg = NULL;
952 PyObject *bytes = NULL;
953 PyObject *str = NULL;
954 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000955
Fred Drake676940b2000-09-22 15:21:31 +0000956 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000957 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000958
Fred Drake7b6caff2003-07-21 17:05:56 +0000959 if ((arg = PyTuple_New(1)) == NULL) {
960 Py_DECREF(bytes);
Fred Drake0582df92000-07-12 04:49:00 +0000961 goto finally;
Fred Drake7b6caff2003-07-21 17:05:56 +0000962 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000963
Tim Peters954eef72000-09-22 06:01:11 +0000964 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000965
Martin v. Löwis9171f022004-10-13 19:50:11 +0000966#if PY_VERSION_HEX < 0x02020000
967 str = PyObject_CallObject(meth, arg);
968#else
969 str = PyObject_Call(meth, arg, NULL);
970#endif
971 if (str == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000972 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000973
Fred Drake0582df92000-07-12 04:49:00 +0000974 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000975 if (!PyString_Check(str)) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000976 PyErr_Format(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000977 "read() did not return a string object (type=%.400s)",
978 str->ob_type->tp_name);
979 goto finally;
980 }
981 len = PyString_GET_SIZE(str);
982 if (len > buf_size) {
983 PyErr_Format(PyExc_ValueError,
984 "read() returned too much data: "
985 "%i bytes requested, %i returned",
986 buf_size, len);
Fred Drake0582df92000-07-12 04:49:00 +0000987 goto finally;
988 }
989 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000990finally:
Fred Drake0582df92000-07-12 04:49:00 +0000991 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000992 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000993 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000994}
995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000996PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000997"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000998Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000999
1000static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001001xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001002{
Fred Drake0582df92000-07-12 04:49:00 +00001003 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +00001004 FILE *fp;
1005 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001006
Fred Drake0582df92000-07-12 04:49:00 +00001007 if (PyFile_Check(f)) {
1008 fp = PyFile_AsFile(f);
1009 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +00001010 else {
Fred Drake0582df92000-07-12 04:49:00 +00001011 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +00001012 readmethod = PyObject_GetAttrString(f, "read");
1013 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001014 PyErr_Clear();
Fred Drake71b63ff2002-06-28 22:29:01 +00001015 PyErr_SetString(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +00001016 "argument must have 'read' attribute");
Fred Drake814f9fe2002-07-19 22:03:03 +00001017 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001018 }
1019 }
1020 for (;;) {
1021 int bytes_read;
1022 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +00001023 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +00001024 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001025 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +00001026 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001027
Fred Drake0582df92000-07-12 04:49:00 +00001028 if (fp) {
1029 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
1030 if (bytes_read < 0) {
1031 PyErr_SetFromErrno(PyExc_IOError);
1032 return NULL;
1033 }
1034 }
1035 else {
1036 bytes_read = readinst(buf, BUF_SIZE, readmethod);
Fred Drake7b6caff2003-07-21 17:05:56 +00001037 if (bytes_read < 0) {
1038 Py_DECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001039 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001040 }
Fred Drake0582df92000-07-12 04:49:00 +00001041 }
1042 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +00001043 if (PyErr_Occurred()) {
1044 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001045 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001046 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001047
Fred Drake0582df92000-07-12 04:49:00 +00001048 if (!rv || bytes_read == 0)
1049 break;
1050 }
Fred Drake7b6caff2003-07-21 17:05:56 +00001051 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +00001052 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001053}
1054
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001055PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001056"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001057Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001058
1059static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001060xmlparse_SetBase(xmlparseobject *self, PyObject *args)
1061{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001062 char *base;
1063
Fred Drake0582df92000-07-12 04:49:00 +00001064 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001065 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001066 if (!XML_SetBase(self->itself, base)) {
1067 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001068 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001069 Py_INCREF(Py_None);
1070 return Py_None;
1071}
1072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001073PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001074"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001075Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001076
1077static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001078xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +00001079{
Fred Drake0582df92000-07-12 04:49:00 +00001080 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001081}
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +00001084"GetInputContext() -> string\n\
1085Return the untranslated text of the input that caused the current event.\n\
1086If 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 +00001087for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +00001088
1089static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001090xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +00001091{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001092 if (self->in_callback) {
1093 int offset, size;
1094 const char *buffer
1095 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +00001096
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097 if (buffer != NULL)
1098 return PyString_FromStringAndSize(buffer + offset,
1099 size - offset);
1100 else
1101 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001102 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001103 else
1104 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001105}
Fred Drakebd6101c2001-02-14 18:29:45 +00001106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001107PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +00001108"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +00001109Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001110information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001111
1112static PyObject *
1113xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
1114{
1115 char *context;
1116 char *encoding = NULL;
1117 xmlparseobject *new_parser;
1118 int i;
1119
Martin v. Löwisc57428d2001-09-19 09:55:09 +00001120 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +00001121 &context, &encoding)) {
1122 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001123 }
1124
Martin v. Löwis894258c2001-09-23 10:20:10 +00001125#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001126 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001127 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001128#else
1129 /* Python versions 2.2 and later */
1130 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1131#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001132
1133 if (new_parser == NULL)
1134 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001135 new_parser->buffer_size = self->buffer_size;
1136 new_parser->buffer_used = 0;
1137 if (self->buffer != NULL) {
1138 new_parser->buffer = malloc(new_parser->buffer_size);
1139 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +00001140#ifndef Py_TPFLAGS_HAVE_GC
1141 /* Code for versions 2.0 and 2.1 */
1142 PyObject_Del(new_parser);
1143#else
1144 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001145 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +00001146#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +00001147 return PyErr_NoMemory();
1148 }
1149 }
1150 else
1151 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001152 new_parser->returns_unicode = self->returns_unicode;
1153 new_parser->ordered_attributes = self->ordered_attributes;
1154 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001155 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001156 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001157 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001158 encoding);
1159 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001160 new_parser->intern = self->intern;
1161 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001162#ifdef Py_TPFLAGS_HAVE_GC
1163 PyObject_GC_Track(new_parser);
1164#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001165 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001166#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001167
1168 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001169 Py_DECREF(new_parser);
1170 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001171 }
1172
1173 XML_SetUserData(new_parser->itself, (void *)new_parser);
1174
1175 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001176 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001177 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001178
Fred Drake2a3d7db2002-06-28 22:56:48 +00001179 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001180 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001181 Py_DECREF(new_parser);
1182 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001183 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001184 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001185
1186 /* then copy handlers from self */
1187 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001188 PyObject *handler = self->handlers[i];
1189 if (handler != NULL) {
1190 Py_INCREF(handler);
1191 new_parser->handlers[i] = handler;
1192 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001193 handler_info[i].handler);
1194 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001195 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001196 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001197}
1198
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001199PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001200"SetParamEntityParsing(flag) -> success\n\
1201Controls parsing of parameter entities (including the external DTD\n\
1202subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1203XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1204XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001206
1207static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001208xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001209{
Fred Drake85d835f2001-02-08 15:39:08 +00001210 int flag;
1211 if (!PyArg_ParseTuple(args, "i", &flag))
1212 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001213 flag = XML_SetParamEntityParsing(p->itself, flag);
Fred Drake85d835f2001-02-08 15:39:08 +00001214 return PyInt_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001215}
1216
Martin v. Löwisc847f402003-01-21 11:09:21 +00001217
1218#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001219PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1220"UseForeignDTD([flag])\n\
1221Allows the application to provide an artificial external subset if one is\n\
1222not specified as part of the document instance. This readily allows the\n\
1223use of a 'default' document type controlled by the application, while still\n\
1224getting the advantage of providing document type information to the parser.\n\
1225'flag' defaults to True if not provided.");
1226
1227static PyObject *
1228xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1229{
1230 PyObject *flagobj = NULL;
1231 XML_Bool flag = XML_TRUE;
1232 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001233 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001234 return NULL;
1235 if (flagobj != NULL)
1236 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1237 rc = XML_UseForeignDTD(self->itself, flag);
1238 if (rc != XML_ERROR_NONE) {
1239 return set_error(self, rc);
1240 }
1241 Py_INCREF(Py_None);
1242 return Py_None;
1243}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001244#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001245
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001246static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001247 {"Parse", (PyCFunction)xmlparse_Parse,
Fred Drakebd6101c2001-02-14 18:29:45 +00001248 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001249 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001250 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001251 {"SetBase", (PyCFunction)xmlparse_SetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001252 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001253 {"GetBase", (PyCFunction)xmlparse_GetBase,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001254 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001255 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001256 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001257 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
1258 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001259 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001260 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001261#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001262 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
1263 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001264#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001265 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001266};
1267
1268/* ---------- */
1269
1270
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001271#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001272
Fred Drake71b63ff2002-06-28 22:29:01 +00001273/* pyexpat international encoding support.
1274 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001275*/
1276
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001277static char template_buffer[257];
Fred Drakebb66a202001-03-01 20:48:17 +00001278PyObject *template_string = NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001279
Fred Drake71b63ff2002-06-28 22:29:01 +00001280static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001281init_template_buffer(void)
1282{
1283 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001284 for (i = 0; i < 256; i++) {
1285 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001286 }
Fred Drakebb66a202001-03-01 20:48:17 +00001287 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001288}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001289
Fred Drake71b63ff2002-06-28 22:29:01 +00001290static int
1291PyUnknownEncodingHandler(void *encodingHandlerData,
1292 const XML_Char *name,
1293 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001294{
Fred Drakebb66a202001-03-01 20:48:17 +00001295 PyUnicodeObject *_u_string = NULL;
1296 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001297 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001298
Fred Drakebb66a202001-03-01 20:48:17 +00001299 /* Yes, supports only 8bit encodings */
1300 _u_string = (PyUnicodeObject *)
1301 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001302
Fred Drakebb66a202001-03-01 20:48:17 +00001303 if (_u_string == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001304 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001305
Fred Drakebb66a202001-03-01 20:48:17 +00001306 for (i = 0; i < 256; i++) {
1307 /* Stupid to access directly, but fast */
1308 Py_UNICODE c = _u_string->str[i];
1309 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001310 info->map[i] = -1;
Fred Drakebb66a202001-03-01 20:48:17 +00001311 else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001312 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001313 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001314 info->data = NULL;
1315 info->convert = NULL;
1316 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001317 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001318 Py_DECREF(_u_string);
1319 return result;
1320}
1321
1322#endif
1323
1324static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001325newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001326{
1327 int i;
1328 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001329
Martin v. Löwis894258c2001-09-23 10:20:10 +00001330#ifdef Py_TPFLAGS_HAVE_GC
1331 /* Code for versions 2.2 and later */
1332 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1333#else
Fred Drake0582df92000-07-12 04:49:00 +00001334 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001335#endif
Fred Drake0582df92000-07-12 04:49:00 +00001336 if (self == NULL)
1337 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001338
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001339#ifdef Py_USING_UNICODE
Fred Drake0582df92000-07-12 04:49:00 +00001340 self->returns_unicode = 1;
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001341#else
1342 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001343#endif
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001344
Fred Drake2a3d7db2002-06-28 22:56:48 +00001345 self->buffer = NULL;
1346 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1347 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001348 self->ordered_attributes = 0;
1349 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001350 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001351 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001352 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001353 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001354 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1355 }
Fred Drake85d835f2001-02-08 15:39:08 +00001356 else {
Fred Drake0582df92000-07-12 04:49:00 +00001357 self->itself = XML_ParserCreate(encoding);
1358 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001359 self->intern = intern;
1360 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001361#ifdef Py_TPFLAGS_HAVE_GC
1362 PyObject_GC_Track(self);
1363#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001364 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001365#endif
Fred Drake0582df92000-07-12 04:49:00 +00001366 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001367 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001368 "XML_ParserCreate failed");
1369 Py_DECREF(self);
1370 return NULL;
1371 }
1372 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001373#ifdef Py_USING_UNICODE
Fred Drake7c75bf22002-07-01 14:02:31 +00001374 XML_SetUnknownEncodingHandler(self->itself,
1375 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001376#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001377
Fred Drake2a3d7db2002-06-28 22:56:48 +00001378 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001379 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001380
Fred Drake7c75bf22002-07-01 14:02:31 +00001381 self->handlers = malloc(sizeof(PyObject *) * i);
1382 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001383 Py_DECREF(self);
1384 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001385 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001386 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001387
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001388 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001389}
1390
1391
1392static void
Fred Drake0582df92000-07-12 04:49:00 +00001393xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001394{
Fred Drake0582df92000-07-12 04:49:00 +00001395 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001396#ifdef Py_TPFLAGS_HAVE_GC
1397 PyObject_GC_UnTrack(self);
1398#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001399 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001400#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001401 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001402 XML_ParserFree(self->itself);
1403 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001404
Fred Drake85d835f2001-02-08 15:39:08 +00001405 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001406 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001407 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001408 temp = self->handlers[i];
1409 self->handlers[i] = NULL;
1410 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001411 }
1412 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001413 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001414 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001415 if (self->buffer != NULL) {
1416 free(self->buffer);
1417 self->buffer = NULL;
1418 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001419 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001420#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001421 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001422 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001423#else
1424 /* Code for versions 2.2 and later. */
1425 PyObject_GC_Del(self);
1426#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001427}
1428
Fred Drake0582df92000-07-12 04:49:00 +00001429static int
1430handlername2int(const char *name)
1431{
1432 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001433 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001434 if (strcmp(name, handler_info[i].name) == 0) {
1435 return i;
1436 }
1437 }
1438 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001439}
1440
1441static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001442get_pybool(int istrue)
1443{
1444 PyObject *result = istrue ? Py_True : Py_False;
1445 Py_INCREF(result);
1446 return result;
1447}
1448
1449static PyObject *
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001450xmlparse_getattr(xmlparseobject *self, char *name)
1451{
Fred Drake71b63ff2002-06-28 22:29:01 +00001452 int handlernum = handlername2int(name);
1453
1454 if (handlernum != -1) {
1455 PyObject *result = self->handlers[handlernum];
1456 if (result == NULL)
1457 result = Py_None;
1458 Py_INCREF(result);
1459 return result;
1460 }
1461 if (name[0] == 'E') {
1462 if (strcmp(name, "ErrorCode") == 0)
1463 return PyInt_FromLong((long)
1464 XML_GetErrorCode(self->itself));
1465 if (strcmp(name, "ErrorLineNumber") == 0)
1466 return PyInt_FromLong((long)
1467 XML_GetErrorLineNumber(self->itself));
1468 if (strcmp(name, "ErrorColumnNumber") == 0)
1469 return PyInt_FromLong((long)
1470 XML_GetErrorColumnNumber(self->itself));
1471 if (strcmp(name, "ErrorByteIndex") == 0)
1472 return PyInt_FromLong((long)
1473 XML_GetErrorByteIndex(self->itself));
1474 }
Dave Cole3203efb2004-08-26 00:37:31 +00001475 if (name[0] == 'C') {
1476 if (strcmp(name, "CurrentLineNumber") == 0)
1477 return PyInt_FromLong((long)
1478 XML_GetCurrentLineNumber(self->itself));
1479 if (strcmp(name, "CurrentColumnNumber") == 0)
1480 return PyInt_FromLong((long)
1481 XML_GetCurrentColumnNumber(self->itself));
1482 if (strcmp(name, "CurrentByteIndex") == 0)
1483 return PyInt_FromLong((long)
1484 XML_GetCurrentByteIndex(self->itself));
1485 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001486 if (name[0] == 'b') {
1487 if (strcmp(name, "buffer_size") == 0)
1488 return PyInt_FromLong((long) self->buffer_size);
1489 if (strcmp(name, "buffer_text") == 0)
1490 return get_pybool(self->buffer != NULL);
1491 if (strcmp(name, "buffer_used") == 0)
1492 return PyInt_FromLong((long) self->buffer_used);
1493 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001494 if (strcmp(name, "namespace_prefixes") == 0)
1495 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001496 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001497 return get_pybool(self->ordered_attributes);
Fred Drake0582df92000-07-12 04:49:00 +00001498 if (strcmp(name, "returns_unicode") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001499 return get_pybool((long) self->returns_unicode);
Fred Drake85d835f2001-02-08 15:39:08 +00001500 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001501 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001502 if (strcmp(name, "intern") == 0) {
1503 if (self->intern == NULL) {
1504 Py_INCREF(Py_None);
1505 return Py_None;
1506 }
1507 else {
1508 Py_INCREF(self->intern);
1509 return self->intern;
1510 }
1511 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001512
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001513#define APPEND(list, str) \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001514 do { \
1515 PyObject *o = PyString_FromString(str); \
1516 if (o != NULL) \
1517 PyList_Append(list, o); \
1518 Py_XDECREF(o); \
1519 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001520
Fred Drake0582df92000-07-12 04:49:00 +00001521 if (strcmp(name, "__members__") == 0) {
1522 int i;
1523 PyObject *rc = PyList_New(0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001524 if (!rc)
1525 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001526 for (i = 0; handler_info[i].name != NULL; i++) {
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001527 PyObject *o = get_handler_name(&handler_info[i]);
1528 if (o != NULL)
1529 PyList_Append(rc, o);
1530 Py_XDECREF(o);
Fred Drake0582df92000-07-12 04:49:00 +00001531 }
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001532 APPEND(rc, "ErrorCode");
1533 APPEND(rc, "ErrorLineNumber");
1534 APPEND(rc, "ErrorColumnNumber");
1535 APPEND(rc, "ErrorByteIndex");
Dave Cole3203efb2004-08-26 00:37:31 +00001536 APPEND(rc, "CurrentLineNumber");
1537 APPEND(rc, "CurrentColumnNumber");
1538 APPEND(rc, "CurrentByteIndex");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001539 APPEND(rc, "buffer_size");
1540 APPEND(rc, "buffer_text");
1541 APPEND(rc, "buffer_used");
Martin v. Löwis069dde22003-01-21 10:58:18 +00001542 APPEND(rc, "namespace_prefixes");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001543 APPEND(rc, "ordered_attributes");
1544 APPEND(rc, "returns_unicode");
1545 APPEND(rc, "specified_attributes");
1546 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001547
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001548#undef APPEND
Fred Drake0582df92000-07-12 04:49:00 +00001549 return rc;
1550 }
1551 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001552}
1553
Fred Drake6f987622000-08-25 18:03:30 +00001554static int
1555sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001556{
1557 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001558 if (handlernum >= 0) {
1559 xmlhandler c_handler = NULL;
1560 PyObject *temp = self->handlers[handlernum];
1561
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001562 if (v == Py_None) {
1563 /* If this is the character data handler, and a character
1564 data handler is already active, we need to be more
1565 careful. What we can safely do is replace the existing
1566 character data handler callback function with a no-op
1567 function that will refuse to call Python. The downside
1568 is that this doesn't completely remove the character
1569 data handler from the C layer if there's any callback
1570 active, so Expat does a little more work than it
1571 otherwise would, but that's really an odd case. A more
1572 elaborate system of handlers and state could remove the
1573 C handler more effectively. */
1574 if (handlernum == CharacterData && self->in_callback)
1575 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001576 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001577 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001578 else if (v != NULL) {
1579 Py_INCREF(v);
1580 c_handler = handler_info[handlernum].handler;
1581 }
Fred Drake0582df92000-07-12 04:49:00 +00001582 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001583 Py_XDECREF(temp);
1584 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001585 return 1;
1586 }
1587 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001588}
1589
1590static int
Fred Drake6f987622000-08-25 18:03:30 +00001591xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001592{
Fred Drake6f987622000-08-25 18:03:30 +00001593 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001594 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001595 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1596 return -1;
1597 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001598 if (strcmp(name, "buffer_text") == 0) {
1599 if (PyObject_IsTrue(v)) {
1600 if (self->buffer == NULL) {
1601 self->buffer = malloc(self->buffer_size);
1602 if (self->buffer == NULL) {
1603 PyErr_NoMemory();
1604 return -1;
1605 }
1606 self->buffer_used = 0;
1607 }
1608 }
1609 else if (self->buffer != NULL) {
1610 if (flush_character_buffer(self) < 0)
1611 return -1;
1612 free(self->buffer);
1613 self->buffer = NULL;
1614 }
1615 return 0;
1616 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001617 if (strcmp(name, "namespace_prefixes") == 0) {
1618 if (PyObject_IsTrue(v))
1619 self->ns_prefixes = 1;
1620 else
1621 self->ns_prefixes = 0;
1622 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1623 return 0;
1624 }
Fred Drake85d835f2001-02-08 15:39:08 +00001625 if (strcmp(name, "ordered_attributes") == 0) {
1626 if (PyObject_IsTrue(v))
1627 self->ordered_attributes = 1;
1628 else
1629 self->ordered_attributes = 0;
1630 return 0;
1631 }
Fred Drake6f987622000-08-25 18:03:30 +00001632 if (strcmp(name, "returns_unicode") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001633 if (PyObject_IsTrue(v)) {
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001634#ifndef Py_USING_UNICODE
Fred Drake71b63ff2002-06-28 22:29:01 +00001635 PyErr_SetString(PyExc_ValueError,
1636 "Unicode support not available");
Fred Drake6f987622000-08-25 18:03:30 +00001637 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001638#else
Fred Drake6f987622000-08-25 18:03:30 +00001639 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001640#endif
Fred Drake6f987622000-08-25 18:03:30 +00001641 }
1642 else
1643 self->returns_unicode = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001644 return 0;
1645 }
1646 if (strcmp(name, "specified_attributes") == 0) {
1647 if (PyObject_IsTrue(v))
1648 self->specified_attributes = 1;
1649 else
1650 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001651 return 0;
1652 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001653 if (strcmp(name, "CharacterDataHandler") == 0) {
1654 /* If we're changing the character data handler, flush all
1655 * cached data with the old handler. Not sure there's a
1656 * "right" thing to do, though, but this probably won't
1657 * happen.
1658 */
1659 if (flush_character_buffer(self) < 0)
1660 return -1;
1661 }
Fred Drake6f987622000-08-25 18:03:30 +00001662 if (sethandler(self, name, v)) {
1663 return 0;
1664 }
1665 PyErr_SetString(PyExc_AttributeError, name);
1666 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001667}
1668
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001669static int
1670xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1671{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001672 int i;
1673 for (i = 0; handler_info[i].name != NULL; i++)
1674 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001675 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001676}
1677
1678static int
1679xmlparse_clear(xmlparseobject *op)
1680{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001681 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001682 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001683 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001684}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001686PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001687
1688static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001689 PyObject_HEAD_INIT(NULL)
1690 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001691 "pyexpat.xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001692 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001693 0, /*tp_itemsize*/
1694 /* methods */
1695 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1696 (printfunc)0, /*tp_print*/
1697 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1698 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1699 (cmpfunc)0, /*tp_compare*/
1700 (reprfunc)0, /*tp_repr*/
1701 0, /*tp_as_number*/
1702 0, /*tp_as_sequence*/
1703 0, /*tp_as_mapping*/
1704 (hashfunc)0, /*tp_hash*/
1705 (ternaryfunc)0, /*tp_call*/
1706 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001707 0, /* tp_getattro */
1708 0, /* tp_setattro */
1709 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001710#ifdef Py_TPFLAGS_HAVE_GC
Fred Drake71b63ff2002-06-28 22:29:01 +00001711 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001712#else
Fred Drake71b63ff2002-06-28 22:29:01 +00001713 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001714#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001715 Xmlparsetype__doc__, /* tp_doc - Documentation string */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001716 (traverseproc)xmlparse_traverse, /* tp_traverse */
1717 (inquiry)xmlparse_clear /* tp_clear */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001718};
1719
1720/* End of code for xmlparser objects */
1721/* -------------------------------------------------------- */
1722
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001723PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001724"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001725Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001726
1727static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001728pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1729{
Fred Drakecde79132001-04-25 16:01:30 +00001730 char *encoding = NULL;
1731 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001732 PyObject *intern = NULL;
1733 PyObject *result;
1734 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001735 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001736 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001737
Fred Drakeb91a36b2002-06-27 19:40:48 +00001738 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1739 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001740 return NULL;
1741 if (namespace_separator != NULL
1742 && strlen(namespace_separator) > 1) {
1743 PyErr_SetString(PyExc_ValueError,
1744 "namespace_separator must be at most one"
1745 " character, omitted, or None");
1746 return NULL;
1747 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001748 /* Explicitly passing None means no interning is desired.
1749 Not passing anything means that a new dictionary is used. */
1750 if (intern == Py_None)
1751 intern = NULL;
1752 else if (intern == NULL) {
1753 intern = PyDict_New();
1754 if (!intern)
1755 return NULL;
1756 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001757 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001758 else if (!PyDict_Check(intern)) {
1759 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1760 return NULL;
1761 }
1762
1763 result = newxmlparseobject(encoding, namespace_separator, intern);
1764 if (intern_decref) {
1765 Py_DECREF(intern);
1766 }
1767 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001768}
1769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001770PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001771"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001772Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001773
1774static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001775pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001776{
Fred Drake0582df92000-07-12 04:49:00 +00001777 long code = 0;
1778
1779 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1780 return NULL;
1781 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001782}
1783
1784/* List of methods defined in the module */
1785
1786static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001787 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1788 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1789 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1790 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001791
Fred Drake0582df92000-07-12 04:49:00 +00001792 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001793};
1794
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001795/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797PyDoc_STRVAR(pyexpat_module_documentation,
1798"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001799
Fred Drake4113b132001-03-24 19:58:26 +00001800/* Return a Python string that represents the version number without the
1801 * extra cruft added by revision control, even if the right options were
1802 * given to the "cvs export" command to make it not include the extra
1803 * cruft.
1804 */
1805static PyObject *
1806get_version_string(void)
1807{
1808 static char *rcsid = "$Revision$";
1809 char *rev = rcsid;
1810 int i = 0;
1811
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001812 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001813 ++rev;
1814 while (rev[i] != ' ' && rev[i] != '\0')
1815 ++i;
1816
1817 return PyString_FromStringAndSize(rev, i);
1818}
1819
Fred Drakecde79132001-04-25 16:01:30 +00001820/* Initialization function for the module */
1821
1822#ifndef MODULE_NAME
1823#define MODULE_NAME "pyexpat"
1824#endif
1825
1826#ifndef MODULE_INITFUNC
1827#define MODULE_INITFUNC initpyexpat
1828#endif
1829
Martin v. Löwis069dde22003-01-21 10:58:18 +00001830#ifndef PyMODINIT_FUNC
1831# ifdef MS_WINDOWS
1832# define PyMODINIT_FUNC __declspec(dllexport) void
1833# else
1834# define PyMODINIT_FUNC void
1835# endif
1836#endif
1837
Mark Hammond8235ea12002-07-19 06:55:41 +00001838PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001839
Martin v. Löwis069dde22003-01-21 10:58:18 +00001840PyMODINIT_FUNC
1841MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001842{
1843 PyObject *m, *d;
Fred Drakecde79132001-04-25 16:01:30 +00001844 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001845 PyObject *errors_module;
1846 PyObject *modelmod_name;
1847 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001848 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001849 static struct PyExpat_CAPI capi;
1850 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001851
Fred Drake6f987622000-08-25 18:03:30 +00001852 if (errmod_name == NULL)
1853 return;
Fred Drakecde79132001-04-25 16:01:30 +00001854 modelmod_name = PyString_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001855 if (modelmod_name == NULL)
1856 return;
Fred Drake6f987622000-08-25 18:03:30 +00001857
Fred Drake0582df92000-07-12 04:49:00 +00001858 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001859
Fred Drake0582df92000-07-12 04:49:00 +00001860 /* Create the module and add the functions */
Fred Drakecde79132001-04-25 16:01:30 +00001861 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
Fred Drake85d835f2001-02-08 15:39:08 +00001862 pyexpat_module_documentation);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001863 if (m == NULL)
1864 return;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001865
Fred Drake0582df92000-07-12 04:49:00 +00001866 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001867 if (ErrorObject == NULL) {
1868 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001869 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001870 if (ErrorObject == NULL)
1871 return;
1872 }
1873 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001874 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001875 Py_INCREF(ErrorObject);
1876 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001877 Py_INCREF(&Xmlparsetype);
1878 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001879
Fred Drake4113b132001-03-24 19:58:26 +00001880 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001881 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1882 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001883 {
1884 XML_Expat_Version info = XML_ExpatVersionInfo();
1885 PyModule_AddObject(m, "version_info",
1886 Py_BuildValue("(iii)", info.major,
1887 info.minor, info.micro));
1888 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001889#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001890 init_template_buffer();
1891#endif
Fred Drake0582df92000-07-12 04:49:00 +00001892 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001893 compiled, this should check and set native_encoding
1894 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001895 */
Fred Drake93adb692000-09-23 04:55:48 +00001896 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001897
Fred Drake85d835f2001-02-08 15:39:08 +00001898 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001899 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001900 errors_module = PyDict_GetItem(d, errmod_name);
1901 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001902 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001903 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001904 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001905 /* gives away the reference to errors_module */
1906 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001907 }
1908 }
Fred Drake6f987622000-08-25 18:03:30 +00001909 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001910 model_module = PyDict_GetItem(d, modelmod_name);
1911 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001912 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001913 if (model_module != NULL) {
1914 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1915 /* gives away the reference to model_module */
1916 PyModule_AddObject(m, "model", model_module);
1917 }
1918 }
1919 Py_DECREF(modelmod_name);
1920 if (errors_module == NULL || model_module == NULL)
1921 /* Don't core dump later! */
Fred Drake6f987622000-08-25 18:03:30 +00001922 return;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001923
Martin v. Löwisc847f402003-01-21 11:09:21 +00001924#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001925 {
1926 const XML_Feature *features = XML_GetFeatureList();
1927 PyObject *list = PyList_New(0);
1928 if (list == NULL)
1929 /* just ignore it */
1930 PyErr_Clear();
1931 else {
1932 int i = 0;
1933 for (; features[i].feature != XML_FEATURE_END; ++i) {
1934 int ok;
1935 PyObject *item = Py_BuildValue("si", features[i].name,
1936 features[i].value);
1937 if (item == NULL) {
1938 Py_DECREF(list);
1939 list = NULL;
1940 break;
1941 }
1942 ok = PyList_Append(list, item);
1943 Py_DECREF(item);
1944 if (ok < 0) {
1945 PyErr_Clear();
1946 break;
1947 }
1948 }
1949 if (list != NULL)
1950 PyModule_AddObject(m, "features", list);
1951 }
1952 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001953#endif
Fred Drake6f987622000-08-25 18:03:30 +00001954
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001955#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001956 PyModule_AddStringConstant(errors_module, #name, \
1957 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001958
Fred Drake0582df92000-07-12 04:49:00 +00001959 MYCONST(XML_ERROR_NO_MEMORY);
1960 MYCONST(XML_ERROR_SYNTAX);
1961 MYCONST(XML_ERROR_NO_ELEMENTS);
1962 MYCONST(XML_ERROR_INVALID_TOKEN);
1963 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1964 MYCONST(XML_ERROR_PARTIAL_CHAR);
1965 MYCONST(XML_ERROR_TAG_MISMATCH);
1966 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1967 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1968 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1969 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1970 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1971 MYCONST(XML_ERROR_ASYNC_ENTITY);
1972 MYCONST(XML_ERROR_BAD_CHAR_REF);
1973 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1974 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1975 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1976 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1977 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001978 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1979 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1980 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001981 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1982 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1983 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1984 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1985 /* Added in Expat 1.95.7. */
1986 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1987 /* Added in Expat 1.95.8. */
1988 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1989 MYCONST(XML_ERROR_INCOMPLETE_PE);
1990 MYCONST(XML_ERROR_XML_DECL);
1991 MYCONST(XML_ERROR_TEXT_DECL);
1992 MYCONST(XML_ERROR_PUBLICID);
1993 MYCONST(XML_ERROR_SUSPENDED);
1994 MYCONST(XML_ERROR_NOT_SUSPENDED);
1995 MYCONST(XML_ERROR_ABORTED);
1996 MYCONST(XML_ERROR_FINISHED);
1997 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001998
Fred Drake85d835f2001-02-08 15:39:08 +00001999 PyModule_AddStringConstant(errors_module, "__doc__",
2000 "Constants used to describe error conditions.");
2001
Fred Drake93adb692000-09-23 04:55:48 +00002002#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002003
Fred Drake85d835f2001-02-08 15:39:08 +00002004#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002005 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
2006 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
2007 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00002008#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002009
Fred Drake85d835f2001-02-08 15:39:08 +00002010#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
2011 PyModule_AddStringConstant(model_module, "__doc__",
2012 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002013
Fred Drake85d835f2001-02-08 15:39:08 +00002014 MYCONST(XML_CTYPE_EMPTY);
2015 MYCONST(XML_CTYPE_ANY);
2016 MYCONST(XML_CTYPE_MIXED);
2017 MYCONST(XML_CTYPE_NAME);
2018 MYCONST(XML_CTYPE_CHOICE);
2019 MYCONST(XML_CTYPE_SEQ);
2020
2021 MYCONST(XML_CQUANT_NONE);
2022 MYCONST(XML_CQUANT_OPT);
2023 MYCONST(XML_CQUANT_REP);
2024 MYCONST(XML_CQUANT_PLUS);
2025#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00002026
2027 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002028 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002029 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002030 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
2031 capi.MINOR_VERSION = XML_MINOR_VERSION;
2032 capi.MICRO_VERSION = XML_MICRO_VERSION;
2033 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002034 capi.GetErrorCode = XML_GetErrorCode;
2035 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
2036 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002037 capi.Parse = XML_Parse;
2038 capi.ParserCreate_MM = XML_ParserCreate_MM;
2039 capi.ParserFree = XML_ParserFree;
2040 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
2041 capi.SetCommentHandler = XML_SetCommentHandler;
2042 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
2043 capi.SetElementHandler = XML_SetElementHandler;
2044 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
2045 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
2046 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
2047 capi.SetUserData = XML_SetUserData;
Fredrik Lundhc3345042005-12-13 19:49:55 +00002048
2049 /* export as cobject */
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002050 capi_object = PyCObject_FromVoidPtr(&capi, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002051 if (capi_object)
2052 PyModule_AddObject(m, "expat_CAPI", capi_object);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002053}
2054
Fred Drake6f987622000-08-25 18:03:30 +00002055static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002056clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00002057{
Fred Drakecde79132001-04-25 16:01:30 +00002058 int i = 0;
2059 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002060
Fred Drake71b63ff2002-06-28 22:29:01 +00002061 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002062 if (initial)
Fred Drake71b63ff2002-06-28 22:29:01 +00002063 self->handlers[i] = NULL;
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002064 else {
Fred Drakecde79132001-04-25 16:01:30 +00002065 temp = self->handlers[i];
2066 self->handlers[i] = NULL;
2067 Py_XDECREF(temp);
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002068 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002069 }
Fred Drakecde79132001-04-25 16:01:30 +00002070 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002071}
2072
Tim Peters0c322792002-07-17 16:49:03 +00002073static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002074 {"StartElementHandler",
2075 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002076 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002077 {"EndElementHandler",
2078 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002079 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002080 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002081 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2082 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002083 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002084 (xmlhandlersetter)XML_SetCharacterDataHandler,
2085 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002086 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002087 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002088 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002089 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002090 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002091 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002092 {"StartNamespaceDeclHandler",
2093 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002094 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002095 {"EndNamespaceDeclHandler",
2096 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002097 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002098 {"CommentHandler",
2099 (xmlhandlersetter)XML_SetCommentHandler,
2100 (xmlhandler)my_CommentHandler},
2101 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002102 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002103 (xmlhandler)my_StartCdataSectionHandler},
2104 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002105 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002106 (xmlhandler)my_EndCdataSectionHandler},
2107 {"DefaultHandler",
2108 (xmlhandlersetter)XML_SetDefaultHandler,
2109 (xmlhandler)my_DefaultHandler},
2110 {"DefaultHandlerExpand",
2111 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2112 (xmlhandler)my_DefaultHandlerExpandHandler},
2113 {"NotStandaloneHandler",
2114 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2115 (xmlhandler)my_NotStandaloneHandler},
2116 {"ExternalEntityRefHandler",
2117 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002118 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002119 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002120 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002121 (xmlhandler)my_StartDoctypeDeclHandler},
2122 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002123 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002124 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002125 {"EntityDeclHandler",
2126 (xmlhandlersetter)XML_SetEntityDeclHandler,
2127 (xmlhandler)my_EntityDeclHandler},
2128 {"XmlDeclHandler",
2129 (xmlhandlersetter)XML_SetXmlDeclHandler,
2130 (xmlhandler)my_XmlDeclHandler},
2131 {"ElementDeclHandler",
2132 (xmlhandlersetter)XML_SetElementDeclHandler,
2133 (xmlhandler)my_ElementDeclHandler},
2134 {"AttlistDeclHandler",
2135 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2136 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002137#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002138 {"SkippedEntityHandler",
2139 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2140 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002141#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002142
Fred Drake0582df92000-07-12 04:49:00 +00002143 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002144};