blob: 4ced53b611aebea3215262ea11cc835e77925c50 [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
Christian Heimesfa535f52013-07-07 17:35:11 +020011static XML_Memory_Handling_Suite ExpatMemoryHandler = {
12 PyObject_Malloc, PyObject_Realloc, PyObject_Free};
13
Fred Drake0582df92000-07-12 04:49:00 +000014enum HandlerTypes {
15 StartElement,
16 EndElement,
17 ProcessingInstruction,
18 CharacterData,
19 UnparsedEntityDecl,
20 NotationDecl,
21 StartNamespaceDecl,
22 EndNamespaceDecl,
23 Comment,
24 StartCdataSection,
25 EndCdataSection,
26 Default,
27 DefaultHandlerExpand,
28 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000029 ExternalEntityRef,
30 StartDoctypeDecl,
31 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000032 EntityDecl,
33 XmlDecl,
34 ElementDecl,
35 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000036#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000037 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000038#endif
Fred Drake85d835f2001-02-08 15:39:08 +000039 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000040};
41
42static PyObject *ErrorObject;
43
44/* ----------------------------------------------------- */
45
46/* Declarations for objects of type xmlparser */
47
48typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000049 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000050
Fred Drake0582df92000-07-12 04:49:00 +000051 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000052 int ordered_attributes; /* Return attributes as a list. */
53 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000054 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000055 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000056 XML_Char *buffer; /* Buffer used when accumulating characters */
57 /* NULL if not enabled */
58 int buffer_size; /* Size of buffer, in XML_Char units */
59 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000060 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000061 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000062} xmlparseobject;
63
Fred Drake2a3d7db2002-06-28 22:56:48 +000064#define CHARACTER_DATA_BUFFER_SIZE 8192
65
Jeremy Hylton938ace62002-07-17 16:30:39 +000066static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000067
Fred Drake117ac852002-09-24 16:24:54 +000068typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000069typedef void* xmlhandler;
70
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000071struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000072 const char *name;
73 xmlhandlersetter setter;
74 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000075 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000076 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000077};
78
Jeremy Hylton938ace62002-07-17 16:30:39 +000079static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000080
Fred Drakebd6101c2001-02-14 18:29:45 +000081/* Set an integer attribute on the error object; return true on success,
82 * false on an exception.
83 */
84static int
85set_error_attr(PyObject *err, char *name, int value)
86{
Christian Heimes217cfd12007-12-02 14:31:20 +000087 PyObject *v = PyLong_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +000088
Neal Norwitz2f5e9902006-03-08 06:36:45 +000089 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
90 Py_XDECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +000091 return 0;
92 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +000093 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +000094 return 1;
95}
96
97/* Build and set an Expat exception, including positioning
98 * information. Always returns NULL.
99 */
Fred Drake85d835f2001-02-08 15:39:08 +0000100static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000101set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000102{
103 PyObject *err;
Victor Stinner499dfcf2011-03-21 13:26:24 +0100104 PyObject *buffer;
Fred Drake85d835f2001-02-08 15:39:08 +0000105 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000106 int lineno = XML_GetErrorLineNumber(parser);
107 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000108
Victor Stinner499dfcf2011-03-21 13:26:24 +0100109 buffer = PyUnicode_FromFormat("%s: line %i, column %i",
110 XML_ErrorString(code), lineno, column);
111 if (buffer == NULL)
112 return NULL;
113 err = PyObject_CallFunction(ErrorObject, "O", buffer);
114 Py_DECREF(buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000115 if ( err != NULL
116 && set_error_attr(err, "code", code)
117 && set_error_attr(err, "offset", column)
118 && set_error_attr(err, "lineno", lineno)) {
119 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000120 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000121 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000122 return NULL;
123}
124
Fred Drake71b63ff2002-06-28 22:29:01 +0000125static int
126have_handler(xmlparseobject *self, int type)
127{
128 PyObject *handler = self->handlers[type];
129 return handler != NULL;
130}
131
132static PyObject *
133get_handler_name(struct HandlerInfo *hinfo)
134{
135 PyObject *name = hinfo->nameobj;
136 if (name == NULL) {
Neal Norwitz392c5be2007-08-25 17:20:32 +0000137 name = PyUnicode_FromString(hinfo->name);
Fred Drake71b63ff2002-06-28 22:29:01 +0000138 hinfo->nameobj = name;
139 }
140 Py_XINCREF(name);
141 return name;
142}
143
Fred Drake85d835f2001-02-08 15:39:08 +0000144
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000145/* Convert a string of XML_Chars into a Unicode string.
146 Returns None if str is a null pointer. */
147
Fred Drake0582df92000-07-12 04:49:00 +0000148static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000149conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000150{
Fred Drake71b63ff2002-06-28 22:29:01 +0000151 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000152 and hence in UTF-8. */
153 /* UTF-8 from Expat, Unicode desired */
154 if (str == NULL) {
155 Py_INCREF(Py_None);
156 return Py_None;
157 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000158 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000159}
160
Fred Drake0582df92000-07-12 04:49:00 +0000161static PyObject *
162conv_string_len_to_unicode(const XML_Char *str, int len)
163{
Fred Drake71b63ff2002-06-28 22:29:01 +0000164 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000165 and hence in UTF-8. */
166 /* UTF-8 from Expat, Unicode desired */
167 if (str == NULL) {
168 Py_INCREF(Py_None);
169 return Py_None;
170 }
Fred Drake6f987622000-08-25 18:03:30 +0000171 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000172}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000173
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000174/* Callback routines */
175
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000176static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000177
Martin v. Löwis069dde22003-01-21 10:58:18 +0000178/* This handler is used when an error has been detected, in the hope
179 that actual parsing can be terminated early. This will only help
180 if an external entity reference is encountered. */
181static int
182error_external_entity_ref_handler(XML_Parser parser,
183 const XML_Char *context,
184 const XML_Char *base,
185 const XML_Char *systemId,
186 const XML_Char *publicId)
187{
188 return 0;
189}
190
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000191/* Dummy character data handler used when an error (exception) has
192 been detected, and the actual parsing can be terminated early.
193 This is needed since character data handler can't be safely removed
194 from within the character data handler, but can be replaced. It is
195 used only from the character data handler trampoline, and must be
196 used right after `flag_error()` is called. */
197static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198noop_character_data_handler(void *userData, const XML_Char *data, int len)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000199{
200 /* Do nothing. */
201}
202
Fred Drake6f987622000-08-25 18:03:30 +0000203static void
204flag_error(xmlparseobject *self)
205{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000206 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000207 XML_SetExternalEntityRefHandler(self->itself,
208 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000209}
210
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000211static PyObject*
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200212call_with_frame(char *funcname, int lineno, PyObject* func, PyObject* args,
Fred Drake39689c52004-08-13 03:12:57 +0000213 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000214{
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200215 PyObject *res;
Fred Drakebd6101c2001-02-14 18:29:45 +0000216
Fred Drakebd6101c2001-02-14 18:29:45 +0000217 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000218 if (res == NULL) {
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200219 _PyTraceback_Add(funcname, __FILE__, lineno);
Fred Drake39689c52004-08-13 03:12:57 +0000220 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000221 }
Fred Drakebd6101c2001-02-14 18:29:45 +0000222 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000223}
224
Fred Drakeb91a36b2002-06-27 19:40:48 +0000225static PyObject*
226string_intern(xmlparseobject *self, const char* str)
227{
Guido van Rossum4ca94712007-07-23 17:42:32 +0000228 PyObject *result = conv_string_to_unicode(str);
Fred Drakeb91a36b2002-06-27 19:40:48 +0000229 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000230 /* result can be NULL if the unicode conversion failed. */
231 if (!result)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000233 if (!self->intern)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000235 value = PyDict_GetItem(self->intern, result);
236 if (!value) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 if (PyDict_SetItem(self->intern, result, result) == 0)
Fred Drakeb91a36b2002-06-27 19:40:48 +0000238 return result;
239 else
240 return NULL;
241 }
242 Py_INCREF(value);
243 Py_DECREF(result);
244 return value;
245}
246
Fred Drake2a3d7db2002-06-28 22:56:48 +0000247/* Return 0 on success, -1 on exception.
248 * flag_error() will be called before return if needed.
249 */
250static int
251call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
252{
253 PyObject *args;
254 PyObject *temp;
255
Georg Brandlc01537f2010-10-15 16:26:08 +0000256 if (!have_handler(self, CharacterData))
257 return -1;
258
Fred Drake2a3d7db2002-06-28 22:56:48 +0000259 args = PyTuple_New(1);
260 if (args == NULL)
261 return -1;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000262 temp = (conv_string_len_to_unicode(buffer, len));
Fred Drake2a3d7db2002-06-28 22:56:48 +0000263 if (temp == NULL) {
264 Py_DECREF(args);
265 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000266 XML_SetCharacterDataHandler(self->itself,
267 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000268 return -1;
269 }
270 PyTuple_SET_ITEM(args, 0, temp);
271 /* temp is now a borrowed reference; consider it unused. */
272 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200273 temp = call_with_frame("CharacterData", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000274 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000275 /* temp is an owned reference again, or NULL */
276 self->in_callback = 0;
277 Py_DECREF(args);
278 if (temp == NULL) {
279 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280 XML_SetCharacterDataHandler(self->itself,
281 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000282 return -1;
283 }
284 Py_DECREF(temp);
285 return 0;
286}
287
288static int
289flush_character_buffer(xmlparseobject *self)
290{
291 int rc;
292 if (self->buffer == NULL || self->buffer_used == 0)
293 return 0;
294 rc = call_character_handler(self, self->buffer, self->buffer_used);
295 self->buffer_used = 0;
296 return rc;
297}
298
299static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
Fred Drake2a3d7db2002-06-28 22:56:48 +0000301{
302 xmlparseobject *self = (xmlparseobject *) userData;
Victor Stinner9e09c262013-07-18 23:17:01 +0200303
304 if (PyErr_Occurred())
305 return;
306
Fred Drake2a3d7db2002-06-28 22:56:48 +0000307 if (self->buffer == NULL)
308 call_character_handler(self, data, len);
309 else {
310 if ((self->buffer_used + len) > self->buffer_size) {
311 if (flush_character_buffer(self) < 0)
312 return;
313 /* handler might have changed; drop the rest on the floor
314 * if there isn't a handler anymore
315 */
316 if (!have_handler(self, CharacterData))
317 return;
318 }
319 if (len > self->buffer_size) {
320 call_character_handler(self, data, len);
321 self->buffer_used = 0;
322 }
323 else {
324 memcpy(self->buffer + self->buffer_used,
325 data, len * sizeof(XML_Char));
326 self->buffer_used += len;
327 }
328 }
329}
330
Fred Drake85d835f2001-02-08 15:39:08 +0000331static void
332my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000333 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000334{
335 xmlparseobject *self = (xmlparseobject *)userData;
336
Fred Drake71b63ff2002-06-28 22:29:01 +0000337 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000338 PyObject *container, *rv, *args;
339 int i, max;
340
Victor Stinner9e09c262013-07-18 23:17:01 +0200341 if (PyErr_Occurred())
342 return;
343
Fred Drake2a3d7db2002-06-28 22:56:48 +0000344 if (flush_character_buffer(self) < 0)
345 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000346 /* Set max to the number of slots filled in atts[]; max/2 is
347 * the number of attributes we need to process.
348 */
349 if (self->specified_attributes) {
350 max = XML_GetSpecifiedAttributeCount(self->itself);
351 }
352 else {
353 max = 0;
354 while (atts[max] != NULL)
355 max += 2;
356 }
357 /* Build the container. */
358 if (self->ordered_attributes)
359 container = PyList_New(max);
360 else
361 container = PyDict_New();
362 if (container == NULL) {
363 flag_error(self);
364 return;
365 }
366 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000367 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000368 PyObject *v;
369 if (n == NULL) {
370 flag_error(self);
371 Py_DECREF(container);
372 return;
373 }
Guido van Rossum4ca94712007-07-23 17:42:32 +0000374 v = conv_string_to_unicode((XML_Char *) atts[i+1]);
Fred Drake85d835f2001-02-08 15:39:08 +0000375 if (v == NULL) {
376 flag_error(self);
377 Py_DECREF(container);
378 Py_DECREF(n);
379 return;
380 }
381 if (self->ordered_attributes) {
382 PyList_SET_ITEM(container, i, n);
383 PyList_SET_ITEM(container, i+1, v);
384 }
385 else if (PyDict_SetItem(container, n, v)) {
386 flag_error(self);
387 Py_DECREF(n);
388 Py_DECREF(v);
389 return;
390 }
391 else {
392 Py_DECREF(n);
393 Py_DECREF(v);
394 }
395 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000396 args = string_intern(self, name);
397 if (args != NULL)
398 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000399 if (args == NULL) {
400 Py_DECREF(container);
401 return;
402 }
403 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000404 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200405 rv = call_with_frame("StartElement", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000406 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000407 self->in_callback = 0;
408 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000409 if (rv == NULL) {
410 flag_error(self);
411 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000412 }
Fred Drake85d835f2001-02-08 15:39:08 +0000413 Py_DECREF(rv);
414 }
415}
416
417#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
418 RETURN, GETUSERDATA) \
419static RC \
420my_##NAME##Handler PARAMS {\
421 xmlparseobject *self = GETUSERDATA ; \
422 PyObject *args = NULL; \
423 PyObject *rv = NULL; \
424 INIT \
425\
Fred Drake71b63ff2002-06-28 22:29:01 +0000426 if (have_handler(self, NAME)) { \
Victor Stinner9e09c262013-07-18 23:17:01 +0200427 if (PyErr_Occurred()) \
428 return RETURN; \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000429 if (flush_character_buffer(self) < 0) \
430 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000431 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000432 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000433 self->in_callback = 1; \
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200434 rv = call_with_frame(#NAME,__LINE__, \
Fred Drake39689c52004-08-13 03:12:57 +0000435 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000436 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000437 Py_DECREF(args); \
438 if (rv == NULL) { \
439 flag_error(self); \
440 return RETURN; \
441 } \
442 CONVERSION \
443 Py_DECREF(rv); \
444 } \
445 return RETURN; \
446}
447
Fred Drake6f987622000-08-25 18:03:30 +0000448#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
450 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000451
Fred Drake6f987622000-08-25 18:03:30 +0000452#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
454 rc = PyLong_AsLong(rv);, rc, \
455 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000456
Fred Drake71b63ff2002-06-28 22:29:01 +0000457VOID_HANDLER(EndElement,
458 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000459 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000460
Fred Drake6f987622000-08-25 18:03:30 +0000461VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000462 (void *userData,
463 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000464 const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000465 ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000466
Fred Drake6f987622000-08-25 18:03:30 +0000467VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000468 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000469 const XML_Char *entityName,
470 const XML_Char *base,
471 const XML_Char *systemId,
472 const XML_Char *publicId,
473 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000474 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000475 string_intern(self, entityName), string_intern(self, base),
476 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000477 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000478
Fred Drake85d835f2001-02-08 15:39:08 +0000479VOID_HANDLER(EntityDecl,
480 (void *userData,
481 const XML_Char *entityName,
482 int is_parameter_entity,
483 const XML_Char *value,
484 int value_length,
485 const XML_Char *base,
486 const XML_Char *systemId,
487 const XML_Char *publicId,
488 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000489 ("NiNNNNN",
490 string_intern(self, entityName), is_parameter_entity,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000491 (conv_string_len_to_unicode(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000492 string_intern(self, base), string_intern(self, systemId),
493 string_intern(self, publicId),
494 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000495
496VOID_HANDLER(XmlDecl,
497 (void *userData,
498 const XML_Char *version,
499 const XML_Char *encoding,
500 int standalone),
501 ("(O&O&i)",
Guido van Rossum4ca94712007-07-23 17:42:32 +0000502 conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000503 standalone))
504
505static PyObject *
506conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000507 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000508{
509 PyObject *result = NULL;
510 PyObject *children = PyTuple_New(model->numchildren);
511 int i;
512
513 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000514 assert(model->numchildren < INT_MAX);
515 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000516 PyObject *child = conv_content_model(&model->children[i],
517 conv_string);
518 if (child == NULL) {
519 Py_XDECREF(children);
520 return NULL;
521 }
522 PyTuple_SET_ITEM(children, i, child);
523 }
524 result = Py_BuildValue("(iiO&N)",
525 model->type, model->quant,
526 conv_string,model->name, children);
527 }
528 return result;
529}
530
Fred Drake06dd8cf2003-02-02 03:54:17 +0000531static void
532my_ElementDeclHandler(void *userData,
533 const XML_Char *name,
534 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000535{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000536 xmlparseobject *self = (xmlparseobject *)userData;
537 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000538
Fred Drake06dd8cf2003-02-02 03:54:17 +0000539 if (have_handler(self, ElementDecl)) {
540 PyObject *rv = NULL;
541 PyObject *modelobj, *nameobj;
542
Victor Stinner9e09c262013-07-18 23:17:01 +0200543 if (PyErr_Occurred())
544 return;
545
Fred Drake06dd8cf2003-02-02 03:54:17 +0000546 if (flush_character_buffer(self) < 0)
547 goto finally;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000548 modelobj = conv_content_model(model, (conv_string_to_unicode));
Fred Drake06dd8cf2003-02-02 03:54:17 +0000549 if (modelobj == NULL) {
550 flag_error(self);
551 goto finally;
552 }
553 nameobj = string_intern(self, name);
554 if (nameobj == NULL) {
555 Py_DECREF(modelobj);
556 flag_error(self);
557 goto finally;
558 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000559 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000560 if (args == NULL) {
561 Py_DECREF(modelobj);
562 flag_error(self);
563 goto finally;
564 }
565 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200566 rv = call_with_frame("ElementDecl", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000567 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000568 self->in_callback = 0;
569 if (rv == NULL) {
570 flag_error(self);
571 goto finally;
572 }
573 Py_DECREF(rv);
574 }
575 finally:
576 Py_XDECREF(args);
577 XML_FreeContentModel(self->itself, model);
578 return;
579}
Fred Drake85d835f2001-02-08 15:39:08 +0000580
581VOID_HANDLER(AttlistDecl,
582 (void *userData,
583 const XML_Char *elname,
584 const XML_Char *attname,
585 const XML_Char *att_type,
586 const XML_Char *dflt,
587 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000588 ("(NNO&O&i)",
589 string_intern(self, elname), string_intern(self, attname),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000590 conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
Fred Drake85d835f2001-02-08 15:39:08 +0000591 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000592
Martin v. Löwisc847f402003-01-21 11:09:21 +0000593#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000594VOID_HANDLER(SkippedEntity,
595 (void *userData,
596 const XML_Char *entityName,
597 int is_parameter_entity),
598 ("Ni",
599 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000600#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000601
Fred Drake71b63ff2002-06-28 22:29:01 +0000602VOID_HANDLER(NotationDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 (void *userData,
604 const XML_Char *notationName,
605 const XML_Char *base,
606 const XML_Char *systemId,
607 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000608 ("(NNNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 string_intern(self, notationName), string_intern(self, base),
610 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000611
Fred Drake6f987622000-08-25 18:03:30 +0000612VOID_HANDLER(StartNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 (void *userData,
614 const XML_Char *prefix,
615 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000616 ("(NN)",
617 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000618
Fred Drake6f987622000-08-25 18:03:30 +0000619VOID_HANDLER(EndNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 (void *userData,
621 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000622 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000623
Fred Drake6f987622000-08-25 18:03:30 +0000624VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000625 (void *userData, const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000626 ("(O&)", conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000627
Fred Drake6f987622000-08-25 18:03:30 +0000628VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000629 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000631
Fred Drake6f987622000-08-25 18:03:30 +0000632VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000633 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000635
Fred Drake6f987622000-08-25 18:03:30 +0000636VOID_HANDLER(Default,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 (void *userData, const XML_Char *s, int len),
638 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000639
Fred Drake6f987622000-08-25 18:03:30 +0000640VOID_HANDLER(DefaultHandlerExpand,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 (void *userData, const XML_Char *s, int len),
642 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000643
Fred Drake71b63ff2002-06-28 22:29:01 +0000644INT_HANDLER(NotStandalone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 (void *userData),
646 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000647
Fred Drake6f987622000-08-25 18:03:30 +0000648RC_HANDLER(int, ExternalEntityRef,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 (XML_Parser parser,
650 const XML_Char *context,
651 const XML_Char *base,
652 const XML_Char *systemId,
653 const XML_Char *publicId),
654 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000655 ("(O&NNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 conv_string_to_unicode ,context, string_intern(self, base),
657 string_intern(self, systemId), string_intern(self, publicId)),
658 rc = PyLong_AsLong(rv);, rc,
659 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000660
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000661/* XXX UnknownEncodingHandler */
662
Fred Drake85d835f2001-02-08 15:39:08 +0000663VOID_HANDLER(StartDoctypeDecl,
664 (void *userData, const XML_Char *doctypeName,
665 const XML_Char *sysid, const XML_Char *pubid,
666 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000667 ("(NNNi)", string_intern(self, doctypeName),
668 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000669 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000670
671VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000672
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000673/* ---------------------------------------------------------------- */
674
Fred Drake71b63ff2002-06-28 22:29:01 +0000675static PyObject *
676get_parse_result(xmlparseobject *self, int rv)
677{
678 if (PyErr_Occurred()) {
679 return NULL;
680 }
681 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000682 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000683 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000684 if (flush_character_buffer(self) < 0) {
685 return NULL;
686 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000687 return PyLong_FromLong(rv);
Fred Drake71b63ff2002-06-28 22:29:01 +0000688}
689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000690PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000691"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000692Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000693
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200694#define MAX_CHUNK_SIZE (1 << 20)
695
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000696static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000697xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000698{
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200699 PyObject *data;
Fred Drake0582df92000-07-12 04:49:00 +0000700 int isFinal = 0;
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200701 const char *s;
702 Py_ssize_t slen;
703 Py_buffer view;
704 int rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000705
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200706 if (!PyArg_ParseTuple(args, "O|i:Parse", &data, &isFinal))
Fred Drake0582df92000-07-12 04:49:00 +0000707 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000708
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200709 if (PyUnicode_Check(data)) {
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200710 view.buf = NULL;
Serhiy Storchaka36b365c2013-02-04 18:28:01 +0200711 s = PyUnicode_AsUTF8AndSize(data, &slen);
712 if (s == NULL)
713 return NULL;
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200714 /* Explicitly set UTF-8 encoding. Return code ignored. */
715 (void)XML_SetEncoding(self->itself, "utf-8");
716 }
717 else {
718 if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
719 return NULL;
720 s = view.buf;
721 slen = view.len;
722 }
723
724 while (slen > MAX_CHUNK_SIZE) {
725 rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0);
726 if (!rc)
727 goto done;
728 s += MAX_CHUNK_SIZE;
729 slen -= MAX_CHUNK_SIZE;
730 }
Christian Heimesba723202013-11-22 00:46:18 +0100731 assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX);
732 rc = XML_Parse(self->itself, s, (int)slen, isFinal);
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200733
734done:
735 if (view.buf != NULL)
736 PyBuffer_Release(&view);
737 return get_parse_result(self, rc);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000738}
739
Fred Drakeca1f4262000-09-21 20:10:23 +0000740/* File reading copied from cPickle */
741
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000742#define BUF_SIZE 2048
743
Fred Drake0582df92000-07-12 04:49:00 +0000744static int
745readinst(char *buf, int buf_size, PyObject *meth)
746{
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000747 PyObject *str;
748 Py_ssize_t len;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000749 char *ptr;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000750
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000751 str = PyObject_CallFunction(meth, "n", buf_size);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000752 if (str == NULL)
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000753 goto error;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000754
Christian Heimes72b710a2008-05-26 13:28:38 +0000755 if (PyBytes_Check(str))
756 ptr = PyBytes_AS_STRING(str);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000757 else if (PyByteArray_Check(str))
758 ptr = PyByteArray_AS_STRING(str);
Guido van Rossum98297ee2007-11-06 21:34:58 +0000759 else {
Fred Drake71b63ff2002-06-28 22:29:01 +0000760 PyErr_Format(PyExc_TypeError,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000761 "read() did not return a bytes object (type=%.400s)",
Christian Heimes90aa7642007-12-19 02:45:37 +0000762 Py_TYPE(str)->tp_name);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000763 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000764 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000765 len = Py_SIZE(str);
Fred Drake0582df92000-07-12 04:49:00 +0000766 if (len > buf_size) {
767 PyErr_Format(PyExc_ValueError,
768 "read() returned too much data: "
Victor Stinner9d6f9362011-01-04 22:00:04 +0000769 "%i bytes requested, %zd returned",
Fred Drake0582df92000-07-12 04:49:00 +0000770 buf_size, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000771 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000772 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000773 memcpy(buf, ptr, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000774 Py_DECREF(str);
775 /* len <= buf_size <= INT_MAX */
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000776 return (int)len;
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000777
778error:
779 Py_XDECREF(str);
780 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000781}
782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000783PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000784"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000785Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000786
787static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000788xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000789{
Fred Drake0582df92000-07-12 04:49:00 +0000790 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000791 PyObject *readmethod = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200792 _Py_IDENTIFIER(read);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000793
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200794 readmethod = _PyObject_GetAttrId(f, &PyId_read);
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000795 if (readmethod == NULL) {
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000796 PyErr_SetString(PyExc_TypeError,
797 "argument must have 'read' attribute");
798 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000799 }
800 for (;;) {
801 int bytes_read;
802 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000803 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000804 Py_XDECREF(readmethod);
Ned Deilye7d532f2014-03-27 16:39:58 -0700805 return get_parse_result(self, 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000806 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000807
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000808 bytes_read = readinst(buf, BUF_SIZE, readmethod);
809 if (bytes_read < 0) {
810 Py_DECREF(readmethod);
811 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000812 }
813 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000814 if (PyErr_Occurred()) {
815 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000816 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000817 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000818
Fred Drake0582df92000-07-12 04:49:00 +0000819 if (!rv || bytes_read == 0)
820 break;
821 }
Fred Drake7b6caff2003-07-21 17:05:56 +0000822 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +0000823 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000824}
825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000826PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000827"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000828Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000829
830static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000831xmlparse_SetBase(xmlparseobject *self, PyObject *args)
832{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000833 char *base;
834
Fred Drake0582df92000-07-12 04:49:00 +0000835 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000836 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000837 if (!XML_SetBase(self->itself, base)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000839 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000840 Py_INCREF(Py_None);
841 return Py_None;
842}
843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000844PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000845"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000846Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000847
848static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000849xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +0000850{
Fred Drake0582df92000-07-12 04:49:00 +0000851 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000852}
853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000854PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +0000855"GetInputContext() -> string\n\
856Return the untranslated text of the input that caused the current event.\n\
857If 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 +0000858for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +0000859
860static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000861xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +0000862{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000863 if (self->in_callback) {
864 int offset, size;
865 const char *buffer
866 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +0000867
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000868 if (buffer != NULL)
Christian Heimes72b710a2008-05-26 13:28:38 +0000869 return PyBytes_FromStringAndSize(buffer + offset,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000870 size - offset);
871 else
872 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000873 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000874 else
875 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000876}
Fred Drakebd6101c2001-02-14 18:29:45 +0000877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000878PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +0000879"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +0000880Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000881information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000882
883static PyObject *
884xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
885{
886 char *context;
887 char *encoding = NULL;
888 xmlparseobject *new_parser;
889 int i;
890
Martin v. Löwisc57428d2001-09-19 09:55:09 +0000891 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +0000892 &context, &encoding)) {
893 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000894 }
895
Martin v. Löwis894258c2001-09-23 10:20:10 +0000896 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake85d835f2001-02-08 15:39:08 +0000897 if (new_parser == NULL)
898 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +0000899 new_parser->buffer_size = self->buffer_size;
900 new_parser->buffer_used = 0;
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000901 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000902 new_parser->ordered_attributes = self->ordered_attributes;
903 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +0000904 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000905 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000906 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000908 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000909 new_parser->intern = self->intern;
910 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000911 PyObject_GC_Track(new_parser);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000912
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000913 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +0200914 new_parser->buffer = PyMem_Malloc(new_parser->buffer_size);
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000915 if (new_parser->buffer == NULL) {
916 Py_DECREF(new_parser);
917 return PyErr_NoMemory();
918 }
919 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000920 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +0000921 Py_DECREF(new_parser);
922 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000923 }
924
925 XML_SetUserData(new_parser->itself, (void *)new_parser);
926
927 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +0000928 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +0000929 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000930
Victor Stinnerb6404912013-07-07 16:21:41 +0200931 new_parser->handlers = PyMem_Malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000932 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +0000933 Py_DECREF(new_parser);
934 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000935 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000936 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000937
938 /* then copy handlers from self */
939 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000940 PyObject *handler = self->handlers[i];
941 if (handler != NULL) {
942 Py_INCREF(handler);
943 new_parser->handlers[i] = handler;
944 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +0000945 handler_info[i].handler);
946 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000947 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000948 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000949}
950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000951PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000952"SetParamEntityParsing(flag) -> success\n\
953Controls parsing of parameter entities (including the external DTD\n\
954subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
955XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
956XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000957was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000958
959static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +0000960xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000961{
Fred Drake85d835f2001-02-08 15:39:08 +0000962 int flag;
963 if (!PyArg_ParseTuple(args, "i", &flag))
964 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +0000965 flag = XML_SetParamEntityParsing(p->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +0000966 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000967}
968
Martin v. Löwisc847f402003-01-21 11:09:21 +0000969
970#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +0000971PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
972"UseForeignDTD([flag])\n\
973Allows the application to provide an artificial external subset if one is\n\
974not specified as part of the document instance. This readily allows the\n\
975use of a 'default' document type controlled by the application, while still\n\
976getting the advantage of providing document type information to the parser.\n\
977'flag' defaults to True if not provided.");
978
979static PyObject *
980xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
981{
Antoine Pitrou6f430e42012-08-15 23:18:25 +0200982 int flag = 1;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000983 enum XML_Error rc;
Georg Brandld37b9d72012-09-24 13:41:52 +0200984 if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", &flag))
Martin v. Löwis069dde22003-01-21 10:58:18 +0000985 return NULL;
Antoine Pitrou6f430e42012-08-15 23:18:25 +0200986 rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000987 if (rc != XML_ERROR_NONE) {
988 return set_error(self, rc);
989 }
990 Py_INCREF(Py_None);
991 return Py_None;
992}
Martin v. Löwisc847f402003-01-21 11:09:21 +0000993#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000994
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +0000995static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs);
996
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000997static struct PyMethodDef xmlparse_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 {"Parse", (PyCFunction)xmlparse_Parse,
999 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001000 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001002 {"SetBase", (PyCFunction)xmlparse_SetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001004 {"GetBase", (PyCFunction)xmlparse_GetBase,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001006 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001008 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001010 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001012#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001013 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001015#endif
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001016 {"__dir__", xmlparse_dir, METH_NOARGS},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001018};
1019
1020/* ---------- */
1021
1022
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001023
Fred Drake71b63ff2002-06-28 22:29:01 +00001024/* pyexpat international encoding support.
1025 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001026*/
1027
Fred Drake71b63ff2002-06-28 22:29:01 +00001028static int
1029PyUnknownEncodingHandler(void *encodingHandlerData,
1030 const XML_Char *name,
1031 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001032{
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001033 static unsigned char template_buffer[256] = {0};
1034 PyObject* u;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001035 int i;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001036 void *data;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001037 unsigned int kind;
Fred Drake71b63ff2002-06-28 22:29:01 +00001038
Victor Stinner9e09c262013-07-18 23:17:01 +02001039 if (PyErr_Occurred())
1040 return XML_STATUS_ERROR;
1041
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001042 if (template_buffer[1] == 0) {
1043 for (i = 0; i < 256; i++)
1044 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001045 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001046
1047 u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace");
Christian Heimesb5821552013-06-29 20:43:13 +02001048 if (u == NULL || PyUnicode_READY(u)) {
Christian Heimes72172422013-06-29 21:49:27 +02001049 Py_XDECREF(u);
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001050 return XML_STATUS_ERROR;
Christian Heimesb5821552013-06-29 20:43:13 +02001051 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001052
1053 if (PyUnicode_GET_LENGTH(u) != 256) {
1054 Py_DECREF(u);
1055 PyErr_SetString(PyExc_ValueError,
1056 "multi-byte encodings are not supported");
1057 return XML_STATUS_ERROR;
1058 }
1059
1060 kind = PyUnicode_KIND(u);
1061 data = PyUnicode_DATA(u);
1062 for (i = 0; i < 256; i++) {
1063 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
1064 if (ch != Py_UNICODE_REPLACEMENT_CHARACTER)
1065 info->map[i] = ch;
1066 else
1067 info->map[i] = -1;
1068 }
1069
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001070 info->data = NULL;
1071 info->convert = NULL;
1072 info->release = NULL;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001073 Py_DECREF(u);
1074
1075 return XML_STATUS_OK;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001076}
1077
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001078
1079static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001080newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001081{
1082 int i;
1083 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001084
Martin v. Löwis894258c2001-09-23 10:20:10 +00001085 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake0582df92000-07-12 04:49:00 +00001086 if (self == NULL)
1087 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001088
Fred Drake2a3d7db2002-06-28 22:56:48 +00001089 self->buffer = NULL;
1090 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1091 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001092 self->ordered_attributes = 0;
1093 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001094 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001095 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001096 self->handlers = NULL;
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001097 self->intern = intern;
1098 Py_XINCREF(self->intern);
1099 PyObject_GC_Track(self);
1100
Christian Heimesfa535f52013-07-07 17:35:11 +02001101 /* namespace_separator is either NULL or contains one char + \0 */
1102 self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler,
1103 namespace_separator);
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001104 if (self->itself == NULL) {
1105 PyErr_SetString(PyExc_RuntimeError,
1106 "XML_ParserCreate failed");
1107 Py_DECREF(self);
1108 return NULL;
1109 }
Gregory P. Smith25227712012-03-14 18:10:37 -07001110#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)
1111 /* This feature was added upstream in libexpat 2.1.0. Our expat copy
1112 * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
1113 * to indicate that we can still use it. */
Gregory P. Smith8e91cf62012-03-14 14:26:55 -07001114 XML_SetHashSalt(self->itself,
Christian Heimes985ecdc2013-11-20 11:46:18 +01001115 (unsigned long)_Py_HashSecret.expat.hashsalt);
Gregory P. Smith25227712012-03-14 18:10:37 -07001116#endif
Fred Drake0582df92000-07-12 04:49:00 +00001117 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001118 XML_SetUnknownEncodingHandler(self->itself,
1119 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001120
Fred Drake2a3d7db2002-06-28 22:56:48 +00001121 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001122 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001123
Victor Stinnerb6404912013-07-07 16:21:41 +02001124 self->handlers = PyMem_Malloc(sizeof(PyObject *) * i);
Fred Drake7c75bf22002-07-01 14:02:31 +00001125 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001126 Py_DECREF(self);
1127 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001128 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001129 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001130
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001131 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001132}
1133
1134
1135static void
Fred Drake0582df92000-07-12 04:49:00 +00001136xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001137{
Fred Drake0582df92000-07-12 04:49:00 +00001138 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001139 PyObject_GC_UnTrack(self);
Fred Drake85d835f2001-02-08 15:39:08 +00001140 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001141 XML_ParserFree(self->itself);
1142 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001143
Fred Drake85d835f2001-02-08 15:39:08 +00001144 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001145 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001146 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001147 temp = self->handlers[i];
1148 self->handlers[i] = NULL;
1149 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001150 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001151 PyMem_Free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001152 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001153 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001154 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001155 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001156 self->buffer = NULL;
1157 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001158 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001159 PyObject_GC_Del(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001160}
1161
Fred Drake0582df92000-07-12 04:49:00 +00001162static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001163handlername2int(PyObject *name)
Fred Drake0582df92000-07-12 04:49:00 +00001164{
1165 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001166 for (i = 0; handler_info[i].name != NULL; i++) {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001167 if (PyUnicode_CompareWithASCIIString(
1168 name, handler_info[i].name) == 0) {
Fred Drake0582df92000-07-12 04:49:00 +00001169 return i;
1170 }
1171 }
1172 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001173}
1174
1175static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001176get_pybool(int istrue)
1177{
1178 PyObject *result = istrue ? Py_True : Py_False;
1179 Py_INCREF(result);
1180 return result;
1181}
1182
1183static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001184xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001185{
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001186 Py_UCS4 first_char;
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001187 int handlernum = -1;
1188
Alexander Belopolskye239d232010-12-08 23:31:48 +00001189 if (!PyUnicode_Check(nameobj))
1190 goto generic;
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001191 if (PyUnicode_READY(nameobj))
1192 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193
Alexander Belopolskye239d232010-12-08 23:31:48 +00001194 handlernum = handlername2int(nameobj);
Fred Drake71b63ff2002-06-28 22:29:01 +00001195
1196 if (handlernum != -1) {
1197 PyObject *result = self->handlers[handlernum];
1198 if (result == NULL)
1199 result = Py_None;
1200 Py_INCREF(result);
1201 return result;
1202 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001203
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001204 first_char = PyUnicode_READ_CHAR(nameobj, 0);
1205 if (first_char == 'E') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001206 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorCode") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001207 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001208 XML_GetErrorCode(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001209 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001210 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001211 XML_GetErrorLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001212 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001213 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001214 XML_GetErrorColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001215 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001216 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001217 XML_GetErrorByteIndex(self->itself));
1218 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001219 if (first_char == 'C') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001220 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001221 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001222 XML_GetCurrentLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001223 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001224 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001225 XML_GetCurrentColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001226 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001227 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001228 XML_GetCurrentByteIndex(self->itself));
1229 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001230 if (first_char == 'b') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001231 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_size") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001232 return PyLong_FromLong((long) self->buffer_size);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001233 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_text") == 0)
Fred Drake2a3d7db2002-06-28 22:56:48 +00001234 return get_pybool(self->buffer != NULL);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001235 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_used") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001236 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001237 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001238 if (PyUnicode_CompareWithASCIIString(nameobj, "namespace_prefixes") == 0)
Martin v. Löwis069dde22003-01-21 10:58:18 +00001239 return get_pybool(self->ns_prefixes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001240 if (PyUnicode_CompareWithASCIIString(nameobj, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001241 return get_pybool(self->ordered_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001242 if (PyUnicode_CompareWithASCIIString(nameobj, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001243 return get_pybool((long) self->specified_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001244 if (PyUnicode_CompareWithASCIIString(nameobj, "intern") == 0) {
Fred Drakeb91a36b2002-06-27 19:40:48 +00001245 if (self->intern == NULL) {
1246 Py_INCREF(Py_None);
1247 return Py_None;
1248 }
1249 else {
1250 Py_INCREF(self->intern);
1251 return self->intern;
1252 }
1253 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001254 generic:
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001255 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001256}
1257
1258static PyObject *
1259xmlparse_dir(PyObject *self, PyObject* noargs)
1260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261#define APPEND(list, str) \
1262 do { \
1263 PyObject *o = PyUnicode_FromString(str); \
1264 if (o != NULL) \
1265 PyList_Append(list, o); \
1266 Py_XDECREF(o); \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001267 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001268
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001269 int i;
1270 PyObject *rc = PyList_New(0);
1271 if (!rc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 return NULL;
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001273 for (i = 0; handler_info[i].name != NULL; i++) {
1274 PyObject *o = get_handler_name(&handler_info[i]);
1275 if (o != NULL)
1276 PyList_Append(rc, o);
1277 Py_XDECREF(o);
1278 }
1279 APPEND(rc, "ErrorCode");
1280 APPEND(rc, "ErrorLineNumber");
1281 APPEND(rc, "ErrorColumnNumber");
1282 APPEND(rc, "ErrorByteIndex");
1283 APPEND(rc, "CurrentLineNumber");
1284 APPEND(rc, "CurrentColumnNumber");
1285 APPEND(rc, "CurrentByteIndex");
1286 APPEND(rc, "buffer_size");
1287 APPEND(rc, "buffer_text");
1288 APPEND(rc, "buffer_used");
1289 APPEND(rc, "namespace_prefixes");
1290 APPEND(rc, "ordered_attributes");
1291 APPEND(rc, "specified_attributes");
1292 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001293
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001294#undef APPEND
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001295
1296 if (PyErr_Occurred()) {
1297 Py_DECREF(rc);
1298 rc = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001299 }
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001300
1301 return rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001302}
1303
Fred Drake6f987622000-08-25 18:03:30 +00001304static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001305sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001306{
1307 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001308 if (handlernum >= 0) {
1309 xmlhandler c_handler = NULL;
1310 PyObject *temp = self->handlers[handlernum];
1311
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001312 if (v == Py_None) {
1313 /* If this is the character data handler, and a character
1314 data handler is already active, we need to be more
1315 careful. What we can safely do is replace the existing
1316 character data handler callback function with a no-op
1317 function that will refuse to call Python. The downside
1318 is that this doesn't completely remove the character
1319 data handler from the C layer if there's any callback
1320 active, so Expat does a little more work than it
1321 otherwise would, but that's really an odd case. A more
1322 elaborate system of handlers and state could remove the
1323 C handler more effectively. */
1324 if (handlernum == CharacterData && self->in_callback)
1325 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001326 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001327 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001328 else if (v != NULL) {
1329 Py_INCREF(v);
1330 c_handler = handler_info[handlernum].handler;
1331 }
Fred Drake0582df92000-07-12 04:49:00 +00001332 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001333 Py_XDECREF(temp);
1334 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001335 return 1;
1336 }
1337 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001338}
1339
1340static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001341xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001342{
Fred Drake6f987622000-08-25 18:03:30 +00001343 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001344 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001345 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1346 return -1;
1347 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001348 assert(PyUnicode_Check(name));
1349 if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001350 int b = PyObject_IsTrue(v);
1351 if (b < 0)
1352 return -1;
1353 if (b) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001354 if (self->buffer == NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001355 self->buffer = PyMem_Malloc(self->buffer_size);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001356 if (self->buffer == NULL) {
1357 PyErr_NoMemory();
1358 return -1;
1359 }
1360 self->buffer_used = 0;
1361 }
1362 }
1363 else if (self->buffer != NULL) {
1364 if (flush_character_buffer(self) < 0)
1365 return -1;
Victor Stinnerb6404912013-07-07 16:21:41 +02001366 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001367 self->buffer = NULL;
1368 }
1369 return 0;
1370 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001371 if (PyUnicode_CompareWithASCIIString(name, "namespace_prefixes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001372 int b = PyObject_IsTrue(v);
1373 if (b < 0)
1374 return -1;
1375 self->ns_prefixes = b;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001376 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1377 return 0;
1378 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001379 if (PyUnicode_CompareWithASCIIString(name, "ordered_attributes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001380 int b = PyObject_IsTrue(v);
1381 if (b < 0)
1382 return -1;
1383 self->ordered_attributes = b;
Fred Drake85d835f2001-02-08 15:39:08 +00001384 return 0;
1385 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001386 if (PyUnicode_CompareWithASCIIString(name, "specified_attributes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001387 int b = PyObject_IsTrue(v);
1388 if (b < 0)
1389 return -1;
1390 self->specified_attributes = b;
Fred Drake6f987622000-08-25 18:03:30 +00001391 return 0;
1392 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001393
Alexander Belopolskye239d232010-12-08 23:31:48 +00001394 if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
Christian Heimes2380ac72008-01-09 00:17:24 +00001395 long new_buffer_size;
1396 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1398 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001399 }
1400
1401 new_buffer_size=PyLong_AS_LONG(v);
1402 /* trivial case -- no change */
1403 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001405 }
1406
1407 if (new_buffer_size <= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1409 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001410 }
1411
1412 /* check maximum */
1413 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 char errmsg[100];
1415 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1416 PyErr_SetString(PyExc_ValueError, errmsg);
1417 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001418 }
1419
1420 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 /* there is already a buffer */
1422 if (self->buffer_used != 0) {
Christian Heimes09994a92013-07-20 22:41:58 +02001423 if (flush_character_buffer(self) < 0) {
1424 return -1;
1425 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 }
1427 /* free existing buffer */
Victor Stinnerb6404912013-07-07 16:21:41 +02001428 PyMem_Free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001429 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001430 self->buffer = PyMem_Malloc(new_buffer_size);
Christian Heimes2380ac72008-01-09 00:17:24 +00001431 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 PyErr_NoMemory();
1433 return -1;
1434 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001435 self->buffer_size = new_buffer_size;
1436 return 0;
1437 }
1438
Alexander Belopolskye239d232010-12-08 23:31:48 +00001439 if (PyUnicode_CompareWithASCIIString(name, "CharacterDataHandler") == 0) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001440 /* If we're changing the character data handler, flush all
1441 * cached data with the old handler. Not sure there's a
1442 * "right" thing to do, though, but this probably won't
1443 * happen.
1444 */
1445 if (flush_character_buffer(self) < 0)
1446 return -1;
1447 }
Fred Drake6f987622000-08-25 18:03:30 +00001448 if (sethandler(self, name, v)) {
1449 return 0;
1450 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001451 PyErr_SetObject(PyExc_AttributeError, name);
Fred Drake6f987622000-08-25 18:03:30 +00001452 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001453}
1454
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001455static int
1456xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1457{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001458 int i;
1459 for (i = 0; handler_info[i].name != NULL; i++)
1460 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001461 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001462}
1463
1464static int
1465xmlparse_clear(xmlparseobject *op)
1466{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001467 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001468 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001469 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001470}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001472PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001473
1474static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 PyVarObject_HEAD_INIT(NULL, 0)
1476 "pyexpat.xmlparser", /*tp_name*/
Antoine Pitrou23683ef2011-01-04 00:00:31 +00001477 sizeof(xmlparseobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 0, /*tp_itemsize*/
1479 /* methods */
1480 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1481 (printfunc)0, /*tp_print*/
1482 0, /*tp_getattr*/
Alexander Belopolskye239d232010-12-08 23:31:48 +00001483 0, /*tp_setattr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 0, /*tp_reserved*/
1485 (reprfunc)0, /*tp_repr*/
1486 0, /*tp_as_number*/
1487 0, /*tp_as_sequence*/
1488 0, /*tp_as_mapping*/
1489 (hashfunc)0, /*tp_hash*/
1490 (ternaryfunc)0, /*tp_call*/
1491 (reprfunc)0, /*tp_str*/
1492 (getattrofunc)xmlparse_getattro, /* tp_getattro */
Alexander Belopolskye239d232010-12-08 23:31:48 +00001493 (setattrofunc)xmlparse_setattro, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 0, /* tp_as_buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1497 (traverseproc)xmlparse_traverse, /* tp_traverse */
1498 (inquiry)xmlparse_clear, /* tp_clear */
1499 0, /* tp_richcompare */
1500 0, /* tp_weaklistoffset */
1501 0, /* tp_iter */
1502 0, /* tp_iternext */
1503 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001504};
1505
1506/* End of code for xmlparser objects */
1507/* -------------------------------------------------------- */
1508
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001509PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001510"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001511Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001512
1513static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001514pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1515{
Fred Drakecde79132001-04-25 16:01:30 +00001516 char *encoding = NULL;
1517 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001518 PyObject *intern = NULL;
1519 PyObject *result;
1520 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001521 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001522 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001523
Fred Drakeb91a36b2002-06-27 19:40:48 +00001524 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1525 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001526 return NULL;
1527 if (namespace_separator != NULL
1528 && strlen(namespace_separator) > 1) {
1529 PyErr_SetString(PyExc_ValueError,
1530 "namespace_separator must be at most one"
1531 " character, omitted, or None");
1532 return NULL;
1533 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001534 /* Explicitly passing None means no interning is desired.
1535 Not passing anything means that a new dictionary is used. */
1536 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001538 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 intern = PyDict_New();
1540 if (!intern)
1541 return NULL;
1542 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001543 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001544 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1546 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001547 }
1548
1549 result = newxmlparseobject(encoding, namespace_separator, intern);
1550 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001552 }
1553 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001554}
1555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001556PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001557"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001558Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001559
1560static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001561pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001562{
Fred Drake0582df92000-07-12 04:49:00 +00001563 long code = 0;
1564
1565 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1566 return NULL;
1567 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001568}
1569
1570/* List of methods defined in the module */
1571
1572static struct PyMethodDef pyexpat_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
Fred Drake0582df92000-07-12 04:49:00 +00001574 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1576 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001579};
1580
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001581/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001583PyDoc_STRVAR(pyexpat_module_documentation,
1584"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001585
Fred Drakecde79132001-04-25 16:01:30 +00001586/* Initialization function for the module */
1587
1588#ifndef MODULE_NAME
1589#define MODULE_NAME "pyexpat"
1590#endif
1591
1592#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001593#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00001594#endif
1595
Martin v. Löwis069dde22003-01-21 10:58:18 +00001596#ifndef PyMODINIT_FUNC
1597# ifdef MS_WINDOWS
1598# define PyMODINIT_FUNC __declspec(dllexport) void
1599# else
1600# define PyMODINIT_FUNC void
1601# endif
1602#endif
1603
Mark Hammond8235ea12002-07-19 06:55:41 +00001604PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001605
Martin v. Löwis1a214512008-06-11 05:26:20 +00001606static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 PyModuleDef_HEAD_INIT,
1608 MODULE_NAME,
1609 pyexpat_module_documentation,
1610 -1,
1611 pyexpat_methods,
1612 NULL,
1613 NULL,
1614 NULL,
1615 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001616};
1617
Martin v. Löwis069dde22003-01-21 10:58:18 +00001618PyMODINIT_FUNC
1619MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001620{
1621 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001622 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001623 PyObject *errors_module;
1624 PyObject *modelmod_name;
1625 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001626 PyObject *sys_modules;
Georg Brandlb4dac712010-10-15 14:46:48 +00001627 PyObject *tmpnum, *tmpstr;
1628 PyObject *codes_dict;
1629 PyObject *rev_codes_dict;
1630 int res;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001631 static struct PyExpat_CAPI capi;
Georg Brandlb4dac712010-10-15 14:46:48 +00001632 PyObject *capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001633
Fred Drake6f987622000-08-25 18:03:30 +00001634 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001635 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001636 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001637 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001638 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00001639
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001640 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001642
Fred Drake0582df92000-07-12 04:49:00 +00001643 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001644 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001645 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001647
Fred Drake0582df92000-07-12 04:49:00 +00001648 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001649 if (ErrorObject == NULL) {
1650 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001651 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001652 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001653 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001654 }
1655 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001656 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001657 Py_INCREF(ErrorObject);
1658 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001659 Py_INCREF(&Xmlparsetype);
1660 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001661
Fred Drake738293d2000-12-21 17:25:07 +00001662 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1663 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001664 {
1665 XML_Expat_Version info = XML_ExpatVersionInfo();
1666 PyModule_AddObject(m, "version_info",
1667 Py_BuildValue("(iii)", info.major,
1668 info.minor, info.micro));
1669 }
Fred Drake0582df92000-07-12 04:49:00 +00001670 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001671 compiled, this should check and set native_encoding
1672 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001673 */
Fred Drake93adb692000-09-23 04:55:48 +00001674 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001675
Fred Drake85d835f2001-02-08 15:39:08 +00001676 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001677 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001678 errors_module = PyDict_GetItem(d, errmod_name);
1679 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001680 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001681 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001682 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001683 /* gives away the reference to errors_module */
1684 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001685 }
1686 }
Fred Drake6f987622000-08-25 18:03:30 +00001687 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001688 model_module = PyDict_GetItem(d, modelmod_name);
1689 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001690 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001691 if (model_module != NULL) {
1692 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1693 /* gives away the reference to model_module */
1694 PyModule_AddObject(m, "model", model_module);
1695 }
1696 }
1697 Py_DECREF(modelmod_name);
1698 if (errors_module == NULL || model_module == NULL)
1699 /* Don't core dump later! */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001700 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701
Martin v. Löwisc847f402003-01-21 11:09:21 +00001702#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001703 {
1704 const XML_Feature *features = XML_GetFeatureList();
1705 PyObject *list = PyList_New(0);
1706 if (list == NULL)
1707 /* just ignore it */
1708 PyErr_Clear();
1709 else {
1710 int i = 0;
1711 for (; features[i].feature != XML_FEATURE_END; ++i) {
1712 int ok;
1713 PyObject *item = Py_BuildValue("si", features[i].name,
1714 features[i].value);
1715 if (item == NULL) {
1716 Py_DECREF(list);
1717 list = NULL;
1718 break;
1719 }
1720 ok = PyList_Append(list, item);
1721 Py_DECREF(item);
1722 if (ok < 0) {
1723 PyErr_Clear();
1724 break;
1725 }
1726 }
1727 if (list != NULL)
1728 PyModule_AddObject(m, "features", list);
1729 }
1730 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001731#endif
Fred Drake6f987622000-08-25 18:03:30 +00001732
Georg Brandlb4dac712010-10-15 14:46:48 +00001733 codes_dict = PyDict_New();
1734 rev_codes_dict = PyDict_New();
1735 if (codes_dict == NULL || rev_codes_dict == NULL) {
1736 Py_XDECREF(codes_dict);
1737 Py_XDECREF(rev_codes_dict);
1738 return NULL;
1739 }
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001740
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001741#define MYCONST(name) \
Georg Brandlb4dac712010-10-15 14:46:48 +00001742 if (PyModule_AddStringConstant(errors_module, #name, \
1743 (char *)XML_ErrorString(name)) < 0) \
1744 return NULL; \
1745 tmpnum = PyLong_FromLong(name); \
1746 if (tmpnum == NULL) return NULL; \
1747 res = PyDict_SetItemString(codes_dict, \
1748 XML_ErrorString(name), tmpnum); \
1749 if (res < 0) return NULL; \
1750 tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \
1751 if (tmpstr == NULL) return NULL; \
1752 res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \
1753 Py_DECREF(tmpstr); \
1754 Py_DECREF(tmpnum); \
1755 if (res < 0) return NULL; \
Fred Drake7bd9f412000-07-04 23:51:31 +00001756
Fred Drake0582df92000-07-12 04:49:00 +00001757 MYCONST(XML_ERROR_NO_MEMORY);
1758 MYCONST(XML_ERROR_SYNTAX);
1759 MYCONST(XML_ERROR_NO_ELEMENTS);
1760 MYCONST(XML_ERROR_INVALID_TOKEN);
1761 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1762 MYCONST(XML_ERROR_PARTIAL_CHAR);
1763 MYCONST(XML_ERROR_TAG_MISMATCH);
1764 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1765 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1766 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1767 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1768 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1769 MYCONST(XML_ERROR_ASYNC_ENTITY);
1770 MYCONST(XML_ERROR_BAD_CHAR_REF);
1771 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1772 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1773 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1774 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1775 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001776 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1777 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1778 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001779 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1780 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1781 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1782 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1783 /* Added in Expat 1.95.7. */
1784 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1785 /* Added in Expat 1.95.8. */
1786 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1787 MYCONST(XML_ERROR_INCOMPLETE_PE);
1788 MYCONST(XML_ERROR_XML_DECL);
1789 MYCONST(XML_ERROR_TEXT_DECL);
1790 MYCONST(XML_ERROR_PUBLICID);
1791 MYCONST(XML_ERROR_SUSPENDED);
1792 MYCONST(XML_ERROR_NOT_SUSPENDED);
1793 MYCONST(XML_ERROR_ABORTED);
1794 MYCONST(XML_ERROR_FINISHED);
1795 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001796
Georg Brandlb4dac712010-10-15 14:46:48 +00001797 if (PyModule_AddStringConstant(errors_module, "__doc__",
1798 "Constants used to describe "
1799 "error conditions.") < 0)
1800 return NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001801
Georg Brandlb4dac712010-10-15 14:46:48 +00001802 if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0)
1803 return NULL;
1804 if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0)
1805 return NULL;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001806
Fred Drake93adb692000-09-23 04:55:48 +00001807#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001808
Fred Drake85d835f2001-02-08 15:39:08 +00001809#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001810 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1811 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1812 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001813#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001814
Fred Drake85d835f2001-02-08 15:39:08 +00001815#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1816 PyModule_AddStringConstant(model_module, "__doc__",
1817 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001818
Fred Drake85d835f2001-02-08 15:39:08 +00001819 MYCONST(XML_CTYPE_EMPTY);
1820 MYCONST(XML_CTYPE_ANY);
1821 MYCONST(XML_CTYPE_MIXED);
1822 MYCONST(XML_CTYPE_NAME);
1823 MYCONST(XML_CTYPE_CHOICE);
1824 MYCONST(XML_CTYPE_SEQ);
1825
1826 MYCONST(XML_CQUANT_NONE);
1827 MYCONST(XML_CQUANT_OPT);
1828 MYCONST(XML_CQUANT_REP);
1829 MYCONST(XML_CQUANT_PLUS);
1830#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001831
1832 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001833 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001834 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001835 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1836 capi.MINOR_VERSION = XML_MINOR_VERSION;
1837 capi.MICRO_VERSION = XML_MICRO_VERSION;
1838 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001839 capi.GetErrorCode = XML_GetErrorCode;
1840 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1841 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001842 capi.Parse = XML_Parse;
1843 capi.ParserCreate_MM = XML_ParserCreate_MM;
1844 capi.ParserFree = XML_ParserFree;
1845 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1846 capi.SetCommentHandler = XML_SetCommentHandler;
1847 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1848 capi.SetElementHandler = XML_SetElementHandler;
1849 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1850 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1851 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1852 capi.SetUserData = XML_SetUserData;
Eli Bendersky2b6b73e2012-06-01 11:32:34 +03001853 capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
Serhiy Storchaka66d53fa2013-05-22 17:07:51 +03001854 capi.SetEncoding = XML_SetEncoding;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001855 capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856
Benjamin Petersonb173f782009-05-05 22:31:58 +00001857 /* export using capsule */
1858 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001859 if (capi_object)
1860 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001861 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001862}
1863
Fred Drake6f987622000-08-25 18:03:30 +00001864static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001865clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001866{
Fred Drakecde79132001-04-25 16:01:30 +00001867 int i = 0;
1868 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001869
Fred Drake71b63ff2002-06-28 22:29:01 +00001870 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001871 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 self->handlers[i] = NULL;
1873 else {
Fred Drakecde79132001-04-25 16:01:30 +00001874 temp = self->handlers[i];
1875 self->handlers[i] = NULL;
1876 Py_XDECREF(temp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00001878 }
Fred Drakecde79132001-04-25 16:01:30 +00001879 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001880}
1881
Tim Peters0c322792002-07-17 16:49:03 +00001882static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00001883 {"StartElementHandler",
1884 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001885 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001886 {"EndElementHandler",
1887 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001888 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001889 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001890 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1891 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001892 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001893 (xmlhandlersetter)XML_SetCharacterDataHandler,
1894 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001895 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001896 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001897 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001898 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001899 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001900 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001901 {"StartNamespaceDeclHandler",
1902 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001903 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001904 {"EndNamespaceDeclHandler",
1905 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001906 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00001907 {"CommentHandler",
1908 (xmlhandlersetter)XML_SetCommentHandler,
1909 (xmlhandler)my_CommentHandler},
1910 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001911 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001912 (xmlhandler)my_StartCdataSectionHandler},
1913 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001914 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001915 (xmlhandler)my_EndCdataSectionHandler},
1916 {"DefaultHandler",
1917 (xmlhandlersetter)XML_SetDefaultHandler,
1918 (xmlhandler)my_DefaultHandler},
1919 {"DefaultHandlerExpand",
1920 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1921 (xmlhandler)my_DefaultHandlerExpandHandler},
1922 {"NotStandaloneHandler",
1923 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1924 (xmlhandler)my_NotStandaloneHandler},
1925 {"ExternalEntityRefHandler",
1926 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001927 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001928 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001929 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001930 (xmlhandler)my_StartDoctypeDeclHandler},
1931 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001932 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001933 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00001934 {"EntityDeclHandler",
1935 (xmlhandlersetter)XML_SetEntityDeclHandler,
1936 (xmlhandler)my_EntityDeclHandler},
1937 {"XmlDeclHandler",
1938 (xmlhandlersetter)XML_SetXmlDeclHandler,
1939 (xmlhandler)my_XmlDeclHandler},
1940 {"ElementDeclHandler",
1941 (xmlhandlersetter)XML_SetElementDeclHandler,
1942 (xmlhandler)my_ElementDeclHandler},
1943 {"AttlistDeclHandler",
1944 (xmlhandlersetter)XML_SetAttlistDeclHandler,
1945 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001946#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00001947 {"SkippedEntityHandler",
1948 (xmlhandlersetter)XML_SetSkippedEntityHandler,
1949 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001950#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001951
Fred Drake0582df92000-07-12 04:49:00 +00001952 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001953};