blob: 9b78d7e3a61cb8e55b34760ceda01b8488b75da4 [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;
Victor Stinner499dfcf2011-03-21 13:26:24 +0100103 PyObject *buffer;
Fred Drake85d835f2001-02-08 15:39:08 +0000104 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
Victor Stinner499dfcf2011-03-21 13:26:24 +0100108 buffer = PyUnicode_FromFormat("%s: line %i, column %i",
109 XML_ErrorString(code), lineno, column);
110 if (buffer == NULL)
111 return NULL;
112 err = PyObject_CallFunction(ErrorObject, "O", buffer);
113 Py_DECREF(buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000114 if ( err != NULL
115 && set_error_attr(err, "code", code)
116 && set_error_attr(err, "offset", column)
117 && set_error_attr(err, "lineno", lineno)) {
118 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000119 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000120 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000121 return NULL;
122}
123
Fred Drake71b63ff2002-06-28 22:29:01 +0000124static int
125have_handler(xmlparseobject *self, int type)
126{
127 PyObject *handler = self->handlers[type];
128 return handler != NULL;
129}
130
131static PyObject *
132get_handler_name(struct HandlerInfo *hinfo)
133{
134 PyObject *name = hinfo->nameobj;
135 if (name == NULL) {
Neal Norwitz392c5be2007-08-25 17:20:32 +0000136 name = PyUnicode_FromString(hinfo->name);
Fred Drake71b63ff2002-06-28 22:29:01 +0000137 hinfo->nameobj = name;
138 }
139 Py_XINCREF(name);
140 return name;
141}
142
Fred Drake85d835f2001-02-08 15:39:08 +0000143
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000144/* Convert a string of XML_Chars into a Unicode string.
145 Returns None if str is a null pointer. */
146
Fred Drake0582df92000-07-12 04:49:00 +0000147static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000148conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000149{
Fred Drake71b63ff2002-06-28 22:29:01 +0000150 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000151 and hence in UTF-8. */
152 /* UTF-8 from Expat, Unicode desired */
153 if (str == NULL) {
154 Py_INCREF(Py_None);
155 return Py_None;
156 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000157 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000158}
159
Fred Drake0582df92000-07-12 04:49:00 +0000160static PyObject *
161conv_string_len_to_unicode(const XML_Char *str, int len)
162{
Fred Drake71b63ff2002-06-28 22:29:01 +0000163 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000164 and hence in UTF-8. */
165 /* UTF-8 from Expat, Unicode desired */
166 if (str == NULL) {
167 Py_INCREF(Py_None);
168 return Py_None;
169 }
Fred Drake6f987622000-08-25 18:03:30 +0000170 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000171}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000172
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000173/* Callback routines */
174
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000175static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000176
Martin v. Löwis069dde22003-01-21 10:58:18 +0000177/* This handler is used when an error has been detected, in the hope
178 that actual parsing can be terminated early. This will only help
179 if an external entity reference is encountered. */
180static int
181error_external_entity_ref_handler(XML_Parser parser,
182 const XML_Char *context,
183 const XML_Char *base,
184 const XML_Char *systemId,
185 const XML_Char *publicId)
186{
187 return 0;
188}
189
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000190/* Dummy character data handler used when an error (exception) has
191 been detected, and the actual parsing can be terminated early.
192 This is needed since character data handler can't be safely removed
193 from within the character data handler, but can be replaced. It is
194 used only from the character data handler trampoline, and must be
195 used right after `flag_error()` is called. */
196static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197noop_character_data_handler(void *userData, const XML_Char *data, int len)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000198{
199 /* Do nothing. */
200}
201
Fred Drake6f987622000-08-25 18:03:30 +0000202static void
203flag_error(xmlparseobject *self)
204{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000205 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000206 XML_SetExternalEntityRefHandler(self->itself,
207 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000208}
209
210static PyCodeObject*
211getcode(enum HandlerTypes slot, char* func_name, int lineno)
212{
Fred Drakebd6101c2001-02-14 18:29:45 +0000213 if (handler_info[slot].tb_code == NULL) {
Fred Drakebd6101c2001-02-14 18:29:45 +0000214 handler_info[slot].tb_code =
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000215 PyCode_NewEmpty(__FILE__, func_name, lineno);
Fred Drakebd6101c2001-02-14 18:29:45 +0000216 }
217 return handler_info[slot].tb_code;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000218}
219
Jeremy Hylton9263f572003-06-27 16:13:17 +0000220#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000221static int
222trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
223{
224 int result = 0;
225 if (!tstate->use_tracing || tstate->tracing)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 return 0;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000227 if (tstate->c_profilefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 tstate->tracing++;
229 result = tstate->c_profilefunc(tstate->c_profileobj,
230 f, code , val);
231 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
232 || (tstate->c_profilefunc != NULL));
233 tstate->tracing--;
234 if (result)
235 return result;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000236 }
237 if (tstate->c_tracefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 tstate->tracing++;
239 result = tstate->c_tracefunc(tstate->c_traceobj,
240 f, code , val);
241 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
242 || (tstate->c_profilefunc != NULL));
243 tstate->tracing--;
244 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000245 return result;
246}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000247
248static int
249trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
250{
251 PyObject *type, *value, *traceback, *arg;
252 int err;
253
254 if (tstate->c_tracefunc == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000256
257 PyErr_Fetch(&type, &value, &traceback);
258 if (value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 value = Py_None;
260 Py_INCREF(value);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000261 }
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000262 arg = PyTuple_Pack(3, type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000263 if (arg == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 PyErr_Restore(type, value, traceback);
265 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000266 }
267 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
268 Py_DECREF(arg);
269 if (err == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 PyErr_Restore(type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000271 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 Py_XDECREF(type);
273 Py_XDECREF(value);
274 Py_XDECREF(traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000275 }
276 return err;
277}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000278#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000279
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000280static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000281call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
282 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000283{
Fred Drakebd6101c2001-02-14 18:29:45 +0000284 PyThreadState *tstate = PyThreadState_GET();
285 PyFrameObject *f;
286 PyObject *res;
287
288 if (c == NULL)
289 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290
Jeremy Hylton9263f572003-06-27 16:13:17 +0000291 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000292 if (f == NULL)
293 return NULL;
294 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000295#ifdef FIX_TRACE
296 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000298 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000299#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000300 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000301 if (res == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 if (tstate->curexc_traceback == NULL)
303 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000304 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000305#ifdef FIX_TRACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 if (trace_frame_exc(tstate, f) < 0) {
307 return NULL;
308 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000309 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000310 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
312 Py_XDECREF(res);
313 res = NULL;
314 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000315 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000316#else
317 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000318#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000319 tstate->frame = f->f_back;
320 Py_DECREF(f);
321 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000322}
323
Fred Drakeb91a36b2002-06-27 19:40:48 +0000324static PyObject*
325string_intern(xmlparseobject *self, const char* str)
326{
Guido van Rossum4ca94712007-07-23 17:42:32 +0000327 PyObject *result = conv_string_to_unicode(str);
Fred Drakeb91a36b2002-06-27 19:40:48 +0000328 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000329 /* result can be NULL if the unicode conversion failed. */
330 if (!result)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000332 if (!self->intern)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000334 value = PyDict_GetItem(self->intern, result);
335 if (!value) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (PyDict_SetItem(self->intern, result, result) == 0)
Fred Drakeb91a36b2002-06-27 19:40:48 +0000337 return result;
338 else
339 return NULL;
340 }
341 Py_INCREF(value);
342 Py_DECREF(result);
343 return value;
344}
345
Fred Drake2a3d7db2002-06-28 22:56:48 +0000346/* Return 0 on success, -1 on exception.
347 * flag_error() will be called before return if needed.
348 */
349static int
350call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
351{
352 PyObject *args;
353 PyObject *temp;
354
Georg Brandlc01537f2010-10-15 16:26:08 +0000355 if (!have_handler(self, CharacterData))
356 return -1;
357
Fred Drake2a3d7db2002-06-28 22:56:48 +0000358 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{
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000801 PyObject *str;
802 Py_ssize_t len;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000803 char *ptr;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000804
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000805 str = PyObject_CallFunction(meth, "n", buf_size);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000806 if (str == NULL)
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000807 goto error;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000808
Christian Heimes72b710a2008-05-26 13:28:38 +0000809 if (PyBytes_Check(str))
810 ptr = PyBytes_AS_STRING(str);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000811 else if (PyByteArray_Check(str))
812 ptr = PyByteArray_AS_STRING(str);
Guido van Rossum98297ee2007-11-06 21:34:58 +0000813 else {
Fred Drake71b63ff2002-06-28 22:29:01 +0000814 PyErr_Format(PyExc_TypeError,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000815 "read() did not return a bytes object (type=%.400s)",
Christian Heimes90aa7642007-12-19 02:45:37 +0000816 Py_TYPE(str)->tp_name);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000817 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000818 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000819 len = Py_SIZE(str);
Fred Drake0582df92000-07-12 04:49:00 +0000820 if (len > buf_size) {
821 PyErr_Format(PyExc_ValueError,
822 "read() returned too much data: "
Victor Stinner9d6f9362011-01-04 22:00:04 +0000823 "%i bytes requested, %zd returned",
Fred Drake0582df92000-07-12 04:49:00 +0000824 buf_size, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000825 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000826 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000827 memcpy(buf, ptr, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000828 Py_DECREF(str);
829 /* len <= buf_size <= INT_MAX */
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000830 return (int)len;
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000831
832error:
833 Py_XDECREF(str);
834 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000835}
836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000837PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000838"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000839Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000840
841static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000842xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000843{
Fred Drake0582df92000-07-12 04:49:00 +0000844 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000845 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000847
848 readmethod = PyObject_GetAttrString(f, "read");
849 if (readmethod == NULL) {
850 PyErr_Clear();
851 PyErr_SetString(PyExc_TypeError,
852 "argument must have 'read' attribute");
853 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000854 }
855 for (;;) {
856 int bytes_read;
857 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000858 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000859 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000860 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +0000861 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000862
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000863 bytes_read = readinst(buf, BUF_SIZE, readmethod);
864 if (bytes_read < 0) {
865 Py_DECREF(readmethod);
866 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000867 }
868 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000869 if (PyErr_Occurred()) {
870 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000871 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000872 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000873
Fred Drake0582df92000-07-12 04:49:00 +0000874 if (!rv || bytes_read == 0)
875 break;
876 }
Fred Drake7b6caff2003-07-21 17:05:56 +0000877 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +0000878 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000879}
880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000881PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000882"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000883Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000884
885static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000886xmlparse_SetBase(xmlparseobject *self, PyObject *args)
887{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000888 char *base;
889
Fred Drake0582df92000-07-12 04:49:00 +0000890 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000891 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000892 if (!XML_SetBase(self->itself, base)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000894 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000895 Py_INCREF(Py_None);
896 return Py_None;
897}
898
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000899PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000900"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000901Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000902
903static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000904xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +0000905{
Fred Drake0582df92000-07-12 04:49:00 +0000906 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000907}
908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000909PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +0000910"GetInputContext() -> string\n\
911Return the untranslated text of the input that caused the current event.\n\
912If 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 +0000913for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +0000914
915static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000916xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +0000917{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000918 if (self->in_callback) {
919 int offset, size;
920 const char *buffer
921 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +0000922
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000923 if (buffer != NULL)
Christian Heimes72b710a2008-05-26 13:28:38 +0000924 return PyBytes_FromStringAndSize(buffer + offset,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000925 size - offset);
926 else
927 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000928 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000929 else
930 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000931}
Fred Drakebd6101c2001-02-14 18:29:45 +0000932
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000933PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +0000934"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000935Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000936information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000937
938static PyObject *
939xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
940{
941 char *context;
942 char *encoding = NULL;
943 xmlparseobject *new_parser;
944 int i;
945
Martin v. Löwisc57428d2001-09-19 09:55:09 +0000946 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +0000947 &context, &encoding)) {
948 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000949 }
950
Martin v. Löwis894258c2001-09-23 10:20:10 +0000951 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake85d835f2001-02-08 15:39:08 +0000952 if (new_parser == NULL)
953 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +0000954 new_parser->buffer_size = self->buffer_size;
955 new_parser->buffer_used = 0;
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000956 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000957 new_parser->ordered_attributes = self->ordered_attributes;
958 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +0000959 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000960 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000961 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000963 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000964 new_parser->intern = self->intern;
965 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000966 PyObject_GC_Track(new_parser);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000967
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000968 if (self->buffer != NULL) {
969 new_parser->buffer = malloc(new_parser->buffer_size);
970 if (new_parser->buffer == NULL) {
971 Py_DECREF(new_parser);
972 return PyErr_NoMemory();
973 }
974 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000975 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +0000976 Py_DECREF(new_parser);
977 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000978 }
979
980 XML_SetUserData(new_parser->itself, (void *)new_parser);
981
982 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +0000983 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +0000984 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000985
Fred Drake2a3d7db2002-06-28 22:56:48 +0000986 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000987 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +0000988 Py_DECREF(new_parser);
989 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000990 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000991 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000992
993 /* then copy handlers from self */
994 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000995 PyObject *handler = self->handlers[i];
996 if (handler != NULL) {
997 Py_INCREF(handler);
998 new_parser->handlers[i] = handler;
999 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001000 handler_info[i].handler);
1001 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001002 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001003 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001004}
1005
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001006PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001007"SetParamEntityParsing(flag) -> success\n\
1008Controls parsing of parameter entities (including the external DTD\n\
1009subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1010XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1011XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001012was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001013
1014static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001015xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001016{
Fred Drake85d835f2001-02-08 15:39:08 +00001017 int flag;
1018 if (!PyArg_ParseTuple(args, "i", &flag))
1019 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001020 flag = XML_SetParamEntityParsing(p->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +00001021 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001022}
1023
Martin v. Löwisc847f402003-01-21 11:09:21 +00001024
1025#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001026PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1027"UseForeignDTD([flag])\n\
1028Allows the application to provide an artificial external subset if one is\n\
1029not specified as part of the document instance. This readily allows the\n\
1030use of a 'default' document type controlled by the application, while still\n\
1031getting the advantage of providing document type information to the parser.\n\
1032'flag' defaults to True if not provided.");
1033
1034static PyObject *
1035xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1036{
1037 PyObject *flagobj = NULL;
1038 XML_Bool flag = XML_TRUE;
1039 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001040 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001041 return NULL;
1042 if (flagobj != NULL)
1043 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1044 rc = XML_UseForeignDTD(self->itself, flag);
1045 if (rc != XML_ERROR_NONE) {
1046 return set_error(self, rc);
1047 }
1048 Py_INCREF(Py_None);
1049 return Py_None;
1050}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001051#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001052
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001053static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs);
1054
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001055static struct PyMethodDef xmlparse_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 {"Parse", (PyCFunction)xmlparse_Parse,
1057 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001058 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001060 {"SetBase", (PyCFunction)xmlparse_SetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001062 {"GetBase", (PyCFunction)xmlparse_GetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001064 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001066 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001068 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001070#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001071 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001073#endif
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001074 {"__dir__", xmlparse_dir, METH_NOARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001076};
1077
1078/* ---------- */
1079
1080
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001081
Fred Drake71b63ff2002-06-28 22:29:01 +00001082/* pyexpat international encoding support.
1083 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001084*/
1085
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001086static char template_buffer[257];
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001087
Fred Drake71b63ff2002-06-28 22:29:01 +00001088static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001089init_template_buffer(void)
1090{
1091 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001092 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001094 }
Fred Drakebb66a202001-03-01 20:48:17 +00001095 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001096}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001097
Fred Drake71b63ff2002-06-28 22:29:01 +00001098static int
1099PyUnknownEncodingHandler(void *encodingHandlerData,
1100 const XML_Char *name,
1101 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001102{
Fred Drakebb66a202001-03-01 20:48:17 +00001103 PyUnicodeObject *_u_string = NULL;
1104 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001105 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001106
Fred Drakebb66a202001-03-01 20:48:17 +00001107 /* Yes, supports only 8bit encodings */
1108 _u_string = (PyUnicodeObject *)
1109 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001110
Fred Drakebb66a202001-03-01 20:48:17 +00001111 if (_u_string == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001113
Fred Drakebb66a202001-03-01 20:48:17 +00001114 for (i = 0; i < 256; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 /* Stupid to access directly, but fast */
1116 Py_UNICODE c = _u_string->str[i];
1117 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
1118 info->map[i] = -1;
1119 else
1120 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001121 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001122 info->data = NULL;
1123 info->convert = NULL;
1124 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001125 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001126 Py_DECREF(_u_string);
1127 return result;
1128}
1129
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001130
1131static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001132newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001133{
1134 int i;
1135 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001136
Martin v. Löwis894258c2001-09-23 10:20:10 +00001137 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake0582df92000-07-12 04:49:00 +00001138 if (self == NULL)
1139 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001140
Fred Drake2a3d7db2002-06-28 22:56:48 +00001141 self->buffer = NULL;
1142 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1143 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001144 self->ordered_attributes = 0;
1145 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001146 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001147 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001148 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001149 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001150 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1151 }
Fred Drake85d835f2001-02-08 15:39:08 +00001152 else {
Fred Drake0582df92000-07-12 04:49:00 +00001153 self->itself = XML_ParserCreate(encoding);
1154 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001155 self->intern = intern;
1156 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001157 PyObject_GC_Track(self);
Fred Drake0582df92000-07-12 04:49:00 +00001158 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001159 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001160 "XML_ParserCreate failed");
1161 Py_DECREF(self);
1162 return NULL;
1163 }
1164 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001165 XML_SetUnknownEncodingHandler(self->itself,
1166 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001167
Fred Drake2a3d7db2002-06-28 22:56:48 +00001168 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001169 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001170
Fred Drake7c75bf22002-07-01 14:02:31 +00001171 self->handlers = malloc(sizeof(PyObject *) * i);
1172 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001173 Py_DECREF(self);
1174 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001175 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001176 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001177
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001178 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001179}
1180
1181
1182static void
Fred Drake0582df92000-07-12 04:49:00 +00001183xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001184{
Fred Drake0582df92000-07-12 04:49:00 +00001185 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001186 PyObject_GC_UnTrack(self);
Fred Drake85d835f2001-02-08 15:39:08 +00001187 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001188 XML_ParserFree(self->itself);
1189 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001190
Fred Drake85d835f2001-02-08 15:39:08 +00001191 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001192 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001193 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001194 temp = self->handlers[i];
1195 self->handlers[i] = NULL;
1196 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001197 }
1198 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001199 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001200 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001201 if (self->buffer != NULL) {
1202 free(self->buffer);
1203 self->buffer = NULL;
1204 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001205 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001206 PyObject_GC_Del(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001207}
1208
Fred Drake0582df92000-07-12 04:49:00 +00001209static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001210handlername2int(PyObject *name)
Fred Drake0582df92000-07-12 04:49:00 +00001211{
1212 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001213 for (i = 0; handler_info[i].name != NULL; i++) {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001214 if (PyUnicode_CompareWithASCIIString(
1215 name, handler_info[i].name) == 0) {
Fred Drake0582df92000-07-12 04:49:00 +00001216 return i;
1217 }
1218 }
1219 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001220}
1221
1222static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001223get_pybool(int istrue)
1224{
1225 PyObject *result = istrue ? Py_True : Py_False;
1226 Py_INCREF(result);
1227 return result;
1228}
1229
1230static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001231xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001232{
Alexander Belopolskye239d232010-12-08 23:31:48 +00001233 Py_UNICODE *name;
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001234 int handlernum = -1;
1235
Alexander Belopolskye239d232010-12-08 23:31:48 +00001236 if (!PyUnicode_Check(nameobj))
1237 goto generic;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238
Alexander Belopolskye239d232010-12-08 23:31:48 +00001239 handlernum = handlername2int(nameobj);
Fred Drake71b63ff2002-06-28 22:29:01 +00001240
1241 if (handlernum != -1) {
1242 PyObject *result = self->handlers[handlernum];
1243 if (result == NULL)
1244 result = Py_None;
1245 Py_INCREF(result);
1246 return result;
1247 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001248
1249 name = PyUnicode_AS_UNICODE(nameobj);
Fred Drake71b63ff2002-06-28 22:29:01 +00001250 if (name[0] == 'E') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001251 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorCode") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001252 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001253 XML_GetErrorCode(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001254 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001255 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001256 XML_GetErrorLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001257 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001258 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001259 XML_GetErrorColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001260 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001261 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001262 XML_GetErrorByteIndex(self->itself));
1263 }
Dave Cole3203efb2004-08-26 00:37:31 +00001264 if (name[0] == 'C') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001265 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001266 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001267 XML_GetCurrentLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001268 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001269 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001270 XML_GetCurrentColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001271 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001272 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001273 XML_GetCurrentByteIndex(self->itself));
1274 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001275 if (name[0] == 'b') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001276 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_size") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001277 return PyLong_FromLong((long) self->buffer_size);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001278 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_text") == 0)
Fred Drake2a3d7db2002-06-28 22:56:48 +00001279 return get_pybool(self->buffer != NULL);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001280 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_used") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001281 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001282 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001283 if (PyUnicode_CompareWithASCIIString(nameobj, "namespace_prefixes") == 0)
Martin v. Löwis069dde22003-01-21 10:58:18 +00001284 return get_pybool(self->ns_prefixes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001285 if (PyUnicode_CompareWithASCIIString(nameobj, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001286 return get_pybool(self->ordered_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001287 if (PyUnicode_CompareWithASCIIString(nameobj, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001288 return get_pybool((long) self->specified_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001289 if (PyUnicode_CompareWithASCIIString(nameobj, "intern") == 0) {
Fred Drakeb91a36b2002-06-27 19:40:48 +00001290 if (self->intern == NULL) {
1291 Py_INCREF(Py_None);
1292 return Py_None;
1293 }
1294 else {
1295 Py_INCREF(self->intern);
1296 return self->intern;
1297 }
1298 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001299 generic:
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001300 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001301}
1302
1303static PyObject *
1304xmlparse_dir(PyObject *self, PyObject* noargs)
1305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306#define APPEND(list, str) \
1307 do { \
1308 PyObject *o = PyUnicode_FromString(str); \
1309 if (o != NULL) \
1310 PyList_Append(list, o); \
1311 Py_XDECREF(o); \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001312 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001313
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001314 int i;
1315 PyObject *rc = PyList_New(0);
1316 if (!rc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 return NULL;
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001318 for (i = 0; handler_info[i].name != NULL; i++) {
1319 PyObject *o = get_handler_name(&handler_info[i]);
1320 if (o != NULL)
1321 PyList_Append(rc, o);
1322 Py_XDECREF(o);
1323 }
1324 APPEND(rc, "ErrorCode");
1325 APPEND(rc, "ErrorLineNumber");
1326 APPEND(rc, "ErrorColumnNumber");
1327 APPEND(rc, "ErrorByteIndex");
1328 APPEND(rc, "CurrentLineNumber");
1329 APPEND(rc, "CurrentColumnNumber");
1330 APPEND(rc, "CurrentByteIndex");
1331 APPEND(rc, "buffer_size");
1332 APPEND(rc, "buffer_text");
1333 APPEND(rc, "buffer_used");
1334 APPEND(rc, "namespace_prefixes");
1335 APPEND(rc, "ordered_attributes");
1336 APPEND(rc, "specified_attributes");
1337 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001338
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001339#undef APPEND
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001340
1341 if (PyErr_Occurred()) {
1342 Py_DECREF(rc);
1343 rc = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001344 }
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001345
1346 return rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001347}
1348
Fred Drake6f987622000-08-25 18:03:30 +00001349static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001350sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001351{
1352 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001353 if (handlernum >= 0) {
1354 xmlhandler c_handler = NULL;
1355 PyObject *temp = self->handlers[handlernum];
1356
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001357 if (v == Py_None) {
1358 /* If this is the character data handler, and a character
1359 data handler is already active, we need to be more
1360 careful. What we can safely do is replace the existing
1361 character data handler callback function with a no-op
1362 function that will refuse to call Python. The downside
1363 is that this doesn't completely remove the character
1364 data handler from the C layer if there's any callback
1365 active, so Expat does a little more work than it
1366 otherwise would, but that's really an odd case. A more
1367 elaborate system of handlers and state could remove the
1368 C handler more effectively. */
1369 if (handlernum == CharacterData && self->in_callback)
1370 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001371 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001372 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001373 else if (v != NULL) {
1374 Py_INCREF(v);
1375 c_handler = handler_info[handlernum].handler;
1376 }
Fred Drake0582df92000-07-12 04:49:00 +00001377 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001378 Py_XDECREF(temp);
1379 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001380 return 1;
1381 }
1382 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001383}
1384
1385static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001386xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001387{
Fred Drake6f987622000-08-25 18:03:30 +00001388 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001389 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001390 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1391 return -1;
1392 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001393 assert(PyUnicode_Check(name));
1394 if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001395 if (PyObject_IsTrue(v)) {
1396 if (self->buffer == NULL) {
1397 self->buffer = malloc(self->buffer_size);
1398 if (self->buffer == NULL) {
1399 PyErr_NoMemory();
1400 return -1;
1401 }
1402 self->buffer_used = 0;
1403 }
1404 }
1405 else if (self->buffer != NULL) {
1406 if (flush_character_buffer(self) < 0)
1407 return -1;
1408 free(self->buffer);
1409 self->buffer = NULL;
1410 }
1411 return 0;
1412 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001413 if (PyUnicode_CompareWithASCIIString(name, "namespace_prefixes") == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +00001414 if (PyObject_IsTrue(v))
1415 self->ns_prefixes = 1;
1416 else
1417 self->ns_prefixes = 0;
1418 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1419 return 0;
1420 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001421 if (PyUnicode_CompareWithASCIIString(name, "ordered_attributes") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001422 if (PyObject_IsTrue(v))
1423 self->ordered_attributes = 1;
1424 else
1425 self->ordered_attributes = 0;
1426 return 0;
1427 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001428 if (PyUnicode_CompareWithASCIIString(name, "specified_attributes") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001429 if (PyObject_IsTrue(v))
1430 self->specified_attributes = 1;
1431 else
1432 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001433 return 0;
1434 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001435
Alexander Belopolskye239d232010-12-08 23:31:48 +00001436 if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
Christian Heimes2380ac72008-01-09 00:17:24 +00001437 long new_buffer_size;
1438 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1440 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001441 }
1442
1443 new_buffer_size=PyLong_AS_LONG(v);
1444 /* trivial case -- no change */
1445 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001447 }
1448
1449 if (new_buffer_size <= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1451 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001452 }
1453
1454 /* check maximum */
1455 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 char errmsg[100];
1457 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1458 PyErr_SetString(PyExc_ValueError, errmsg);
1459 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001460 }
1461
1462 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 /* there is already a buffer */
1464 if (self->buffer_used != 0) {
1465 flush_character_buffer(self);
1466 }
1467 /* free existing buffer */
1468 free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001469 }
1470 self->buffer = malloc(new_buffer_size);
1471 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 PyErr_NoMemory();
1473 return -1;
1474 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001475 self->buffer_size = new_buffer_size;
1476 return 0;
1477 }
1478
Alexander Belopolskye239d232010-12-08 23:31:48 +00001479 if (PyUnicode_CompareWithASCIIString(name, "CharacterDataHandler") == 0) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001480 /* If we're changing the character data handler, flush all
1481 * cached data with the old handler. Not sure there's a
1482 * "right" thing to do, though, but this probably won't
1483 * happen.
1484 */
1485 if (flush_character_buffer(self) < 0)
1486 return -1;
1487 }
Fred Drake6f987622000-08-25 18:03:30 +00001488 if (sethandler(self, name, v)) {
1489 return 0;
1490 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001491 PyErr_SetObject(PyExc_AttributeError, name);
Fred Drake6f987622000-08-25 18:03:30 +00001492 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001493}
1494
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001495static int
1496xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1497{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001498 int i;
1499 for (i = 0; handler_info[i].name != NULL; i++)
1500 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001501 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001502}
1503
1504static int
1505xmlparse_clear(xmlparseobject *op)
1506{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001507 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001508 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001509 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001510}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001512PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001513
1514static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 PyVarObject_HEAD_INIT(NULL, 0)
1516 "pyexpat.xmlparser", /*tp_name*/
Antoine Pitrou23683ef2011-01-04 00:00:31 +00001517 sizeof(xmlparseobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 0, /*tp_itemsize*/
1519 /* methods */
1520 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1521 (printfunc)0, /*tp_print*/
1522 0, /*tp_getattr*/
Alexander Belopolskye239d232010-12-08 23:31:48 +00001523 0, /*tp_setattr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 0, /*tp_reserved*/
1525 (reprfunc)0, /*tp_repr*/
1526 0, /*tp_as_number*/
1527 0, /*tp_as_sequence*/
1528 0, /*tp_as_mapping*/
1529 (hashfunc)0, /*tp_hash*/
1530 (ternaryfunc)0, /*tp_call*/
1531 (reprfunc)0, /*tp_str*/
1532 (getattrofunc)xmlparse_getattro, /* tp_getattro */
Alexander Belopolskye239d232010-12-08 23:31:48 +00001533 (setattrofunc)xmlparse_setattro, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 0, /* tp_as_buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1537 (traverseproc)xmlparse_traverse, /* tp_traverse */
1538 (inquiry)xmlparse_clear, /* tp_clear */
1539 0, /* tp_richcompare */
1540 0, /* tp_weaklistoffset */
1541 0, /* tp_iter */
1542 0, /* tp_iternext */
1543 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001544};
1545
1546/* End of code for xmlparser objects */
1547/* -------------------------------------------------------- */
1548
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001549PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001550"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001551Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001552
1553static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001554pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1555{
Fred Drakecde79132001-04-25 16:01:30 +00001556 char *encoding = NULL;
1557 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001558 PyObject *intern = NULL;
1559 PyObject *result;
1560 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001561 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001562 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001563
Fred Drakeb91a36b2002-06-27 19:40:48 +00001564 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1565 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001566 return NULL;
1567 if (namespace_separator != NULL
1568 && strlen(namespace_separator) > 1) {
1569 PyErr_SetString(PyExc_ValueError,
1570 "namespace_separator must be at most one"
1571 " character, omitted, or None");
1572 return NULL;
1573 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001574 /* Explicitly passing None means no interning is desired.
1575 Not passing anything means that a new dictionary is used. */
1576 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001578 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 intern = PyDict_New();
1580 if (!intern)
1581 return NULL;
1582 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001583 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001584 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1586 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001587 }
1588
1589 result = newxmlparseobject(encoding, namespace_separator, intern);
1590 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001592 }
1593 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001594}
1595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001597"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001599
1600static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001601pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001602{
Fred Drake0582df92000-07-12 04:49:00 +00001603 long code = 0;
1604
1605 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1606 return NULL;
1607 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001608}
1609
1610/* List of methods defined in the module */
1611
1612static struct PyMethodDef pyexpat_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
Fred Drake0582df92000-07-12 04:49:00 +00001614 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1616 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001619};
1620
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001621/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623PyDoc_STRVAR(pyexpat_module_documentation,
1624"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001625
Fred Drake4113b132001-03-24 19:58:26 +00001626/* Return a Python string that represents the version number without the
1627 * extra cruft added by revision control, even if the right options were
1628 * given to the "cvs export" command to make it not include the extra
1629 * cruft.
1630 */
1631static PyObject *
1632get_version_string(void)
1633{
1634 static char *rcsid = "$Revision$";
1635 char *rev = rcsid;
1636 int i = 0;
1637
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001638 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001639 ++rev;
1640 while (rev[i] != ' ' && rev[i] != '\0')
1641 ++i;
1642
Neal Norwitz392c5be2007-08-25 17:20:32 +00001643 return PyUnicode_FromStringAndSize(rev, i);
Fred Drake4113b132001-03-24 19:58:26 +00001644}
1645
Fred Drakecde79132001-04-25 16:01:30 +00001646/* Initialization function for the module */
1647
1648#ifndef MODULE_NAME
1649#define MODULE_NAME "pyexpat"
1650#endif
1651
1652#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001653#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00001654#endif
1655
Martin v. Löwis069dde22003-01-21 10:58:18 +00001656#ifndef PyMODINIT_FUNC
1657# ifdef MS_WINDOWS
1658# define PyMODINIT_FUNC __declspec(dllexport) void
1659# else
1660# define PyMODINIT_FUNC void
1661# endif
1662#endif
1663
Mark Hammond8235ea12002-07-19 06:55:41 +00001664PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001665
Martin v. Löwis1a214512008-06-11 05:26:20 +00001666static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 PyModuleDef_HEAD_INIT,
1668 MODULE_NAME,
1669 pyexpat_module_documentation,
1670 -1,
1671 pyexpat_methods,
1672 NULL,
1673 NULL,
1674 NULL,
1675 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001676};
1677
Martin v. Löwis069dde22003-01-21 10:58:18 +00001678PyMODINIT_FUNC
1679MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001680{
1681 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001682 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001683 PyObject *errors_module;
1684 PyObject *modelmod_name;
1685 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001686 PyObject *sys_modules;
Georg Brandlb4dac712010-10-15 14:46:48 +00001687 PyObject *tmpnum, *tmpstr;
1688 PyObject *codes_dict;
1689 PyObject *rev_codes_dict;
1690 int res;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001691 static struct PyExpat_CAPI capi;
Georg Brandlb4dac712010-10-15 14:46:48 +00001692 PyObject *capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001693
Fred Drake6f987622000-08-25 18:03:30 +00001694 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001695 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001696 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001697 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001698 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00001699
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001700 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001702
Fred Drake0582df92000-07-12 04:49:00 +00001703 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001704 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001705 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001707
Fred Drake0582df92000-07-12 04:49:00 +00001708 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001709 if (ErrorObject == NULL) {
1710 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001711 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001712 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001713 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001714 }
1715 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001716 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001717 Py_INCREF(ErrorObject);
1718 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001719 Py_INCREF(&Xmlparsetype);
1720 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001721
Fred Drake4113b132001-03-24 19:58:26 +00001722 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001723 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1724 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001725 {
1726 XML_Expat_Version info = XML_ExpatVersionInfo();
1727 PyModule_AddObject(m, "version_info",
1728 Py_BuildValue("(iii)", info.major,
1729 info.minor, info.micro));
1730 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001731 init_template_buffer();
Fred Drake0582df92000-07-12 04:49:00 +00001732 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001733 compiled, this should check and set native_encoding
1734 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001735 */
Fred Drake93adb692000-09-23 04:55:48 +00001736 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001737
Fred Drake85d835f2001-02-08 15:39:08 +00001738 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001739 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001740 errors_module = PyDict_GetItem(d, errmod_name);
1741 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001742 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001743 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001744 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001745 /* gives away the reference to errors_module */
1746 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001747 }
1748 }
Fred Drake6f987622000-08-25 18:03:30 +00001749 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001750 model_module = PyDict_GetItem(d, modelmod_name);
1751 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001752 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001753 if (model_module != NULL) {
1754 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1755 /* gives away the reference to model_module */
1756 PyModule_AddObject(m, "model", model_module);
1757 }
1758 }
1759 Py_DECREF(modelmod_name);
1760 if (errors_module == NULL || model_module == NULL)
1761 /* Don't core dump later! */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001762 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763
Martin v. Löwisc847f402003-01-21 11:09:21 +00001764#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001765 {
1766 const XML_Feature *features = XML_GetFeatureList();
1767 PyObject *list = PyList_New(0);
1768 if (list == NULL)
1769 /* just ignore it */
1770 PyErr_Clear();
1771 else {
1772 int i = 0;
1773 for (; features[i].feature != XML_FEATURE_END; ++i) {
1774 int ok;
1775 PyObject *item = Py_BuildValue("si", features[i].name,
1776 features[i].value);
1777 if (item == NULL) {
1778 Py_DECREF(list);
1779 list = NULL;
1780 break;
1781 }
1782 ok = PyList_Append(list, item);
1783 Py_DECREF(item);
1784 if (ok < 0) {
1785 PyErr_Clear();
1786 break;
1787 }
1788 }
1789 if (list != NULL)
1790 PyModule_AddObject(m, "features", list);
1791 }
1792 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001793#endif
Fred Drake6f987622000-08-25 18:03:30 +00001794
Georg Brandlb4dac712010-10-15 14:46:48 +00001795 codes_dict = PyDict_New();
1796 rev_codes_dict = PyDict_New();
1797 if (codes_dict == NULL || rev_codes_dict == NULL) {
1798 Py_XDECREF(codes_dict);
1799 Py_XDECREF(rev_codes_dict);
1800 return NULL;
1801 }
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001802
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001803#define MYCONST(name) \
Georg Brandlb4dac712010-10-15 14:46:48 +00001804 if (PyModule_AddStringConstant(errors_module, #name, \
1805 (char *)XML_ErrorString(name)) < 0) \
1806 return NULL; \
1807 tmpnum = PyLong_FromLong(name); \
1808 if (tmpnum == NULL) return NULL; \
1809 res = PyDict_SetItemString(codes_dict, \
1810 XML_ErrorString(name), tmpnum); \
1811 if (res < 0) return NULL; \
1812 tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \
1813 if (tmpstr == NULL) return NULL; \
1814 res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \
1815 Py_DECREF(tmpstr); \
1816 Py_DECREF(tmpnum); \
1817 if (res < 0) return NULL; \
Fred Drake7bd9f412000-07-04 23:51:31 +00001818
Fred Drake0582df92000-07-12 04:49:00 +00001819 MYCONST(XML_ERROR_NO_MEMORY);
1820 MYCONST(XML_ERROR_SYNTAX);
1821 MYCONST(XML_ERROR_NO_ELEMENTS);
1822 MYCONST(XML_ERROR_INVALID_TOKEN);
1823 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1824 MYCONST(XML_ERROR_PARTIAL_CHAR);
1825 MYCONST(XML_ERROR_TAG_MISMATCH);
1826 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1827 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1828 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1829 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1830 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1831 MYCONST(XML_ERROR_ASYNC_ENTITY);
1832 MYCONST(XML_ERROR_BAD_CHAR_REF);
1833 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1834 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1835 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1836 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1837 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001838 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1839 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1840 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001841 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1842 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1843 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1844 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1845 /* Added in Expat 1.95.7. */
1846 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1847 /* Added in Expat 1.95.8. */
1848 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1849 MYCONST(XML_ERROR_INCOMPLETE_PE);
1850 MYCONST(XML_ERROR_XML_DECL);
1851 MYCONST(XML_ERROR_TEXT_DECL);
1852 MYCONST(XML_ERROR_PUBLICID);
1853 MYCONST(XML_ERROR_SUSPENDED);
1854 MYCONST(XML_ERROR_NOT_SUSPENDED);
1855 MYCONST(XML_ERROR_ABORTED);
1856 MYCONST(XML_ERROR_FINISHED);
1857 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001858
Georg Brandlb4dac712010-10-15 14:46:48 +00001859 if (PyModule_AddStringConstant(errors_module, "__doc__",
1860 "Constants used to describe "
1861 "error conditions.") < 0)
1862 return NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001863
Georg Brandlb4dac712010-10-15 14:46:48 +00001864 if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0)
1865 return NULL;
1866 if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0)
1867 return NULL;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001868
Fred Drake93adb692000-09-23 04:55:48 +00001869#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001870
Fred Drake85d835f2001-02-08 15:39:08 +00001871#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001872 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1873 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1874 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001875#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001876
Fred Drake85d835f2001-02-08 15:39:08 +00001877#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1878 PyModule_AddStringConstant(model_module, "__doc__",
1879 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001880
Fred Drake85d835f2001-02-08 15:39:08 +00001881 MYCONST(XML_CTYPE_EMPTY);
1882 MYCONST(XML_CTYPE_ANY);
1883 MYCONST(XML_CTYPE_MIXED);
1884 MYCONST(XML_CTYPE_NAME);
1885 MYCONST(XML_CTYPE_CHOICE);
1886 MYCONST(XML_CTYPE_SEQ);
1887
1888 MYCONST(XML_CQUANT_NONE);
1889 MYCONST(XML_CQUANT_OPT);
1890 MYCONST(XML_CQUANT_REP);
1891 MYCONST(XML_CQUANT_PLUS);
1892#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001893
1894 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001895 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001896 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001897 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1898 capi.MINOR_VERSION = XML_MINOR_VERSION;
1899 capi.MICRO_VERSION = XML_MICRO_VERSION;
1900 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001901 capi.GetErrorCode = XML_GetErrorCode;
1902 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1903 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001904 capi.Parse = XML_Parse;
1905 capi.ParserCreate_MM = XML_ParserCreate_MM;
1906 capi.ParserFree = XML_ParserFree;
1907 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1908 capi.SetCommentHandler = XML_SetCommentHandler;
1909 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1910 capi.SetElementHandler = XML_SetElementHandler;
1911 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1912 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1913 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1914 capi.SetUserData = XML_SetUserData;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915
Benjamin Petersonb173f782009-05-05 22:31:58 +00001916 /* export using capsule */
1917 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001918 if (capi_object)
1919 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001920 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001921}
1922
Fred Drake6f987622000-08-25 18:03:30 +00001923static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001924clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001925{
Fred Drakecde79132001-04-25 16:01:30 +00001926 int i = 0;
1927 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001928
Fred Drake71b63ff2002-06-28 22:29:01 +00001929 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001930 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 self->handlers[i] = NULL;
1932 else {
Fred Drakecde79132001-04-25 16:01:30 +00001933 temp = self->handlers[i];
1934 self->handlers[i] = NULL;
1935 Py_XDECREF(temp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00001937 }
Fred Drakecde79132001-04-25 16:01:30 +00001938 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001939}
1940
Tim Peters0c322792002-07-17 16:49:03 +00001941static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00001942 {"StartElementHandler",
1943 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001944 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001945 {"EndElementHandler",
1946 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001947 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001948 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001949 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1950 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001951 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001952 (xmlhandlersetter)XML_SetCharacterDataHandler,
1953 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001954 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001955 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001956 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001957 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001958 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001959 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001960 {"StartNamespaceDeclHandler",
1961 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001962 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001963 {"EndNamespaceDeclHandler",
1964 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001965 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00001966 {"CommentHandler",
1967 (xmlhandlersetter)XML_SetCommentHandler,
1968 (xmlhandler)my_CommentHandler},
1969 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001970 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001971 (xmlhandler)my_StartCdataSectionHandler},
1972 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001973 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001974 (xmlhandler)my_EndCdataSectionHandler},
1975 {"DefaultHandler",
1976 (xmlhandlersetter)XML_SetDefaultHandler,
1977 (xmlhandler)my_DefaultHandler},
1978 {"DefaultHandlerExpand",
1979 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1980 (xmlhandler)my_DefaultHandlerExpandHandler},
1981 {"NotStandaloneHandler",
1982 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1983 (xmlhandler)my_NotStandaloneHandler},
1984 {"ExternalEntityRefHandler",
1985 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001986 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001987 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001988 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001989 (xmlhandler)my_StartDoctypeDeclHandler},
1990 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001991 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001992 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00001993 {"EntityDeclHandler",
1994 (xmlhandlersetter)XML_SetEntityDeclHandler,
1995 (xmlhandler)my_EntityDeclHandler},
1996 {"XmlDeclHandler",
1997 (xmlhandlersetter)XML_SetXmlDeclHandler,
1998 (xmlhandler)my_XmlDeclHandler},
1999 {"ElementDeclHandler",
2000 (xmlhandlersetter)XML_SetElementDeclHandler,
2001 (xmlhandler)my_ElementDeclHandler},
2002 {"AttlistDeclHandler",
2003 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2004 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002005#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002006 {"SkippedEntityHandler",
2007 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2008 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002009#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002010
Fred Drake0582df92000-07-12 04:49:00 +00002011 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002012};