blob: 165343207cd481b69cd8746179df95665ea39167 [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;
976 if (self->buffer != NULL) {
977 new_parser->buffer = malloc(new_parser->buffer_size);
978 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +0000979#ifndef Py_TPFLAGS_HAVE_GC
980 /* Code for versions 2.0 and 2.1 */
981 PyObject_Del(new_parser);
982#else
983 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +0000984 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +0000985#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +0000986 return PyErr_NoMemory();
987 }
988 }
989 else
990 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000991 new_parser->ordered_attributes = self->ordered_attributes;
992 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +0000993 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000994 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000995 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000997 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000998 new_parser->intern = self->intern;
999 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001000#ifdef Py_TPFLAGS_HAVE_GC
1001 PyObject_GC_Track(new_parser);
1002#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001003 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001004#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001005
1006 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001007 Py_DECREF(new_parser);
1008 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001009 }
1010
1011 XML_SetUserData(new_parser->itself, (void *)new_parser);
1012
1013 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001014 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001015 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001016
Fred Drake2a3d7db2002-06-28 22:56:48 +00001017 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001018 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001019 Py_DECREF(new_parser);
1020 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001021 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001022 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001023
1024 /* then copy handlers from self */
1025 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001026 PyObject *handler = self->handlers[i];
1027 if (handler != NULL) {
1028 Py_INCREF(handler);
1029 new_parser->handlers[i] = handler;
1030 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001031 handler_info[i].handler);
1032 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001033 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001034 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001035}
1036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001037PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001038"SetParamEntityParsing(flag) -> success\n\
1039Controls parsing of parameter entities (including the external DTD\n\
1040subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1041XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1042XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001043was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001044
1045static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001046xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001047{
Fred Drake85d835f2001-02-08 15:39:08 +00001048 int flag;
1049 if (!PyArg_ParseTuple(args, "i", &flag))
1050 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001051 flag = XML_SetParamEntityParsing(p->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +00001052 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001053}
1054
Martin v. Löwisc847f402003-01-21 11:09:21 +00001055
1056#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001057PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1058"UseForeignDTD([flag])\n\
1059Allows the application to provide an artificial external subset if one is\n\
1060not specified as part of the document instance. This readily allows the\n\
1061use of a 'default' document type controlled by the application, while still\n\
1062getting the advantage of providing document type information to the parser.\n\
1063'flag' defaults to True if not provided.");
1064
1065static PyObject *
1066xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1067{
1068 PyObject *flagobj = NULL;
1069 XML_Bool flag = XML_TRUE;
1070 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001071 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001072 return NULL;
1073 if (flagobj != NULL)
1074 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1075 rc = XML_UseForeignDTD(self->itself, flag);
1076 if (rc != XML_ERROR_NONE) {
1077 return set_error(self, rc);
1078 }
1079 Py_INCREF(Py_None);
1080 return Py_None;
1081}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001082#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001083
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001084static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs);
1085
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001086static struct PyMethodDef xmlparse_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 {"Parse", (PyCFunction)xmlparse_Parse,
1088 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001089 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001091 {"SetBase", (PyCFunction)xmlparse_SetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001093 {"GetBase", (PyCFunction)xmlparse_GetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001095 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001097 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001099 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001101#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001102 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001104#endif
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001105 {"__dir__", xmlparse_dir, METH_NOARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001107};
1108
1109/* ---------- */
1110
1111
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001112
Fred Drake71b63ff2002-06-28 22:29:01 +00001113/* pyexpat international encoding support.
1114 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001115*/
1116
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001117static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001118
Fred Drake71b63ff2002-06-28 22:29:01 +00001119static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001120init_template_buffer(void)
1121{
1122 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001123 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001125 }
Fred Drakebb66a202001-03-01 20:48:17 +00001126 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001127}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001128
Fred Drake71b63ff2002-06-28 22:29:01 +00001129static int
1130PyUnknownEncodingHandler(void *encodingHandlerData,
1131 const XML_Char *name,
1132 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001133{
Fred Drakebb66a202001-03-01 20:48:17 +00001134 PyUnicodeObject *_u_string = NULL;
1135 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001136 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001137
Fred Drakebb66a202001-03-01 20:48:17 +00001138 /* Yes, supports only 8bit encodings */
1139 _u_string = (PyUnicodeObject *)
1140 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001141
Fred Drakebb66a202001-03-01 20:48:17 +00001142 if (_u_string == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001144
Fred Drakebb66a202001-03-01 20:48:17 +00001145 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 /* Stupid to access directly, but fast */
1147 Py_UNICODE c = _u_string->str[i];
1148 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
1149 info->map[i] = -1;
1150 else
1151 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001152 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001153 info->data = NULL;
1154 info->convert = NULL;
1155 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001156 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001157 Py_DECREF(_u_string);
1158 return result;
1159}
1160
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001161
1162static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001163newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001164{
1165 int i;
1166 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001167
Martin v. Löwis894258c2001-09-23 10:20:10 +00001168#ifdef Py_TPFLAGS_HAVE_GC
1169 /* Code for versions 2.2 and later */
1170 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1171#else
Fred Drake0582df92000-07-12 04:49:00 +00001172 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001173#endif
Fred Drake0582df92000-07-12 04:49:00 +00001174 if (self == NULL)
1175 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001176
Fred Drake2a3d7db2002-06-28 22:56:48 +00001177 self->buffer = NULL;
1178 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1179 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001180 self->ordered_attributes = 0;
1181 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001182 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001183 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001184 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001185 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001186 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1187 }
Fred Drake85d835f2001-02-08 15:39:08 +00001188 else {
Fred Drake0582df92000-07-12 04:49:00 +00001189 self->itself = XML_ParserCreate(encoding);
1190 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001191 self->intern = intern;
1192 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001193#ifdef Py_TPFLAGS_HAVE_GC
1194 PyObject_GC_Track(self);
1195#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001196 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001197#endif
Fred Drake0582df92000-07-12 04:49:00 +00001198 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001199 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001200 "XML_ParserCreate failed");
1201 Py_DECREF(self);
1202 return NULL;
1203 }
1204 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001205 XML_SetUnknownEncodingHandler(self->itself,
1206 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001207
Fred Drake2a3d7db2002-06-28 22:56:48 +00001208 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001209 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001210
Fred Drake7c75bf22002-07-01 14:02:31 +00001211 self->handlers = malloc(sizeof(PyObject *) * i);
1212 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001213 Py_DECREF(self);
1214 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001215 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001216 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001217
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001218 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001219}
1220
1221
1222static void
Fred Drake0582df92000-07-12 04:49:00 +00001223xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001224{
Fred Drake0582df92000-07-12 04:49:00 +00001225 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001226#ifdef Py_TPFLAGS_HAVE_GC
1227 PyObject_GC_UnTrack(self);
1228#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001229 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001230#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001231 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001232 XML_ParserFree(self->itself);
1233 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001234
Fred Drake85d835f2001-02-08 15:39:08 +00001235 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001236 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001237 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001238 temp = self->handlers[i];
1239 self->handlers[i] = NULL;
1240 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001241 }
1242 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001243 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001244 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001245 if (self->buffer != NULL) {
1246 free(self->buffer);
1247 self->buffer = NULL;
1248 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001249 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001250#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001251 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001252 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001253#else
1254 /* Code for versions 2.2 and later. */
1255 PyObject_GC_Del(self);
1256#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001257}
1258
Fred Drake0582df92000-07-12 04:49:00 +00001259static int
1260handlername2int(const char *name)
1261{
1262 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001263 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001264 if (strcmp(name, handler_info[i].name) == 0) {
1265 return i;
1266 }
1267 }
1268 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001269}
1270
1271static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001272get_pybool(int istrue)
1273{
1274 PyObject *result = istrue ? Py_True : Py_False;
1275 Py_INCREF(result);
1276 return result;
1277}
1278
1279static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001280xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001281{
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001282 char *name = "";
1283 int handlernum = -1;
1284
1285 if (PyUnicode_Check(nameobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 name = _PyUnicode_AsString(nameobj);
1287
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001288 handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001289
1290 if (handlernum != -1) {
1291 PyObject *result = self->handlers[handlernum];
1292 if (result == NULL)
1293 result = Py_None;
1294 Py_INCREF(result);
1295 return result;
1296 }
1297 if (name[0] == 'E') {
1298 if (strcmp(name, "ErrorCode") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001299 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001300 XML_GetErrorCode(self->itself));
1301 if (strcmp(name, "ErrorLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001302 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001303 XML_GetErrorLineNumber(self->itself));
1304 if (strcmp(name, "ErrorColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001305 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001306 XML_GetErrorColumnNumber(self->itself));
1307 if (strcmp(name, "ErrorByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001308 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001309 XML_GetErrorByteIndex(self->itself));
1310 }
Dave Cole3203efb2004-08-26 00:37:31 +00001311 if (name[0] == 'C') {
1312 if (strcmp(name, "CurrentLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001313 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001314 XML_GetCurrentLineNumber(self->itself));
1315 if (strcmp(name, "CurrentColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001316 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001317 XML_GetCurrentColumnNumber(self->itself));
1318 if (strcmp(name, "CurrentByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001319 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001320 XML_GetCurrentByteIndex(self->itself));
1321 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001322 if (name[0] == 'b') {
1323 if (strcmp(name, "buffer_size") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001324 return PyLong_FromLong((long) self->buffer_size);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001325 if (strcmp(name, "buffer_text") == 0)
1326 return get_pybool(self->buffer != NULL);
1327 if (strcmp(name, "buffer_used") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001328 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001329 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001330 if (strcmp(name, "namespace_prefixes") == 0)
1331 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001332 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001333 return get_pybool(self->ordered_attributes);
Fred Drake85d835f2001-02-08 15:39:08 +00001334 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001335 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001336 if (strcmp(name, "intern") == 0) {
1337 if (self->intern == NULL) {
1338 Py_INCREF(Py_None);
1339 return Py_None;
1340 }
1341 else {
1342 Py_INCREF(self->intern);
1343 return self->intern;
1344 }
1345 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001346
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001347 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001348}
1349
1350static PyObject *
1351xmlparse_dir(PyObject *self, PyObject* noargs)
1352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353#define APPEND(list, str) \
1354 do { \
1355 PyObject *o = PyUnicode_FromString(str); \
1356 if (o != NULL) \
1357 PyList_Append(list, o); \
1358 Py_XDECREF(o); \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001359 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001360
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001361 int i;
1362 PyObject *rc = PyList_New(0);
1363 if (!rc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 return NULL;
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001365 for (i = 0; handler_info[i].name != NULL; i++) {
1366 PyObject *o = get_handler_name(&handler_info[i]);
1367 if (o != NULL)
1368 PyList_Append(rc, o);
1369 Py_XDECREF(o);
1370 }
1371 APPEND(rc, "ErrorCode");
1372 APPEND(rc, "ErrorLineNumber");
1373 APPEND(rc, "ErrorColumnNumber");
1374 APPEND(rc, "ErrorByteIndex");
1375 APPEND(rc, "CurrentLineNumber");
1376 APPEND(rc, "CurrentColumnNumber");
1377 APPEND(rc, "CurrentByteIndex");
1378 APPEND(rc, "buffer_size");
1379 APPEND(rc, "buffer_text");
1380 APPEND(rc, "buffer_used");
1381 APPEND(rc, "namespace_prefixes");
1382 APPEND(rc, "ordered_attributes");
1383 APPEND(rc, "specified_attributes");
1384 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001385
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001386#undef APPEND
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001387
1388 if (PyErr_Occurred()) {
1389 Py_DECREF(rc);
1390 rc = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001391 }
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001392
1393 return rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001394}
1395
Fred Drake6f987622000-08-25 18:03:30 +00001396static int
1397sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001398{
1399 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001400 if (handlernum >= 0) {
1401 xmlhandler c_handler = NULL;
1402 PyObject *temp = self->handlers[handlernum];
1403
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001404 if (v == Py_None) {
1405 /* If this is the character data handler, and a character
1406 data handler is already active, we need to be more
1407 careful. What we can safely do is replace the existing
1408 character data handler callback function with a no-op
1409 function that will refuse to call Python. The downside
1410 is that this doesn't completely remove the character
1411 data handler from the C layer if there's any callback
1412 active, so Expat does a little more work than it
1413 otherwise would, but that's really an odd case. A more
1414 elaborate system of handlers and state could remove the
1415 C handler more effectively. */
1416 if (handlernum == CharacterData && self->in_callback)
1417 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001418 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001419 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001420 else if (v != NULL) {
1421 Py_INCREF(v);
1422 c_handler = handler_info[handlernum].handler;
1423 }
Fred Drake0582df92000-07-12 04:49:00 +00001424 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001425 Py_XDECREF(temp);
1426 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001427 return 1;
1428 }
1429 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001430}
1431
1432static int
Fred Drake6f987622000-08-25 18:03:30 +00001433xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001434{
Fred Drake6f987622000-08-25 18:03:30 +00001435 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001436 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001437 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1438 return -1;
1439 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001440 if (strcmp(name, "buffer_text") == 0) {
1441 if (PyObject_IsTrue(v)) {
1442 if (self->buffer == NULL) {
1443 self->buffer = malloc(self->buffer_size);
1444 if (self->buffer == NULL) {
1445 PyErr_NoMemory();
1446 return -1;
1447 }
1448 self->buffer_used = 0;
1449 }
1450 }
1451 else if (self->buffer != NULL) {
1452 if (flush_character_buffer(self) < 0)
1453 return -1;
1454 free(self->buffer);
1455 self->buffer = NULL;
1456 }
1457 return 0;
1458 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001459 if (strcmp(name, "namespace_prefixes") == 0) {
1460 if (PyObject_IsTrue(v))
1461 self->ns_prefixes = 1;
1462 else
1463 self->ns_prefixes = 0;
1464 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1465 return 0;
1466 }
Fred Drake85d835f2001-02-08 15:39:08 +00001467 if (strcmp(name, "ordered_attributes") == 0) {
1468 if (PyObject_IsTrue(v))
1469 self->ordered_attributes = 1;
1470 else
1471 self->ordered_attributes = 0;
1472 return 0;
1473 }
Fred Drake85d835f2001-02-08 15:39:08 +00001474 if (strcmp(name, "specified_attributes") == 0) {
1475 if (PyObject_IsTrue(v))
1476 self->specified_attributes = 1;
1477 else
1478 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001479 return 0;
1480 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001481
1482 if (strcmp(name, "buffer_size") == 0) {
1483 long new_buffer_size;
1484 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1486 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001487 }
1488
1489 new_buffer_size=PyLong_AS_LONG(v);
1490 /* trivial case -- no change */
1491 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001493 }
1494
1495 if (new_buffer_size <= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1497 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001498 }
1499
1500 /* check maximum */
1501 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 char errmsg[100];
1503 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1504 PyErr_SetString(PyExc_ValueError, errmsg);
1505 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001506 }
1507
1508 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 /* there is already a buffer */
1510 if (self->buffer_used != 0) {
1511 flush_character_buffer(self);
1512 }
1513 /* free existing buffer */
1514 free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001515 }
1516 self->buffer = malloc(new_buffer_size);
1517 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 PyErr_NoMemory();
1519 return -1;
1520 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001521 self->buffer_size = new_buffer_size;
1522 return 0;
1523 }
1524
Fred Drake2a3d7db2002-06-28 22:56:48 +00001525 if (strcmp(name, "CharacterDataHandler") == 0) {
1526 /* If we're changing the character data handler, flush all
1527 * cached data with the old handler. Not sure there's a
1528 * "right" thing to do, though, but this probably won't
1529 * happen.
1530 */
1531 if (flush_character_buffer(self) < 0)
1532 return -1;
1533 }
Fred Drake6f987622000-08-25 18:03:30 +00001534 if (sethandler(self, name, v)) {
1535 return 0;
1536 }
1537 PyErr_SetString(PyExc_AttributeError, name);
1538 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001539}
1540
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001541static int
1542xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1543{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001544 int i;
1545 for (i = 0; handler_info[i].name != NULL; i++)
1546 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001547 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001548}
1549
1550static int
1551xmlparse_clear(xmlparseobject *op)
1552{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001553 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001554 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001555 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001556}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001557
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001558PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001559
1560static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 PyVarObject_HEAD_INIT(NULL, 0)
1562 "pyexpat.xmlparser", /*tp_name*/
1563 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
1564 0, /*tp_itemsize*/
1565 /* methods */
1566 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1567 (printfunc)0, /*tp_print*/
1568 0, /*tp_getattr*/
1569 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1570 0, /*tp_reserved*/
1571 (reprfunc)0, /*tp_repr*/
1572 0, /*tp_as_number*/
1573 0, /*tp_as_sequence*/
1574 0, /*tp_as_mapping*/
1575 (hashfunc)0, /*tp_hash*/
1576 (ternaryfunc)0, /*tp_call*/
1577 (reprfunc)0, /*tp_str*/
1578 (getattrofunc)xmlparse_getattro, /* tp_getattro */
1579 0, /* tp_setattro */
1580 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001581#ifdef Py_TPFLAGS_HAVE_GC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001583#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001585#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1587 (traverseproc)xmlparse_traverse, /* tp_traverse */
1588 (inquiry)xmlparse_clear, /* tp_clear */
1589 0, /* tp_richcompare */
1590 0, /* tp_weaklistoffset */
1591 0, /* tp_iter */
1592 0, /* tp_iternext */
1593 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001594};
1595
1596/* End of code for xmlparser objects */
1597/* -------------------------------------------------------- */
1598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001599PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001600"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001602
1603static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001604pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1605{
Fred Drakecde79132001-04-25 16:01:30 +00001606 char *encoding = NULL;
1607 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001608 PyObject *intern = NULL;
1609 PyObject *result;
1610 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001611 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001612 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001613
Fred Drakeb91a36b2002-06-27 19:40:48 +00001614 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1615 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001616 return NULL;
1617 if (namespace_separator != NULL
1618 && strlen(namespace_separator) > 1) {
1619 PyErr_SetString(PyExc_ValueError,
1620 "namespace_separator must be at most one"
1621 " character, omitted, or None");
1622 return NULL;
1623 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001624 /* Explicitly passing None means no interning is desired.
1625 Not passing anything means that a new dictionary is used. */
1626 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001628 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 intern = PyDict_New();
1630 if (!intern)
1631 return NULL;
1632 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001633 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001634 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1636 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001637 }
1638
1639 result = newxmlparseobject(encoding, namespace_separator, intern);
1640 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001642 }
1643 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001644}
1645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001646PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001647"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001648Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001649
1650static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001651pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001652{
Fred Drake0582df92000-07-12 04:49:00 +00001653 long code = 0;
1654
1655 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1656 return NULL;
1657 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001658}
1659
1660/* List of methods defined in the module */
1661
1662static struct PyMethodDef pyexpat_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
Fred Drake0582df92000-07-12 04:49:00 +00001664 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1666 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001669};
1670
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001671/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001673PyDoc_STRVAR(pyexpat_module_documentation,
1674"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001675
Fred Drake4113b132001-03-24 19:58:26 +00001676/* Return a Python string that represents the version number without the
1677 * extra cruft added by revision control, even if the right options were
1678 * given to the "cvs export" command to make it not include the extra
1679 * cruft.
1680 */
1681static PyObject *
1682get_version_string(void)
1683{
1684 static char *rcsid = "$Revision$";
1685 char *rev = rcsid;
1686 int i = 0;
1687
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001688 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001689 ++rev;
1690 while (rev[i] != ' ' && rev[i] != '\0')
1691 ++i;
1692
Neal Norwitz392c5be2007-08-25 17:20:32 +00001693 return PyUnicode_FromStringAndSize(rev, i);
Fred Drake4113b132001-03-24 19:58:26 +00001694}
1695
Fred Drakecde79132001-04-25 16:01:30 +00001696/* Initialization function for the module */
1697
1698#ifndef MODULE_NAME
1699#define MODULE_NAME "pyexpat"
1700#endif
1701
1702#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001703#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00001704#endif
1705
Martin v. Löwis069dde22003-01-21 10:58:18 +00001706#ifndef PyMODINIT_FUNC
1707# ifdef MS_WINDOWS
1708# define PyMODINIT_FUNC __declspec(dllexport) void
1709# else
1710# define PyMODINIT_FUNC void
1711# endif
1712#endif
1713
Mark Hammond8235ea12002-07-19 06:55:41 +00001714PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001715
Martin v. Löwis1a214512008-06-11 05:26:20 +00001716static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 PyModuleDef_HEAD_INIT,
1718 MODULE_NAME,
1719 pyexpat_module_documentation,
1720 -1,
1721 pyexpat_methods,
1722 NULL,
1723 NULL,
1724 NULL,
1725 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001726};
1727
Martin v. Löwis069dde22003-01-21 10:58:18 +00001728PyMODINIT_FUNC
1729MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001730{
1731 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001732 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001733 PyObject *errors_module;
1734 PyObject *modelmod_name;
1735 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001736 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001737 static struct PyExpat_CAPI capi;
1738 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001739
Fred Drake6f987622000-08-25 18:03:30 +00001740 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001741 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001742 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001743 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001744 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00001745
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001746 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001748
Fred Drake0582df92000-07-12 04:49:00 +00001749 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001750 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001751 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001753
Fred Drake0582df92000-07-12 04:49:00 +00001754 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001755 if (ErrorObject == NULL) {
1756 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001757 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001758 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001759 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001760 }
1761 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001762 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001763 Py_INCREF(ErrorObject);
1764 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001765 Py_INCREF(&Xmlparsetype);
1766 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001767
Fred Drake4113b132001-03-24 19:58:26 +00001768 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001769 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1770 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001771 {
1772 XML_Expat_Version info = XML_ExpatVersionInfo();
1773 PyModule_AddObject(m, "version_info",
1774 Py_BuildValue("(iii)", info.major,
1775 info.minor, info.micro));
1776 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001777 init_template_buffer();
Fred Drake0582df92000-07-12 04:49:00 +00001778 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001779 compiled, this should check and set native_encoding
1780 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001781 */
Fred Drake93adb692000-09-23 04:55:48 +00001782 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001783
Fred Drake85d835f2001-02-08 15:39:08 +00001784 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001785 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001786 errors_module = PyDict_GetItem(d, errmod_name);
1787 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001788 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001789 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001790 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001791 /* gives away the reference to errors_module */
1792 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001793 }
1794 }
Fred Drake6f987622000-08-25 18:03:30 +00001795 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001796 model_module = PyDict_GetItem(d, modelmod_name);
1797 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001798 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001799 if (model_module != NULL) {
1800 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1801 /* gives away the reference to model_module */
1802 PyModule_AddObject(m, "model", model_module);
1803 }
1804 }
1805 Py_DECREF(modelmod_name);
1806 if (errors_module == NULL || model_module == NULL)
1807 /* Don't core dump later! */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001808 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809
Martin v. Löwisc847f402003-01-21 11:09:21 +00001810#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001811 {
1812 const XML_Feature *features = XML_GetFeatureList();
1813 PyObject *list = PyList_New(0);
1814 if (list == NULL)
1815 /* just ignore it */
1816 PyErr_Clear();
1817 else {
1818 int i = 0;
1819 for (; features[i].feature != XML_FEATURE_END; ++i) {
1820 int ok;
1821 PyObject *item = Py_BuildValue("si", features[i].name,
1822 features[i].value);
1823 if (item == NULL) {
1824 Py_DECREF(list);
1825 list = NULL;
1826 break;
1827 }
1828 ok = PyList_Append(list, item);
1829 Py_DECREF(item);
1830 if (ok < 0) {
1831 PyErr_Clear();
1832 break;
1833 }
1834 }
1835 if (list != NULL)
1836 PyModule_AddObject(m, "features", list);
1837 }
1838 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001839#endif
Fred Drake6f987622000-08-25 18:03:30 +00001840
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001841#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001842 PyModule_AddStringConstant(errors_module, #name, \
1843 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001844
Fred Drake0582df92000-07-12 04:49:00 +00001845 MYCONST(XML_ERROR_NO_MEMORY);
1846 MYCONST(XML_ERROR_SYNTAX);
1847 MYCONST(XML_ERROR_NO_ELEMENTS);
1848 MYCONST(XML_ERROR_INVALID_TOKEN);
1849 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1850 MYCONST(XML_ERROR_PARTIAL_CHAR);
1851 MYCONST(XML_ERROR_TAG_MISMATCH);
1852 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1853 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1854 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1855 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1856 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1857 MYCONST(XML_ERROR_ASYNC_ENTITY);
1858 MYCONST(XML_ERROR_BAD_CHAR_REF);
1859 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1860 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1861 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1862 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1863 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001864 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1865 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1866 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001867 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1868 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1869 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1870 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1871 /* Added in Expat 1.95.7. */
1872 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1873 /* Added in Expat 1.95.8. */
1874 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1875 MYCONST(XML_ERROR_INCOMPLETE_PE);
1876 MYCONST(XML_ERROR_XML_DECL);
1877 MYCONST(XML_ERROR_TEXT_DECL);
1878 MYCONST(XML_ERROR_PUBLICID);
1879 MYCONST(XML_ERROR_SUSPENDED);
1880 MYCONST(XML_ERROR_NOT_SUSPENDED);
1881 MYCONST(XML_ERROR_ABORTED);
1882 MYCONST(XML_ERROR_FINISHED);
1883 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001884
Fred Drake85d835f2001-02-08 15:39:08 +00001885 PyModule_AddStringConstant(errors_module, "__doc__",
1886 "Constants used to describe error conditions.");
1887
Fred Drake93adb692000-09-23 04:55:48 +00001888#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001889
Fred Drake85d835f2001-02-08 15:39:08 +00001890#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001891 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1892 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1893 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001894#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001895
Fred Drake85d835f2001-02-08 15:39:08 +00001896#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1897 PyModule_AddStringConstant(model_module, "__doc__",
1898 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001899
Fred Drake85d835f2001-02-08 15:39:08 +00001900 MYCONST(XML_CTYPE_EMPTY);
1901 MYCONST(XML_CTYPE_ANY);
1902 MYCONST(XML_CTYPE_MIXED);
1903 MYCONST(XML_CTYPE_NAME);
1904 MYCONST(XML_CTYPE_CHOICE);
1905 MYCONST(XML_CTYPE_SEQ);
1906
1907 MYCONST(XML_CQUANT_NONE);
1908 MYCONST(XML_CQUANT_OPT);
1909 MYCONST(XML_CQUANT_REP);
1910 MYCONST(XML_CQUANT_PLUS);
1911#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001912
1913 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001914 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001915 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001916 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1917 capi.MINOR_VERSION = XML_MINOR_VERSION;
1918 capi.MICRO_VERSION = XML_MICRO_VERSION;
1919 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001920 capi.GetErrorCode = XML_GetErrorCode;
1921 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1922 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001923 capi.Parse = XML_Parse;
1924 capi.ParserCreate_MM = XML_ParserCreate_MM;
1925 capi.ParserFree = XML_ParserFree;
1926 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1927 capi.SetCommentHandler = XML_SetCommentHandler;
1928 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1929 capi.SetElementHandler = XML_SetElementHandler;
1930 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1931 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1932 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1933 capi.SetUserData = XML_SetUserData;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934
Benjamin Petersonb173f782009-05-05 22:31:58 +00001935 /* export using capsule */
1936 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001937 if (capi_object)
1938 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001939 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001940}
1941
Fred Drake6f987622000-08-25 18:03:30 +00001942static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001943clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001944{
Fred Drakecde79132001-04-25 16:01:30 +00001945 int i = 0;
1946 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001947
Fred Drake71b63ff2002-06-28 22:29:01 +00001948 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001949 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 self->handlers[i] = NULL;
1951 else {
Fred Drakecde79132001-04-25 16:01:30 +00001952 temp = self->handlers[i];
1953 self->handlers[i] = NULL;
1954 Py_XDECREF(temp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00001956 }
Fred Drakecde79132001-04-25 16:01:30 +00001957 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001958}
1959
Tim Peters0c322792002-07-17 16:49:03 +00001960static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00001961 {"StartElementHandler",
1962 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001963 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001964 {"EndElementHandler",
1965 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001966 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001967 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001968 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1969 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001970 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001971 (xmlhandlersetter)XML_SetCharacterDataHandler,
1972 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001973 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001974 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001975 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001976 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001977 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001978 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001979 {"StartNamespaceDeclHandler",
1980 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001981 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001982 {"EndNamespaceDeclHandler",
1983 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001984 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00001985 {"CommentHandler",
1986 (xmlhandlersetter)XML_SetCommentHandler,
1987 (xmlhandler)my_CommentHandler},
1988 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001989 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001990 (xmlhandler)my_StartCdataSectionHandler},
1991 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001992 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001993 (xmlhandler)my_EndCdataSectionHandler},
1994 {"DefaultHandler",
1995 (xmlhandlersetter)XML_SetDefaultHandler,
1996 (xmlhandler)my_DefaultHandler},
1997 {"DefaultHandlerExpand",
1998 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1999 (xmlhandler)my_DefaultHandlerExpandHandler},
2000 {"NotStandaloneHandler",
2001 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2002 (xmlhandler)my_NotStandaloneHandler},
2003 {"ExternalEntityRefHandler",
2004 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002005 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002006 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002007 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002008 (xmlhandler)my_StartDoctypeDeclHandler},
2009 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002010 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002011 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002012 {"EntityDeclHandler",
2013 (xmlhandlersetter)XML_SetEntityDeclHandler,
2014 (xmlhandler)my_EntityDeclHandler},
2015 {"XmlDeclHandler",
2016 (xmlhandlersetter)XML_SetXmlDeclHandler,
2017 (xmlhandler)my_XmlDeclHandler},
2018 {"ElementDeclHandler",
2019 (xmlhandlersetter)XML_SetElementDeclHandler,
2020 (xmlhandler)my_ElementDeclHandler},
2021 {"AttlistDeclHandler",
2022 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2023 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002024#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002025 {"SkippedEntityHandler",
2026 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2027 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002028#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002029
Fred Drake0582df92000-07-12 04:49:00 +00002030 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002031};