blob: f24584c63d43950d25ee6d9bddf99721b3ff248c [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
Jeremy Hylton9263f572003-06-27 16:13:17 +000011#define FIX_TRACE
Martin v. Löwis339d0f72001-08-17 18:39:25 +000012
Fred Drake0582df92000-07-12 04:49:00 +000013enum HandlerTypes {
14 StartElement,
15 EndElement,
16 ProcessingInstruction,
17 CharacterData,
18 UnparsedEntityDecl,
19 NotationDecl,
20 StartNamespaceDecl,
21 EndNamespaceDecl,
22 Comment,
23 StartCdataSection,
24 EndCdataSection,
25 Default,
26 DefaultHandlerExpand,
27 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000028 ExternalEntityRef,
29 StartDoctypeDecl,
30 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000031 EntityDecl,
32 XmlDecl,
33 ElementDecl,
34 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000035#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000036 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000037#endif
Fred Drake85d835f2001-02-08 15:39:08 +000038 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000039};
40
41static PyObject *ErrorObject;
42
43/* ----------------------------------------------------- */
44
45/* Declarations for objects of type xmlparser */
46
47typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000048 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000049
Fred Drake0582df92000-07-12 04:49:00 +000050 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000051 int ordered_attributes; /* Return attributes as a list. */
52 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000053 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000054 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000055 XML_Char *buffer; /* Buffer used when accumulating characters */
56 /* NULL if not enabled */
57 int buffer_size; /* Size of buffer, in XML_Char units */
58 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000059 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000060 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000061} xmlparseobject;
62
Fred Drake2a3d7db2002-06-28 22:56:48 +000063#define CHARACTER_DATA_BUFFER_SIZE 8192
64
Jeremy Hylton938ace62002-07-17 16:30:39 +000065static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000066
Fred Drake117ac852002-09-24 16:24:54 +000067typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000068typedef void* xmlhandler;
69
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000070struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000071 const char *name;
72 xmlhandlersetter setter;
73 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000074 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000075 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000076};
77
Jeremy Hylton938ace62002-07-17 16:30:39 +000078static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000079
Fred Drakebd6101c2001-02-14 18:29:45 +000080/* Set an integer attribute on the error object; return true on success,
81 * false on an exception.
82 */
83static int
84set_error_attr(PyObject *err, char *name, int value)
85{
Christian Heimes217cfd12007-12-02 14:31:20 +000086 PyObject *v = PyLong_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +000087
Neal Norwitz2f5e9902006-03-08 06:36:45 +000088 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
89 Py_XDECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +000090 return 0;
91 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +000092 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +000093 return 1;
94}
95
96/* Build and set an Expat exception, including positioning
97 * information. Always returns NULL.
98 */
Fred Drake85d835f2001-02-08 15:39:08 +000099static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000100set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000101{
102 PyObject *err;
103 char buffer[256];
104 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000105 int lineno = XML_GetErrorLineNumber(parser);
106 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000107
Martin v. Löwis6b2cf0e2002-06-30 06:03:35 +0000108 /* There is no risk of overflowing this buffer, since
109 even for 64-bit integers, there is sufficient space. */
110 sprintf(buffer, "%.200s: line %i, column %i",
Fred Drakebd6101c2001-02-14 18:29:45 +0000111 XML_ErrorString(code), lineno, column);
Fred Drake85d835f2001-02-08 15:39:08 +0000112 err = PyObject_CallFunction(ErrorObject, "s", buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000113 if ( err != NULL
114 && set_error_attr(err, "code", code)
115 && set_error_attr(err, "offset", column)
116 && set_error_attr(err, "lineno", lineno)) {
117 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000118 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000119 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000120 return NULL;
121}
122
Fred Drake71b63ff2002-06-28 22:29:01 +0000123static int
124have_handler(xmlparseobject *self, int type)
125{
126 PyObject *handler = self->handlers[type];
127 return handler != NULL;
128}
129
130static PyObject *
131get_handler_name(struct HandlerInfo *hinfo)
132{
133 PyObject *name = hinfo->nameobj;
134 if (name == NULL) {
Neal Norwitz392c5be2007-08-25 17:20:32 +0000135 name = PyUnicode_FromString(hinfo->name);
Fred Drake71b63ff2002-06-28 22:29:01 +0000136 hinfo->nameobj = name;
137 }
138 Py_XINCREF(name);
139 return name;
140}
141
Fred Drake85d835f2001-02-08 15:39:08 +0000142
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000143/* Convert a string of XML_Chars into a Unicode string.
144 Returns None if str is a null pointer. */
145
Fred Drake0582df92000-07-12 04:49:00 +0000146static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000147conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000148{
Fred Drake71b63ff2002-06-28 22:29:01 +0000149 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000150 and hence in UTF-8. */
151 /* UTF-8 from Expat, Unicode desired */
152 if (str == NULL) {
153 Py_INCREF(Py_None);
154 return Py_None;
155 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000156 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000157}
158
Fred Drake0582df92000-07-12 04:49:00 +0000159static PyObject *
160conv_string_len_to_unicode(const XML_Char *str, int len)
161{
Fred Drake71b63ff2002-06-28 22:29:01 +0000162 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000163 and hence in UTF-8. */
164 /* UTF-8 from Expat, Unicode desired */
165 if (str == NULL) {
166 Py_INCREF(Py_None);
167 return Py_None;
168 }
Fred Drake6f987622000-08-25 18:03:30 +0000169 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000170}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000171
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000172/* Callback routines */
173
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000174static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000175
Martin v. Löwis069dde22003-01-21 10:58:18 +0000176/* This handler is used when an error has been detected, in the hope
177 that actual parsing can be terminated early. This will only help
178 if an external entity reference is encountered. */
179static int
180error_external_entity_ref_handler(XML_Parser parser,
181 const XML_Char *context,
182 const XML_Char *base,
183 const XML_Char *systemId,
184 const XML_Char *publicId)
185{
186 return 0;
187}
188
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000189/* Dummy character data handler used when an error (exception) has
190 been detected, and the actual parsing can be terminated early.
191 This is needed since character data handler can't be safely removed
192 from within the character data handler, but can be replaced. It is
193 used only from the character data handler trampoline, and must be
194 used right after `flag_error()` is called. */
195static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196noop_character_data_handler(void *userData, const XML_Char *data, int len)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197{
198 /* Do nothing. */
199}
200
Fred Drake6f987622000-08-25 18:03:30 +0000201static void
202flag_error(xmlparseobject *self)
203{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000204 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000205 XML_SetExternalEntityRefHandler(self->itself,
206 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000207}
208
209static PyCodeObject*
210getcode(enum HandlerTypes slot, char* func_name, int lineno)
211{
Fred Drakebd6101c2001-02-14 18:29:45 +0000212 if (handler_info[slot].tb_code == NULL) {
Fred Drakebd6101c2001-02-14 18:29:45 +0000213 handler_info[slot].tb_code =
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000214 PyCode_NewEmpty(__FILE__, func_name, lineno);
Fred Drakebd6101c2001-02-14 18:29:45 +0000215 }
216 return handler_info[slot].tb_code;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000217}
218
Jeremy Hylton9263f572003-06-27 16:13:17 +0000219#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000220static int
221trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
222{
223 int result = 0;
224 if (!tstate->use_tracing || tstate->tracing)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 return 0;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000226 if (tstate->c_profilefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 tstate->tracing++;
228 result = tstate->c_profilefunc(tstate->c_profileobj,
229 f, code , val);
230 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
231 || (tstate->c_profilefunc != NULL));
232 tstate->tracing--;
233 if (result)
234 return result;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000235 }
236 if (tstate->c_tracefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 tstate->tracing++;
238 result = tstate->c_tracefunc(tstate->c_traceobj,
239 f, code , val);
240 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
241 || (tstate->c_profilefunc != NULL));
242 tstate->tracing--;
243 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000244 return result;
245}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000246
247static int
248trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
249{
250 PyObject *type, *value, *traceback, *arg;
251 int err;
252
253 if (tstate->c_tracefunc == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000255
256 PyErr_Fetch(&type, &value, &traceback);
257 if (value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 value = Py_None;
259 Py_INCREF(value);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000260 }
Martin v. Löwis9171f022004-10-13 19:50:11 +0000261#if PY_VERSION_HEX < 0x02040000
262 arg = Py_BuildValue("(OOO)", type, value, traceback);
263#else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000264 arg = PyTuple_Pack(3, type, value, traceback);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000265#endif
Jeremy Hylton9263f572003-06-27 16:13:17 +0000266 if (arg == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 PyErr_Restore(type, value, traceback);
268 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000269 }
270 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
271 Py_DECREF(arg);
272 if (err == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 PyErr_Restore(type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000274 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 Py_XDECREF(type);
276 Py_XDECREF(value);
277 Py_XDECREF(traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000278 }
279 return err;
280}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000281#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000282
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000283static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000284call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
285 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000286{
Fred Drakebd6101c2001-02-14 18:29:45 +0000287 PyThreadState *tstate = PyThreadState_GET();
288 PyFrameObject *f;
289 PyObject *res;
290
291 if (c == NULL)
292 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293
Jeremy Hylton9263f572003-06-27 16:13:17 +0000294 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000295 if (f == NULL)
296 return NULL;
297 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000298#ifdef FIX_TRACE
299 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000301 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000302#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000303 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000304 if (res == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 if (tstate->curexc_traceback == NULL)
306 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000307 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000308#ifdef FIX_TRACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 if (trace_frame_exc(tstate, f) < 0) {
310 return NULL;
311 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000312 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000313 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
315 Py_XDECREF(res);
316 res = NULL;
317 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000318 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000319#else
320 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000321#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000322 tstate->frame = f->f_back;
323 Py_DECREF(f);
324 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000325}
326
Fred Drakeb91a36b2002-06-27 19:40:48 +0000327static PyObject*
328string_intern(xmlparseobject *self, const char* str)
329{
Guido van Rossum4ca94712007-07-23 17:42:32 +0000330 PyObject *result = conv_string_to_unicode(str);
Fred Drakeb91a36b2002-06-27 19:40:48 +0000331 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000332 /* result can be NULL if the unicode conversion failed. */
333 if (!result)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000335 if (!self->intern)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000337 value = PyDict_GetItem(self->intern, result);
338 if (!value) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 if (PyDict_SetItem(self->intern, result, result) == 0)
Fred Drakeb91a36b2002-06-27 19:40:48 +0000340 return result;
341 else
342 return NULL;
343 }
344 Py_INCREF(value);
345 Py_DECREF(result);
346 return value;
347}
348
Fred Drake2a3d7db2002-06-28 22:56:48 +0000349/* Return 0 on success, -1 on exception.
350 * flag_error() will be called before return if needed.
351 */
352static int
353call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
354{
355 PyObject *args;
356 PyObject *temp;
357
358 args = PyTuple_New(1);
359 if (args == NULL)
360 return -1;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000361 temp = (conv_string_len_to_unicode(buffer, len));
Fred Drake2a3d7db2002-06-28 22:56:48 +0000362 if (temp == NULL) {
363 Py_DECREF(args);
364 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000365 XML_SetCharacterDataHandler(self->itself,
366 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000367 return -1;
368 }
369 PyTuple_SET_ITEM(args, 0, temp);
370 /* temp is now a borrowed reference; consider it unused. */
371 self->in_callback = 1;
372 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000373 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000374 /* temp is an owned reference again, or NULL */
375 self->in_callback = 0;
376 Py_DECREF(args);
377 if (temp == NULL) {
378 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000379 XML_SetCharacterDataHandler(self->itself,
380 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000381 return -1;
382 }
383 Py_DECREF(temp);
384 return 0;
385}
386
387static int
388flush_character_buffer(xmlparseobject *self)
389{
390 int rc;
391 if (self->buffer == NULL || self->buffer_used == 0)
392 return 0;
393 rc = call_character_handler(self, self->buffer, self->buffer_used);
394 self->buffer_used = 0;
395 return rc;
396}
397
398static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
Fred Drake2a3d7db2002-06-28 22:56:48 +0000400{
401 xmlparseobject *self = (xmlparseobject *) userData;
402 if (self->buffer == NULL)
403 call_character_handler(self, data, len);
404 else {
405 if ((self->buffer_used + len) > self->buffer_size) {
406 if (flush_character_buffer(self) < 0)
407 return;
408 /* handler might have changed; drop the rest on the floor
409 * if there isn't a handler anymore
410 */
411 if (!have_handler(self, CharacterData))
412 return;
413 }
414 if (len > self->buffer_size) {
415 call_character_handler(self, data, len);
416 self->buffer_used = 0;
417 }
418 else {
419 memcpy(self->buffer + self->buffer_used,
420 data, len * sizeof(XML_Char));
421 self->buffer_used += len;
422 }
423 }
424}
425
Fred Drake85d835f2001-02-08 15:39:08 +0000426static void
427my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000428 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000429{
430 xmlparseobject *self = (xmlparseobject *)userData;
431
Fred Drake71b63ff2002-06-28 22:29:01 +0000432 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000433 PyObject *container, *rv, *args;
434 int i, max;
435
Fred Drake2a3d7db2002-06-28 22:56:48 +0000436 if (flush_character_buffer(self) < 0)
437 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000438 /* Set max to the number of slots filled in atts[]; max/2 is
439 * the number of attributes we need to process.
440 */
441 if (self->specified_attributes) {
442 max = XML_GetSpecifiedAttributeCount(self->itself);
443 }
444 else {
445 max = 0;
446 while (atts[max] != NULL)
447 max += 2;
448 }
449 /* Build the container. */
450 if (self->ordered_attributes)
451 container = PyList_New(max);
452 else
453 container = PyDict_New();
454 if (container == NULL) {
455 flag_error(self);
456 return;
457 }
458 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000459 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000460 PyObject *v;
461 if (n == NULL) {
462 flag_error(self);
463 Py_DECREF(container);
464 return;
465 }
Guido van Rossum4ca94712007-07-23 17:42:32 +0000466 v = conv_string_to_unicode((XML_Char *) atts[i+1]);
Fred Drake85d835f2001-02-08 15:39:08 +0000467 if (v == NULL) {
468 flag_error(self);
469 Py_DECREF(container);
470 Py_DECREF(n);
471 return;
472 }
473 if (self->ordered_attributes) {
474 PyList_SET_ITEM(container, i, n);
475 PyList_SET_ITEM(container, i+1, v);
476 }
477 else if (PyDict_SetItem(container, n, v)) {
478 flag_error(self);
479 Py_DECREF(n);
480 Py_DECREF(v);
481 return;
482 }
483 else {
484 Py_DECREF(n);
485 Py_DECREF(v);
486 }
487 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000488 args = string_intern(self, name);
489 if (args != NULL)
490 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000491 if (args == NULL) {
492 Py_DECREF(container);
493 return;
494 }
495 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000496 self->in_callback = 1;
497 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000498 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000499 self->in_callback = 0;
500 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000501 if (rv == NULL) {
502 flag_error(self);
503 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000504 }
Fred Drake85d835f2001-02-08 15:39:08 +0000505 Py_DECREF(rv);
506 }
507}
508
509#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
510 RETURN, GETUSERDATA) \
511static RC \
512my_##NAME##Handler PARAMS {\
513 xmlparseobject *self = GETUSERDATA ; \
514 PyObject *args = NULL; \
515 PyObject *rv = NULL; \
516 INIT \
517\
Fred Drake71b63ff2002-06-28 22:29:01 +0000518 if (have_handler(self, NAME)) { \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000519 if (flush_character_buffer(self) < 0) \
520 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000521 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000522 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000523 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000524 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
Fred Drake39689c52004-08-13 03:12:57 +0000525 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000526 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000527 Py_DECREF(args); \
528 if (rv == NULL) { \
529 flag_error(self); \
530 return RETURN; \
531 } \
532 CONVERSION \
533 Py_DECREF(rv); \
534 } \
535 return RETURN; \
536}
537
Fred Drake6f987622000-08-25 18:03:30 +0000538#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
540 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000541
Fred Drake6f987622000-08-25 18:03:30 +0000542#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
544 rc = PyLong_AsLong(rv);, rc, \
545 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000546
Fred Drake71b63ff2002-06-28 22:29:01 +0000547VOID_HANDLER(EndElement,
548 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000549 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000550
Fred Drake6f987622000-08-25 18:03:30 +0000551VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000552 (void *userData,
553 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000554 const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000555 ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000556
Fred Drake6f987622000-08-25 18:03:30 +0000557VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000558 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000559 const XML_Char *entityName,
560 const XML_Char *base,
561 const XML_Char *systemId,
562 const XML_Char *publicId,
563 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000564 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000565 string_intern(self, entityName), string_intern(self, base),
566 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000567 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000568
Fred Drake85d835f2001-02-08 15:39:08 +0000569VOID_HANDLER(EntityDecl,
570 (void *userData,
571 const XML_Char *entityName,
572 int is_parameter_entity,
573 const XML_Char *value,
574 int value_length,
575 const XML_Char *base,
576 const XML_Char *systemId,
577 const XML_Char *publicId,
578 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000579 ("NiNNNNN",
580 string_intern(self, entityName), is_parameter_entity,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000581 (conv_string_len_to_unicode(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000582 string_intern(self, base), string_intern(self, systemId),
583 string_intern(self, publicId),
584 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000585
586VOID_HANDLER(XmlDecl,
587 (void *userData,
588 const XML_Char *version,
589 const XML_Char *encoding,
590 int standalone),
591 ("(O&O&i)",
Guido van Rossum4ca94712007-07-23 17:42:32 +0000592 conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000593 standalone))
594
595static PyObject *
596conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000597 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000598{
599 PyObject *result = NULL;
600 PyObject *children = PyTuple_New(model->numchildren);
601 int i;
602
603 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000604 assert(model->numchildren < INT_MAX);
605 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000606 PyObject *child = conv_content_model(&model->children[i],
607 conv_string);
608 if (child == NULL) {
609 Py_XDECREF(children);
610 return NULL;
611 }
612 PyTuple_SET_ITEM(children, i, child);
613 }
614 result = Py_BuildValue("(iiO&N)",
615 model->type, model->quant,
616 conv_string,model->name, children);
617 }
618 return result;
619}
620
Fred Drake06dd8cf2003-02-02 03:54:17 +0000621static void
622my_ElementDeclHandler(void *userData,
623 const XML_Char *name,
624 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000625{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000626 xmlparseobject *self = (xmlparseobject *)userData;
627 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000628
Fred Drake06dd8cf2003-02-02 03:54:17 +0000629 if (have_handler(self, ElementDecl)) {
630 PyObject *rv = NULL;
631 PyObject *modelobj, *nameobj;
632
633 if (flush_character_buffer(self) < 0)
634 goto finally;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000635 modelobj = conv_content_model(model, (conv_string_to_unicode));
Fred Drake06dd8cf2003-02-02 03:54:17 +0000636 if (modelobj == NULL) {
637 flag_error(self);
638 goto finally;
639 }
640 nameobj = string_intern(self, name);
641 if (nameobj == NULL) {
642 Py_DECREF(modelobj);
643 flag_error(self);
644 goto finally;
645 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000646 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000647 if (args == NULL) {
648 Py_DECREF(modelobj);
649 flag_error(self);
650 goto finally;
651 }
652 self->in_callback = 1;
653 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000654 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000655 self->in_callback = 0;
656 if (rv == NULL) {
657 flag_error(self);
658 goto finally;
659 }
660 Py_DECREF(rv);
661 }
662 finally:
663 Py_XDECREF(args);
664 XML_FreeContentModel(self->itself, model);
665 return;
666}
Fred Drake85d835f2001-02-08 15:39:08 +0000667
668VOID_HANDLER(AttlistDecl,
669 (void *userData,
670 const XML_Char *elname,
671 const XML_Char *attname,
672 const XML_Char *att_type,
673 const XML_Char *dflt,
674 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000675 ("(NNO&O&i)",
676 string_intern(self, elname), string_intern(self, attname),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000677 conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
Fred Drake85d835f2001-02-08 15:39:08 +0000678 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000679
Martin v. Löwisc847f402003-01-21 11:09:21 +0000680#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000681VOID_HANDLER(SkippedEntity,
682 (void *userData,
683 const XML_Char *entityName,
684 int is_parameter_entity),
685 ("Ni",
686 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000687#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000688
Fred Drake71b63ff2002-06-28 22:29:01 +0000689VOID_HANDLER(NotationDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 (void *userData,
691 const XML_Char *notationName,
692 const XML_Char *base,
693 const XML_Char *systemId,
694 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000695 ("(NNNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 string_intern(self, notationName), string_intern(self, base),
697 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000698
Fred Drake6f987622000-08-25 18:03:30 +0000699VOID_HANDLER(StartNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 (void *userData,
701 const XML_Char *prefix,
702 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000703 ("(NN)",
704 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000705
Fred Drake6f987622000-08-25 18:03:30 +0000706VOID_HANDLER(EndNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 (void *userData,
708 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000709 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000710
Fred Drake6f987622000-08-25 18:03:30 +0000711VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000712 (void *userData, const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000713 ("(O&)", conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000714
Fred Drake6f987622000-08-25 18:03:30 +0000715VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000716 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000718
Fred Drake6f987622000-08-25 18:03:30 +0000719VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000720 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000722
Fred Drake6f987622000-08-25 18:03:30 +0000723VOID_HANDLER(Default,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 (void *userData, const XML_Char *s, int len),
725 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000726
Fred Drake6f987622000-08-25 18:03:30 +0000727VOID_HANDLER(DefaultHandlerExpand,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 (void *userData, const XML_Char *s, int len),
729 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000730
Fred Drake71b63ff2002-06-28 22:29:01 +0000731INT_HANDLER(NotStandalone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 (void *userData),
733 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000734
Fred Drake6f987622000-08-25 18:03:30 +0000735RC_HANDLER(int, ExternalEntityRef,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 (XML_Parser parser,
737 const XML_Char *context,
738 const XML_Char *base,
739 const XML_Char *systemId,
740 const XML_Char *publicId),
741 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000742 ("(O&NNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 conv_string_to_unicode ,context, string_intern(self, base),
744 string_intern(self, systemId), string_intern(self, publicId)),
745 rc = PyLong_AsLong(rv);, rc,
746 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000747
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000748/* XXX UnknownEncodingHandler */
749
Fred Drake85d835f2001-02-08 15:39:08 +0000750VOID_HANDLER(StartDoctypeDecl,
751 (void *userData, const XML_Char *doctypeName,
752 const XML_Char *sysid, const XML_Char *pubid,
753 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000754 ("(NNNi)", string_intern(self, doctypeName),
755 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000756 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000757
758VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000759
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000760/* ---------------------------------------------------------------- */
761
Fred Drake71b63ff2002-06-28 22:29:01 +0000762static PyObject *
763get_parse_result(xmlparseobject *self, int rv)
764{
765 if (PyErr_Occurred()) {
766 return NULL;
767 }
768 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000769 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000770 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000771 if (flush_character_buffer(self) < 0) {
772 return NULL;
773 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000774 return PyLong_FromLong(rv);
Fred Drake71b63ff2002-06-28 22:29:01 +0000775}
776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000777PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000778"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000779Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000780
781static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000782xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000783{
Fred Drake0582df92000-07-12 04:49:00 +0000784 char *s;
785 int slen;
786 int isFinal = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000787
Fred Drake0582df92000-07-12 04:49:00 +0000788 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
789 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000790
791 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000792}
793
Fred Drakeca1f4262000-09-21 20:10:23 +0000794/* File reading copied from cPickle */
795
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000796#define BUF_SIZE 2048
797
Fred Drake0582df92000-07-12 04:49:00 +0000798static int
799readinst(char *buf, int buf_size, PyObject *meth)
800{
801 PyObject *arg = NULL;
802 PyObject *bytes = NULL;
803 PyObject *str = NULL;
804 int len = -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000805 char *ptr;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000806
Christian Heimes217cfd12007-12-02 14:31:20 +0000807 if ((bytes = PyLong_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000808 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000809
Fred Drake7b6caff2003-07-21 17:05:56 +0000810 if ((arg = PyTuple_New(1)) == NULL) {
811 Py_DECREF(bytes);
Fred Drake0582df92000-07-12 04:49:00 +0000812 goto finally;
Fred Drake7b6caff2003-07-21 17:05:56 +0000813 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000814
Tim Peters954eef72000-09-22 06:01:11 +0000815 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000816
Martin v. Löwis9171f022004-10-13 19:50:11 +0000817#if PY_VERSION_HEX < 0x02020000
818 str = PyObject_CallObject(meth, arg);
819#else
820 str = PyObject_Call(meth, arg, NULL);
821#endif
822 if (str == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000823 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000824
Christian Heimes72b710a2008-05-26 13:28:38 +0000825 if (PyBytes_Check(str))
826 ptr = PyBytes_AS_STRING(str);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000827 else if (PyByteArray_Check(str))
828 ptr = PyByteArray_AS_STRING(str);
Guido van Rossum98297ee2007-11-06 21:34:58 +0000829 else {
Fred Drake71b63ff2002-06-28 22:29:01 +0000830 PyErr_Format(PyExc_TypeError,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000831 "read() did not return a bytes object (type=%.400s)",
Christian Heimes90aa7642007-12-19 02:45:37 +0000832 Py_TYPE(str)->tp_name);
Fred Drake0582df92000-07-12 04:49:00 +0000833 goto finally;
834 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000835 len = Py_SIZE(str);
Fred Drake0582df92000-07-12 04:49:00 +0000836 if (len > buf_size) {
837 PyErr_Format(PyExc_ValueError,
838 "read() returned too much data: "
839 "%i bytes requested, %i returned",
840 buf_size, len);
Fred Drake0582df92000-07-12 04:49:00 +0000841 goto finally;
842 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000843 memcpy(buf, ptr, len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000844finally:
Fred Drake0582df92000-07-12 04:49:00 +0000845 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000846 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000847 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000848}
849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000850PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000851"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000852Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000853
854static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000855xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000856{
Fred Drake0582df92000-07-12 04:49:00 +0000857 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000858 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000859
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000860
861 readmethod = PyObject_GetAttrString(f, "read");
862 if (readmethod == NULL) {
863 PyErr_Clear();
864 PyErr_SetString(PyExc_TypeError,
865 "argument must have 'read' attribute");
866 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000867 }
868 for (;;) {
869 int bytes_read;
870 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000871 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000872 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000873 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +0000874 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000875
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000876 bytes_read = readinst(buf, BUF_SIZE, readmethod);
877 if (bytes_read < 0) {
878 Py_DECREF(readmethod);
879 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000880 }
881 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000882 if (PyErr_Occurred()) {
883 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000884 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000885 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000886
Fred Drake0582df92000-07-12 04:49:00 +0000887 if (!rv || bytes_read == 0)
888 break;
889 }
Fred Drake7b6caff2003-07-21 17:05:56 +0000890 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +0000891 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000892}
893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000894PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000895"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000896Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000897
898static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000899xmlparse_SetBase(xmlparseobject *self, PyObject *args)
900{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000901 char *base;
902
Fred Drake0582df92000-07-12 04:49:00 +0000903 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000904 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000905 if (!XML_SetBase(self->itself, base)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000907 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000908 Py_INCREF(Py_None);
909 return Py_None;
910}
911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000912PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000913"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000914Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000915
916static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000917xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +0000918{
Fred Drake0582df92000-07-12 04:49:00 +0000919 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000920}
921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000922PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +0000923"GetInputContext() -> string\n\
924Return the untranslated text of the input that caused the current event.\n\
925If 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 +0000926for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +0000927
928static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000929xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +0000930{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000931 if (self->in_callback) {
932 int offset, size;
933 const char *buffer
934 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +0000935
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000936 if (buffer != NULL)
Christian Heimes72b710a2008-05-26 13:28:38 +0000937 return PyBytes_FromStringAndSize(buffer + offset,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000938 size - offset);
939 else
940 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000941 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000942 else
943 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000944}
Fred Drakebd6101c2001-02-14 18:29:45 +0000945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000946PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +0000947"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000948Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000949information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000950
951static PyObject *
952xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
953{
954 char *context;
955 char *encoding = NULL;
956 xmlparseobject *new_parser;
957 int i;
958
Martin v. Löwisc57428d2001-09-19 09:55:09 +0000959 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +0000960 &context, &encoding)) {
961 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000962 }
963
Martin v. Löwis894258c2001-09-23 10:20:10 +0000964#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +0000965 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000966 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000967#else
968 /* Python versions 2.2 and later */
969 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
970#endif
Fred Drake85d835f2001-02-08 15:39:08 +0000971
972 if (new_parser == NULL)
973 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +0000974 new_parser->buffer_size = self->buffer_size;
975 new_parser->buffer_used = 0;
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000976 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000977 new_parser->ordered_attributes = self->ordered_attributes;
978 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +0000979 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000980 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000981 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000983 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000984 new_parser->intern = self->intern;
985 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000986#ifdef Py_TPFLAGS_HAVE_GC
987 PyObject_GC_Track(new_parser);
988#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000989 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000990#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000991
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000992 if (self->buffer != NULL) {
993 new_parser->buffer = malloc(new_parser->buffer_size);
994 if (new_parser->buffer == NULL) {
995 Py_DECREF(new_parser);
996 return PyErr_NoMemory();
997 }
998 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000999 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001000 Py_DECREF(new_parser);
1001 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001002 }
1003
1004 XML_SetUserData(new_parser->itself, (void *)new_parser);
1005
1006 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001007 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001008 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001009
Fred Drake2a3d7db2002-06-28 22:56:48 +00001010 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001011 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001012 Py_DECREF(new_parser);
1013 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001014 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001015 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001016
1017 /* then copy handlers from self */
1018 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001019 PyObject *handler = self->handlers[i];
1020 if (handler != NULL) {
1021 Py_INCREF(handler);
1022 new_parser->handlers[i] = handler;
1023 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001024 handler_info[i].handler);
1025 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001026 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001027 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001028}
1029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001030PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001031"SetParamEntityParsing(flag) -> success\n\
1032Controls parsing of parameter entities (including the external DTD\n\
1033subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1034XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1035XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001036was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001037
1038static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001039xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001040{
Fred Drake85d835f2001-02-08 15:39:08 +00001041 int flag;
1042 if (!PyArg_ParseTuple(args, "i", &flag))
1043 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001044 flag = XML_SetParamEntityParsing(p->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +00001045 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001046}
1047
Martin v. Löwisc847f402003-01-21 11:09:21 +00001048
1049#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001050PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1051"UseForeignDTD([flag])\n\
1052Allows the application to provide an artificial external subset if one is\n\
1053not specified as part of the document instance. This readily allows the\n\
1054use of a 'default' document type controlled by the application, while still\n\
1055getting the advantage of providing document type information to the parser.\n\
1056'flag' defaults to True if not provided.");
1057
1058static PyObject *
1059xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1060{
1061 PyObject *flagobj = NULL;
1062 XML_Bool flag = XML_TRUE;
1063 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001064 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001065 return NULL;
1066 if (flagobj != NULL)
1067 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1068 rc = XML_UseForeignDTD(self->itself, flag);
1069 if (rc != XML_ERROR_NONE) {
1070 return set_error(self, rc);
1071 }
1072 Py_INCREF(Py_None);
1073 return Py_None;
1074}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001075#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001076
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001077static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs);
1078
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001079static struct PyMethodDef xmlparse_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 {"Parse", (PyCFunction)xmlparse_Parse,
1081 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001082 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001084 {"SetBase", (PyCFunction)xmlparse_SetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001086 {"GetBase", (PyCFunction)xmlparse_GetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001088 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001090 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001092 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001094#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001095 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001097#endif
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001098 {"__dir__", xmlparse_dir, METH_NOARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001100};
1101
1102/* ---------- */
1103
1104
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001105
Fred Drake71b63ff2002-06-28 22:29:01 +00001106/* pyexpat international encoding support.
1107 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001108*/
1109
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001110static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001111
Fred Drake71b63ff2002-06-28 22:29:01 +00001112static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001113init_template_buffer(void)
1114{
1115 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001116 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001118 }
Fred Drakebb66a202001-03-01 20:48:17 +00001119 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001120}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001121
Fred Drake71b63ff2002-06-28 22:29:01 +00001122static int
1123PyUnknownEncodingHandler(void *encodingHandlerData,
1124 const XML_Char *name,
1125 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001126{
Fred Drakebb66a202001-03-01 20:48:17 +00001127 PyUnicodeObject *_u_string = NULL;
1128 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001129 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001130
Fred Drakebb66a202001-03-01 20:48:17 +00001131 /* Yes, supports only 8bit encodings */
1132 _u_string = (PyUnicodeObject *)
1133 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001134
Fred Drakebb66a202001-03-01 20:48:17 +00001135 if (_u_string == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001137
Fred Drakebb66a202001-03-01 20:48:17 +00001138 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 /* Stupid to access directly, but fast */
1140 Py_UNICODE c = _u_string->str[i];
1141 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
1142 info->map[i] = -1;
1143 else
1144 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001145 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001146 info->data = NULL;
1147 info->convert = NULL;
1148 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001149 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001150 Py_DECREF(_u_string);
1151 return result;
1152}
1153
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001154
1155static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001156newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001157{
1158 int i;
1159 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001160
Martin v. Löwis894258c2001-09-23 10:20:10 +00001161#ifdef Py_TPFLAGS_HAVE_GC
1162 /* Code for versions 2.2 and later */
1163 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1164#else
Fred Drake0582df92000-07-12 04:49:00 +00001165 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001166#endif
Fred Drake0582df92000-07-12 04:49:00 +00001167 if (self == NULL)
1168 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001169
Fred Drake2a3d7db2002-06-28 22:56:48 +00001170 self->buffer = NULL;
1171 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1172 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001173 self->ordered_attributes = 0;
1174 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001175 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001176 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001177 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001178 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001179 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1180 }
Fred Drake85d835f2001-02-08 15:39:08 +00001181 else {
Fred Drake0582df92000-07-12 04:49:00 +00001182 self->itself = XML_ParserCreate(encoding);
1183 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001184 self->intern = intern;
1185 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001186#ifdef Py_TPFLAGS_HAVE_GC
1187 PyObject_GC_Track(self);
1188#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001189 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001190#endif
Fred Drake0582df92000-07-12 04:49:00 +00001191 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001192 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001193 "XML_ParserCreate failed");
1194 Py_DECREF(self);
1195 return NULL;
1196 }
1197 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001198 XML_SetUnknownEncodingHandler(self->itself,
1199 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001200
Fred Drake2a3d7db2002-06-28 22:56:48 +00001201 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001202 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001203
Fred Drake7c75bf22002-07-01 14:02:31 +00001204 self->handlers = malloc(sizeof(PyObject *) * i);
1205 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001206 Py_DECREF(self);
1207 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001208 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001209 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001210
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001211 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001212}
1213
1214
1215static void
Fred Drake0582df92000-07-12 04:49:00 +00001216xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001217{
Fred Drake0582df92000-07-12 04:49:00 +00001218 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001219#ifdef Py_TPFLAGS_HAVE_GC
1220 PyObject_GC_UnTrack(self);
1221#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001222 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001223#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001224 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001225 XML_ParserFree(self->itself);
1226 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001227
Fred Drake85d835f2001-02-08 15:39:08 +00001228 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001229 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001230 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001231 temp = self->handlers[i];
1232 self->handlers[i] = NULL;
1233 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001234 }
1235 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001236 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001237 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001238 if (self->buffer != NULL) {
1239 free(self->buffer);
1240 self->buffer = NULL;
1241 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001242 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001243#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001244 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001245 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001246#else
1247 /* Code for versions 2.2 and later. */
1248 PyObject_GC_Del(self);
1249#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001250}
1251
Fred Drake0582df92000-07-12 04:49:00 +00001252static int
1253handlername2int(const char *name)
1254{
1255 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001256 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001257 if (strcmp(name, handler_info[i].name) == 0) {
1258 return i;
1259 }
1260 }
1261 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001262}
1263
1264static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001265get_pybool(int istrue)
1266{
1267 PyObject *result = istrue ? Py_True : Py_False;
1268 Py_INCREF(result);
1269 return result;
1270}
1271
1272static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001273xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001274{
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001275 char *name = "";
1276 int handlernum = -1;
1277
1278 if (PyUnicode_Check(nameobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 name = _PyUnicode_AsString(nameobj);
1280
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001281 handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001282
1283 if (handlernum != -1) {
1284 PyObject *result = self->handlers[handlernum];
1285 if (result == NULL)
1286 result = Py_None;
1287 Py_INCREF(result);
1288 return result;
1289 }
1290 if (name[0] == 'E') {
1291 if (strcmp(name, "ErrorCode") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001292 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001293 XML_GetErrorCode(self->itself));
1294 if (strcmp(name, "ErrorLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001295 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001296 XML_GetErrorLineNumber(self->itself));
1297 if (strcmp(name, "ErrorColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001298 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001299 XML_GetErrorColumnNumber(self->itself));
1300 if (strcmp(name, "ErrorByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001301 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001302 XML_GetErrorByteIndex(self->itself));
1303 }
Dave Cole3203efb2004-08-26 00:37:31 +00001304 if (name[0] == 'C') {
1305 if (strcmp(name, "CurrentLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001306 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001307 XML_GetCurrentLineNumber(self->itself));
1308 if (strcmp(name, "CurrentColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001309 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001310 XML_GetCurrentColumnNumber(self->itself));
1311 if (strcmp(name, "CurrentByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001312 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001313 XML_GetCurrentByteIndex(self->itself));
1314 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001315 if (name[0] == 'b') {
1316 if (strcmp(name, "buffer_size") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001317 return PyLong_FromLong((long) self->buffer_size);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001318 if (strcmp(name, "buffer_text") == 0)
1319 return get_pybool(self->buffer != NULL);
1320 if (strcmp(name, "buffer_used") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001321 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001322 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001323 if (strcmp(name, "namespace_prefixes") == 0)
1324 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001325 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001326 return get_pybool(self->ordered_attributes);
Fred Drake85d835f2001-02-08 15:39:08 +00001327 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001328 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001329 if (strcmp(name, "intern") == 0) {
1330 if (self->intern == NULL) {
1331 Py_INCREF(Py_None);
1332 return Py_None;
1333 }
1334 else {
1335 Py_INCREF(self->intern);
1336 return self->intern;
1337 }
1338 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001339
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001340 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001341}
1342
1343static PyObject *
1344xmlparse_dir(PyObject *self, PyObject* noargs)
1345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346#define APPEND(list, str) \
1347 do { \
1348 PyObject *o = PyUnicode_FromString(str); \
1349 if (o != NULL) \
1350 PyList_Append(list, o); \
1351 Py_XDECREF(o); \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001352 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001353
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001354 int i;
1355 PyObject *rc = PyList_New(0);
1356 if (!rc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 return NULL;
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001358 for (i = 0; handler_info[i].name != NULL; i++) {
1359 PyObject *o = get_handler_name(&handler_info[i]);
1360 if (o != NULL)
1361 PyList_Append(rc, o);
1362 Py_XDECREF(o);
1363 }
1364 APPEND(rc, "ErrorCode");
1365 APPEND(rc, "ErrorLineNumber");
1366 APPEND(rc, "ErrorColumnNumber");
1367 APPEND(rc, "ErrorByteIndex");
1368 APPEND(rc, "CurrentLineNumber");
1369 APPEND(rc, "CurrentColumnNumber");
1370 APPEND(rc, "CurrentByteIndex");
1371 APPEND(rc, "buffer_size");
1372 APPEND(rc, "buffer_text");
1373 APPEND(rc, "buffer_used");
1374 APPEND(rc, "namespace_prefixes");
1375 APPEND(rc, "ordered_attributes");
1376 APPEND(rc, "specified_attributes");
1377 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001378
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001379#undef APPEND
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001380
1381 if (PyErr_Occurred()) {
1382 Py_DECREF(rc);
1383 rc = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001384 }
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001385
1386 return rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001387}
1388
Fred Drake6f987622000-08-25 18:03:30 +00001389static int
1390sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001391{
1392 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001393 if (handlernum >= 0) {
1394 xmlhandler c_handler = NULL;
1395 PyObject *temp = self->handlers[handlernum];
1396
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001397 if (v == Py_None) {
1398 /* If this is the character data handler, and a character
1399 data handler is already active, we need to be more
1400 careful. What we can safely do is replace the existing
1401 character data handler callback function with a no-op
1402 function that will refuse to call Python. The downside
1403 is that this doesn't completely remove the character
1404 data handler from the C layer if there's any callback
1405 active, so Expat does a little more work than it
1406 otherwise would, but that's really an odd case. A more
1407 elaborate system of handlers and state could remove the
1408 C handler more effectively. */
1409 if (handlernum == CharacterData && self->in_callback)
1410 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001411 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001412 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001413 else if (v != NULL) {
1414 Py_INCREF(v);
1415 c_handler = handler_info[handlernum].handler;
1416 }
Fred Drake0582df92000-07-12 04:49:00 +00001417 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001418 Py_XDECREF(temp);
1419 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001420 return 1;
1421 }
1422 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001423}
1424
1425static int
Fred Drake6f987622000-08-25 18:03:30 +00001426xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001427{
Fred Drake6f987622000-08-25 18:03:30 +00001428 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001429 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001430 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1431 return -1;
1432 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001433 if (strcmp(name, "buffer_text") == 0) {
1434 if (PyObject_IsTrue(v)) {
1435 if (self->buffer == NULL) {
1436 self->buffer = malloc(self->buffer_size);
1437 if (self->buffer == NULL) {
1438 PyErr_NoMemory();
1439 return -1;
1440 }
1441 self->buffer_used = 0;
1442 }
1443 }
1444 else if (self->buffer != NULL) {
1445 if (flush_character_buffer(self) < 0)
1446 return -1;
1447 free(self->buffer);
1448 self->buffer = NULL;
1449 }
1450 return 0;
1451 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001452 if (strcmp(name, "namespace_prefixes") == 0) {
1453 if (PyObject_IsTrue(v))
1454 self->ns_prefixes = 1;
1455 else
1456 self->ns_prefixes = 0;
1457 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1458 return 0;
1459 }
Fred Drake85d835f2001-02-08 15:39:08 +00001460 if (strcmp(name, "ordered_attributes") == 0) {
1461 if (PyObject_IsTrue(v))
1462 self->ordered_attributes = 1;
1463 else
1464 self->ordered_attributes = 0;
1465 return 0;
1466 }
Fred Drake85d835f2001-02-08 15:39:08 +00001467 if (strcmp(name, "specified_attributes") == 0) {
1468 if (PyObject_IsTrue(v))
1469 self->specified_attributes = 1;
1470 else
1471 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001472 return 0;
1473 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001474
1475 if (strcmp(name, "buffer_size") == 0) {
1476 long new_buffer_size;
1477 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1479 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001480 }
1481
1482 new_buffer_size=PyLong_AS_LONG(v);
1483 /* trivial case -- no change */
1484 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001486 }
1487
1488 if (new_buffer_size <= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1490 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001491 }
1492
1493 /* check maximum */
1494 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 char errmsg[100];
1496 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1497 PyErr_SetString(PyExc_ValueError, errmsg);
1498 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001499 }
1500
1501 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 /* there is already a buffer */
1503 if (self->buffer_used != 0) {
1504 flush_character_buffer(self);
1505 }
1506 /* free existing buffer */
1507 free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001508 }
1509 self->buffer = malloc(new_buffer_size);
1510 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 PyErr_NoMemory();
1512 return -1;
1513 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001514 self->buffer_size = new_buffer_size;
1515 return 0;
1516 }
1517
Fred Drake2a3d7db2002-06-28 22:56:48 +00001518 if (strcmp(name, "CharacterDataHandler") == 0) {
1519 /* If we're changing the character data handler, flush all
1520 * cached data with the old handler. Not sure there's a
1521 * "right" thing to do, though, but this probably won't
1522 * happen.
1523 */
1524 if (flush_character_buffer(self) < 0)
1525 return -1;
1526 }
Fred Drake6f987622000-08-25 18:03:30 +00001527 if (sethandler(self, name, v)) {
1528 return 0;
1529 }
1530 PyErr_SetString(PyExc_AttributeError, name);
1531 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001532}
1533
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001534static int
1535xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1536{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001537 int i;
1538 for (i = 0; handler_info[i].name != NULL; i++)
1539 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001540 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001541}
1542
1543static int
1544xmlparse_clear(xmlparseobject *op)
1545{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001546 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001547 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001548 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001549}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001551PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001552
1553static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 PyVarObject_HEAD_INIT(NULL, 0)
1555 "pyexpat.xmlparser", /*tp_name*/
1556 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
1557 0, /*tp_itemsize*/
1558 /* methods */
1559 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1560 (printfunc)0, /*tp_print*/
1561 0, /*tp_getattr*/
1562 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1563 0, /*tp_reserved*/
1564 (reprfunc)0, /*tp_repr*/
1565 0, /*tp_as_number*/
1566 0, /*tp_as_sequence*/
1567 0, /*tp_as_mapping*/
1568 (hashfunc)0, /*tp_hash*/
1569 (ternaryfunc)0, /*tp_call*/
1570 (reprfunc)0, /*tp_str*/
1571 (getattrofunc)xmlparse_getattro, /* tp_getattro */
1572 0, /* tp_setattro */
1573 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001574#ifdef Py_TPFLAGS_HAVE_GC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001576#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001578#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1580 (traverseproc)xmlparse_traverse, /* tp_traverse */
1581 (inquiry)xmlparse_clear, /* tp_clear */
1582 0, /* tp_richcompare */
1583 0, /* tp_weaklistoffset */
1584 0, /* tp_iter */
1585 0, /* tp_iternext */
1586 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001587};
1588
1589/* End of code for xmlparser objects */
1590/* -------------------------------------------------------- */
1591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001592PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001593"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001594Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001595
1596static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001597pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1598{
Fred Drakecde79132001-04-25 16:01:30 +00001599 char *encoding = NULL;
1600 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001601 PyObject *intern = NULL;
1602 PyObject *result;
1603 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001604 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001605 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001606
Fred Drakeb91a36b2002-06-27 19:40:48 +00001607 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1608 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001609 return NULL;
1610 if (namespace_separator != NULL
1611 && strlen(namespace_separator) > 1) {
1612 PyErr_SetString(PyExc_ValueError,
1613 "namespace_separator must be at most one"
1614 " character, omitted, or None");
1615 return NULL;
1616 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001617 /* Explicitly passing None means no interning is desired.
1618 Not passing anything means that a new dictionary is used. */
1619 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001621 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 intern = PyDict_New();
1623 if (!intern)
1624 return NULL;
1625 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001626 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001627 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1629 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001630 }
1631
1632 result = newxmlparseobject(encoding, namespace_separator, intern);
1633 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001635 }
1636 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001637}
1638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001640"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001641Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001642
1643static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001644pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001645{
Fred Drake0582df92000-07-12 04:49:00 +00001646 long code = 0;
1647
1648 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1649 return NULL;
1650 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001651}
1652
1653/* List of methods defined in the module */
1654
1655static struct PyMethodDef pyexpat_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
Fred Drake0582df92000-07-12 04:49:00 +00001657 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1659 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001662};
1663
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001664/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001665
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001666PyDoc_STRVAR(pyexpat_module_documentation,
1667"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001668
Fred Drake4113b132001-03-24 19:58:26 +00001669/* Return a Python string that represents the version number without the
1670 * extra cruft added by revision control, even if the right options were
1671 * given to the "cvs export" command to make it not include the extra
1672 * cruft.
1673 */
1674static PyObject *
1675get_version_string(void)
1676{
1677 static char *rcsid = "$Revision$";
1678 char *rev = rcsid;
1679 int i = 0;
1680
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001681 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001682 ++rev;
1683 while (rev[i] != ' ' && rev[i] != '\0')
1684 ++i;
1685
Neal Norwitz392c5be2007-08-25 17:20:32 +00001686 return PyUnicode_FromStringAndSize(rev, i);
Fred Drake4113b132001-03-24 19:58:26 +00001687}
1688
Fred Drakecde79132001-04-25 16:01:30 +00001689/* Initialization function for the module */
1690
1691#ifndef MODULE_NAME
1692#define MODULE_NAME "pyexpat"
1693#endif
1694
1695#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001696#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00001697#endif
1698
Martin v. Löwis069dde22003-01-21 10:58:18 +00001699#ifndef PyMODINIT_FUNC
1700# ifdef MS_WINDOWS
1701# define PyMODINIT_FUNC __declspec(dllexport) void
1702# else
1703# define PyMODINIT_FUNC void
1704# endif
1705#endif
1706
Mark Hammond8235ea12002-07-19 06:55:41 +00001707PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001708
Martin v. Löwis1a214512008-06-11 05:26:20 +00001709static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 PyModuleDef_HEAD_INIT,
1711 MODULE_NAME,
1712 pyexpat_module_documentation,
1713 -1,
1714 pyexpat_methods,
1715 NULL,
1716 NULL,
1717 NULL,
1718 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001719};
1720
Martin v. Löwis069dde22003-01-21 10:58:18 +00001721PyMODINIT_FUNC
1722MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001723{
1724 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001725 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001726 PyObject *errors_module;
1727 PyObject *modelmod_name;
1728 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001729 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001730 static struct PyExpat_CAPI capi;
1731 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001732
Fred Drake6f987622000-08-25 18:03:30 +00001733 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001734 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001735 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001736 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001737 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00001738
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001739 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001741
Fred Drake0582df92000-07-12 04:49:00 +00001742 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001743 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001744 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001746
Fred Drake0582df92000-07-12 04:49:00 +00001747 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001748 if (ErrorObject == NULL) {
1749 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001750 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001751 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001752 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001753 }
1754 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001755 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001756 Py_INCREF(ErrorObject);
1757 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001758 Py_INCREF(&Xmlparsetype);
1759 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001760
Fred Drake4113b132001-03-24 19:58:26 +00001761 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001762 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1763 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001764 {
1765 XML_Expat_Version info = XML_ExpatVersionInfo();
1766 PyModule_AddObject(m, "version_info",
1767 Py_BuildValue("(iii)", info.major,
1768 info.minor, info.micro));
1769 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001770 init_template_buffer();
Fred Drake0582df92000-07-12 04:49:00 +00001771 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001772 compiled, this should check and set native_encoding
1773 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001774 */
Fred Drake93adb692000-09-23 04:55:48 +00001775 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001776
Fred Drake85d835f2001-02-08 15:39:08 +00001777 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001778 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001779 errors_module = PyDict_GetItem(d, errmod_name);
1780 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001781 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001782 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001783 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001784 /* gives away the reference to errors_module */
1785 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001786 }
1787 }
Fred Drake6f987622000-08-25 18:03:30 +00001788 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001789 model_module = PyDict_GetItem(d, modelmod_name);
1790 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001791 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001792 if (model_module != NULL) {
1793 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1794 /* gives away the reference to model_module */
1795 PyModule_AddObject(m, "model", model_module);
1796 }
1797 }
1798 Py_DECREF(modelmod_name);
1799 if (errors_module == NULL || model_module == NULL)
1800 /* Don't core dump later! */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001801 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802
Martin v. Löwisc847f402003-01-21 11:09:21 +00001803#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001804 {
1805 const XML_Feature *features = XML_GetFeatureList();
1806 PyObject *list = PyList_New(0);
1807 if (list == NULL)
1808 /* just ignore it */
1809 PyErr_Clear();
1810 else {
1811 int i = 0;
1812 for (; features[i].feature != XML_FEATURE_END; ++i) {
1813 int ok;
1814 PyObject *item = Py_BuildValue("si", features[i].name,
1815 features[i].value);
1816 if (item == NULL) {
1817 Py_DECREF(list);
1818 list = NULL;
1819 break;
1820 }
1821 ok = PyList_Append(list, item);
1822 Py_DECREF(item);
1823 if (ok < 0) {
1824 PyErr_Clear();
1825 break;
1826 }
1827 }
1828 if (list != NULL)
1829 PyModule_AddObject(m, "features", list);
1830 }
1831 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001832#endif
Fred Drake6f987622000-08-25 18:03:30 +00001833
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001834#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001835 PyModule_AddStringConstant(errors_module, #name, \
1836 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001837
Fred Drake0582df92000-07-12 04:49:00 +00001838 MYCONST(XML_ERROR_NO_MEMORY);
1839 MYCONST(XML_ERROR_SYNTAX);
1840 MYCONST(XML_ERROR_NO_ELEMENTS);
1841 MYCONST(XML_ERROR_INVALID_TOKEN);
1842 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1843 MYCONST(XML_ERROR_PARTIAL_CHAR);
1844 MYCONST(XML_ERROR_TAG_MISMATCH);
1845 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1846 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1847 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1848 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1849 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1850 MYCONST(XML_ERROR_ASYNC_ENTITY);
1851 MYCONST(XML_ERROR_BAD_CHAR_REF);
1852 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1853 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1854 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1855 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1856 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001857 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1858 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1859 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001860 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1861 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1862 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1863 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1864 /* Added in Expat 1.95.7. */
1865 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1866 /* Added in Expat 1.95.8. */
1867 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1868 MYCONST(XML_ERROR_INCOMPLETE_PE);
1869 MYCONST(XML_ERROR_XML_DECL);
1870 MYCONST(XML_ERROR_TEXT_DECL);
1871 MYCONST(XML_ERROR_PUBLICID);
1872 MYCONST(XML_ERROR_SUSPENDED);
1873 MYCONST(XML_ERROR_NOT_SUSPENDED);
1874 MYCONST(XML_ERROR_ABORTED);
1875 MYCONST(XML_ERROR_FINISHED);
1876 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001877
Fred Drake85d835f2001-02-08 15:39:08 +00001878 PyModule_AddStringConstant(errors_module, "__doc__",
1879 "Constants used to describe error conditions.");
1880
Fred Drake93adb692000-09-23 04:55:48 +00001881#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001882
Fred Drake85d835f2001-02-08 15:39:08 +00001883#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001884 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1885 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1886 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001887#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001888
Fred Drake85d835f2001-02-08 15:39:08 +00001889#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1890 PyModule_AddStringConstant(model_module, "__doc__",
1891 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001892
Fred Drake85d835f2001-02-08 15:39:08 +00001893 MYCONST(XML_CTYPE_EMPTY);
1894 MYCONST(XML_CTYPE_ANY);
1895 MYCONST(XML_CTYPE_MIXED);
1896 MYCONST(XML_CTYPE_NAME);
1897 MYCONST(XML_CTYPE_CHOICE);
1898 MYCONST(XML_CTYPE_SEQ);
1899
1900 MYCONST(XML_CQUANT_NONE);
1901 MYCONST(XML_CQUANT_OPT);
1902 MYCONST(XML_CQUANT_REP);
1903 MYCONST(XML_CQUANT_PLUS);
1904#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001905
1906 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001907 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001908 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001909 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1910 capi.MINOR_VERSION = XML_MINOR_VERSION;
1911 capi.MICRO_VERSION = XML_MICRO_VERSION;
1912 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001913 capi.GetErrorCode = XML_GetErrorCode;
1914 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1915 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001916 capi.Parse = XML_Parse;
1917 capi.ParserCreate_MM = XML_ParserCreate_MM;
1918 capi.ParserFree = XML_ParserFree;
1919 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1920 capi.SetCommentHandler = XML_SetCommentHandler;
1921 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1922 capi.SetElementHandler = XML_SetElementHandler;
1923 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1924 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1925 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1926 capi.SetUserData = XML_SetUserData;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927
Benjamin Petersonb173f782009-05-05 22:31:58 +00001928 /* export using capsule */
1929 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001930 if (capi_object)
1931 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001932 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001933}
1934
Fred Drake6f987622000-08-25 18:03:30 +00001935static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001936clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001937{
Fred Drakecde79132001-04-25 16:01:30 +00001938 int i = 0;
1939 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001940
Fred Drake71b63ff2002-06-28 22:29:01 +00001941 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001942 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 self->handlers[i] = NULL;
1944 else {
Fred Drakecde79132001-04-25 16:01:30 +00001945 temp = self->handlers[i];
1946 self->handlers[i] = NULL;
1947 Py_XDECREF(temp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00001949 }
Fred Drakecde79132001-04-25 16:01:30 +00001950 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001951}
1952
Tim Peters0c322792002-07-17 16:49:03 +00001953static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00001954 {"StartElementHandler",
1955 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001956 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001957 {"EndElementHandler",
1958 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001959 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001960 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001961 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1962 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001963 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001964 (xmlhandlersetter)XML_SetCharacterDataHandler,
1965 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001966 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001967 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001968 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001969 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001970 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001971 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001972 {"StartNamespaceDeclHandler",
1973 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001974 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001975 {"EndNamespaceDeclHandler",
1976 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001977 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00001978 {"CommentHandler",
1979 (xmlhandlersetter)XML_SetCommentHandler,
1980 (xmlhandler)my_CommentHandler},
1981 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001982 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001983 (xmlhandler)my_StartCdataSectionHandler},
1984 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001985 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001986 (xmlhandler)my_EndCdataSectionHandler},
1987 {"DefaultHandler",
1988 (xmlhandlersetter)XML_SetDefaultHandler,
1989 (xmlhandler)my_DefaultHandler},
1990 {"DefaultHandlerExpand",
1991 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1992 (xmlhandler)my_DefaultHandlerExpandHandler},
1993 {"NotStandaloneHandler",
1994 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1995 (xmlhandler)my_NotStandaloneHandler},
1996 {"ExternalEntityRefHandler",
1997 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001998 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001999 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002000 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002001 (xmlhandler)my_StartDoctypeDeclHandler},
2002 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002003 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002004 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002005 {"EntityDeclHandler",
2006 (xmlhandlersetter)XML_SetEntityDeclHandler,
2007 (xmlhandler)my_EntityDeclHandler},
2008 {"XmlDeclHandler",
2009 (xmlhandlersetter)XML_SetXmlDeclHandler,
2010 (xmlhandler)my_XmlDeclHandler},
2011 {"ElementDeclHandler",
2012 (xmlhandlersetter)XML_SetElementDeclHandler,
2013 (xmlhandler)my_ElementDeclHandler},
2014 {"AttlistDeclHandler",
2015 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2016 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002017#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002018 {"SkippedEntityHandler",
2019 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2020 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002021#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002022
Fred Drake0582df92000-07-12 04:49:00 +00002023 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002024};