blob: 653295bc1f1e2abebf6e620c62fa4ed7cb6b3ed1 [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
Brett Cannond0aeda82014-08-22 14:23:20 -04009/* Do not emit Clinic output to a file as that wreaks havoc with conditionally
10 included methods. */
11/*[clinic input]
12module pyexpat
13[clinic start generated code]*/
14/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b168d503a4490c15]*/
15
Martin v. Löwisc847f402003-01-21 11:09:21 +000016#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
17
Christian Heimesfa535f52013-07-07 17:35:11 +020018static XML_Memory_Handling_Suite ExpatMemoryHandler = {
19 PyObject_Malloc, PyObject_Realloc, PyObject_Free};
20
Fred Drake0582df92000-07-12 04:49:00 +000021enum HandlerTypes {
22 StartElement,
23 EndElement,
24 ProcessingInstruction,
25 CharacterData,
26 UnparsedEntityDecl,
27 NotationDecl,
28 StartNamespaceDecl,
29 EndNamespaceDecl,
30 Comment,
31 StartCdataSection,
32 EndCdataSection,
33 Default,
34 DefaultHandlerExpand,
35 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000036 ExternalEntityRef,
37 StartDoctypeDecl,
38 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000039 EntityDecl,
40 XmlDecl,
41 ElementDecl,
42 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000043#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000044 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000045#endif
Fred Drake85d835f2001-02-08 15:39:08 +000046 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000047};
48
49static PyObject *ErrorObject;
50
51/* ----------------------------------------------------- */
52
53/* Declarations for objects of type xmlparser */
54
55typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000056 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000057
Fred Drake0582df92000-07-12 04:49:00 +000058 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000059 int ordered_attributes; /* Return attributes as a list. */
60 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000061 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000062 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000063 XML_Char *buffer; /* Buffer used when accumulating characters */
64 /* NULL if not enabled */
65 int buffer_size; /* Size of buffer, in XML_Char units */
66 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000067 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000068 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000069} xmlparseobject;
70
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030071#include "clinic/pyexpat.c.h"
72
Fred Drake2a3d7db2002-06-28 22:56:48 +000073#define CHARACTER_DATA_BUFFER_SIZE 8192
74
Jeremy Hylton938ace62002-07-17 16:30:39 +000075static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000076
Fred Drake117ac852002-09-24 16:24:54 +000077typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000078typedef void* xmlhandler;
79
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000080struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000081 const char *name;
82 xmlhandlersetter setter;
83 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000084 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000085 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000086};
87
Jeremy Hylton938ace62002-07-17 16:30:39 +000088static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000089
Fred Drakebd6101c2001-02-14 18:29:45 +000090/* Set an integer attribute on the error object; return true on success,
91 * false on an exception.
92 */
93static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020094set_error_attr(PyObject *err, const char *name, int value)
Fred Drakebd6101c2001-02-14 18:29:45 +000095{
Christian Heimes217cfd12007-12-02 14:31:20 +000096 PyObject *v = PyLong_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +000097
Neal Norwitz2f5e9902006-03-08 06:36:45 +000098 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
99 Py_XDECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000100 return 0;
101 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000102 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000103 return 1;
104}
105
106/* Build and set an Expat exception, including positioning
107 * information. Always returns NULL.
108 */
Fred Drake85d835f2001-02-08 15:39:08 +0000109static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000110set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000111{
112 PyObject *err;
Victor Stinner499dfcf2011-03-21 13:26:24 +0100113 PyObject *buffer;
Fred Drake85d835f2001-02-08 15:39:08 +0000114 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000115 int lineno = XML_GetErrorLineNumber(parser);
116 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000117
Victor Stinner499dfcf2011-03-21 13:26:24 +0100118 buffer = PyUnicode_FromFormat("%s: line %i, column %i",
119 XML_ErrorString(code), lineno, column);
120 if (buffer == NULL)
121 return NULL;
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100122 err = PyObject_CallFunctionObjArgs(ErrorObject, buffer, NULL);
Victor Stinner499dfcf2011-03-21 13:26:24 +0100123 Py_DECREF(buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000124 if ( err != NULL
125 && set_error_attr(err, "code", code)
126 && set_error_attr(err, "offset", column)
127 && set_error_attr(err, "lineno", lineno)) {
128 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000129 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000130 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000131 return NULL;
132}
133
Fred Drake71b63ff2002-06-28 22:29:01 +0000134static int
135have_handler(xmlparseobject *self, int type)
136{
137 PyObject *handler = self->handlers[type];
138 return handler != NULL;
139}
140
141static PyObject *
142get_handler_name(struct HandlerInfo *hinfo)
143{
144 PyObject *name = hinfo->nameobj;
145 if (name == NULL) {
Neal Norwitz392c5be2007-08-25 17:20:32 +0000146 name = PyUnicode_FromString(hinfo->name);
Fred Drake71b63ff2002-06-28 22:29:01 +0000147 hinfo->nameobj = name;
148 }
149 Py_XINCREF(name);
150 return name;
151}
152
Fred Drake85d835f2001-02-08 15:39:08 +0000153
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000154/* Convert a string of XML_Chars into a Unicode string.
155 Returns None if str is a null pointer. */
156
Fred Drake0582df92000-07-12 04:49:00 +0000157static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000158conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000159{
Fred Drake71b63ff2002-06-28 22:29:01 +0000160 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000161 and hence in UTF-8. */
162 /* UTF-8 from Expat, Unicode desired */
163 if (str == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200164 Py_RETURN_NONE;
Fred Drake0582df92000-07-12 04:49:00 +0000165 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000166 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000167}
168
Fred Drake0582df92000-07-12 04:49:00 +0000169static PyObject *
170conv_string_len_to_unicode(const XML_Char *str, int len)
171{
Fred Drake71b63ff2002-06-28 22:29:01 +0000172 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000173 and hence in UTF-8. */
174 /* UTF-8 from Expat, Unicode desired */
175 if (str == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200176 Py_RETURN_NONE;
Fred Drake0582df92000-07-12 04:49:00 +0000177 }
Fred Drake6f987622000-08-25 18:03:30 +0000178 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000179}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000180
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000181/* Callback routines */
182
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000183static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000184
Martin v. Löwis069dde22003-01-21 10:58:18 +0000185/* This handler is used when an error has been detected, in the hope
186 that actual parsing can be terminated early. This will only help
187 if an external entity reference is encountered. */
188static int
189error_external_entity_ref_handler(XML_Parser parser,
190 const XML_Char *context,
191 const XML_Char *base,
192 const XML_Char *systemId,
193 const XML_Char *publicId)
194{
195 return 0;
196}
197
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000198/* Dummy character data handler used when an error (exception) has
199 been detected, and the actual parsing can be terminated early.
200 This is needed since character data handler can't be safely removed
201 from within the character data handler, but can be replaced. It is
202 used only from the character data handler trampoline, and must be
203 used right after `flag_error()` is called. */
204static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205noop_character_data_handler(void *userData, const XML_Char *data, int len)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000206{
207 /* Do nothing. */
208}
209
Fred Drake6f987622000-08-25 18:03:30 +0000210static void
211flag_error(xmlparseobject *self)
212{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000213 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000214 XML_SetExternalEntityRefHandler(self->itself,
215 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000216}
217
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000218static PyObject*
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200219call_with_frame(const char *funcname, int lineno, PyObject* func, PyObject* args,
Fred Drake39689c52004-08-13 03:12:57 +0000220 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000221{
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200222 PyObject *res;
Fred Drakebd6101c2001-02-14 18:29:45 +0000223
Fred Drakebd6101c2001-02-14 18:29:45 +0000224 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000225 if (res == NULL) {
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200226 _PyTraceback_Add(funcname, __FILE__, lineno);
Fred Drake39689c52004-08-13 03:12:57 +0000227 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000228 }
Fred Drakebd6101c2001-02-14 18:29:45 +0000229 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000230}
231
Fred Drakeb91a36b2002-06-27 19:40:48 +0000232static PyObject*
233string_intern(xmlparseobject *self, const char* str)
234{
Guido van Rossum4ca94712007-07-23 17:42:32 +0000235 PyObject *result = conv_string_to_unicode(str);
Fred Drakeb91a36b2002-06-27 19:40:48 +0000236 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000237 /* result can be NULL if the unicode conversion failed. */
238 if (!result)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000240 if (!self->intern)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000242 value = PyDict_GetItem(self->intern, result);
243 if (!value) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 if (PyDict_SetItem(self->intern, result, result) == 0)
Fred Drakeb91a36b2002-06-27 19:40:48 +0000245 return result;
246 else
247 return NULL;
248 }
249 Py_INCREF(value);
250 Py_DECREF(result);
251 return value;
252}
253
Fred Drake2a3d7db2002-06-28 22:56:48 +0000254/* Return 0 on success, -1 on exception.
255 * flag_error() will be called before return if needed.
256 */
257static int
258call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
259{
260 PyObject *args;
261 PyObject *temp;
262
Georg Brandlc01537f2010-10-15 16:26:08 +0000263 if (!have_handler(self, CharacterData))
264 return -1;
265
Fred Drake2a3d7db2002-06-28 22:56:48 +0000266 args = PyTuple_New(1);
267 if (args == NULL)
268 return -1;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000269 temp = (conv_string_len_to_unicode(buffer, len));
Fred Drake2a3d7db2002-06-28 22:56:48 +0000270 if (temp == NULL) {
271 Py_DECREF(args);
272 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000273 XML_SetCharacterDataHandler(self->itself,
274 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000275 return -1;
276 }
277 PyTuple_SET_ITEM(args, 0, temp);
278 /* temp is now a borrowed reference; consider it unused. */
279 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200280 temp = call_with_frame("CharacterData", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000281 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000282 /* temp is an owned reference again, or NULL */
283 self->in_callback = 0;
284 Py_DECREF(args);
285 if (temp == NULL) {
286 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287 XML_SetCharacterDataHandler(self->itself,
288 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000289 return -1;
290 }
291 Py_DECREF(temp);
292 return 0;
293}
294
295static int
296flush_character_buffer(xmlparseobject *self)
297{
298 int rc;
299 if (self->buffer == NULL || self->buffer_used == 0)
300 return 0;
301 rc = call_character_handler(self, self->buffer, self->buffer_used);
302 self->buffer_used = 0;
303 return rc;
304}
305
306static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
Fred Drake2a3d7db2002-06-28 22:56:48 +0000308{
309 xmlparseobject *self = (xmlparseobject *) userData;
Victor Stinner9e09c262013-07-18 23:17:01 +0200310
311 if (PyErr_Occurred())
312 return;
313
Fred Drake2a3d7db2002-06-28 22:56:48 +0000314 if (self->buffer == NULL)
315 call_character_handler(self, data, len);
316 else {
317 if ((self->buffer_used + len) > self->buffer_size) {
318 if (flush_character_buffer(self) < 0)
319 return;
320 /* handler might have changed; drop the rest on the floor
321 * if there isn't a handler anymore
322 */
323 if (!have_handler(self, CharacterData))
324 return;
325 }
326 if (len > self->buffer_size) {
327 call_character_handler(self, data, len);
328 self->buffer_used = 0;
329 }
330 else {
331 memcpy(self->buffer + self->buffer_used,
332 data, len * sizeof(XML_Char));
333 self->buffer_used += len;
334 }
335 }
336}
337
Fred Drake85d835f2001-02-08 15:39:08 +0000338static void
339my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000340 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000341{
342 xmlparseobject *self = (xmlparseobject *)userData;
343
Fred Drake71b63ff2002-06-28 22:29:01 +0000344 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000345 PyObject *container, *rv, *args;
346 int i, max;
347
Victor Stinner9e09c262013-07-18 23:17:01 +0200348 if (PyErr_Occurred())
349 return;
350
Fred Drake2a3d7db2002-06-28 22:56:48 +0000351 if (flush_character_buffer(self) < 0)
352 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000353 /* Set max to the number of slots filled in atts[]; max/2 is
354 * the number of attributes we need to process.
355 */
356 if (self->specified_attributes) {
357 max = XML_GetSpecifiedAttributeCount(self->itself);
358 }
359 else {
360 max = 0;
361 while (atts[max] != NULL)
362 max += 2;
363 }
364 /* Build the container. */
365 if (self->ordered_attributes)
366 container = PyList_New(max);
367 else
368 container = PyDict_New();
369 if (container == NULL) {
370 flag_error(self);
371 return;
372 }
373 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000374 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000375 PyObject *v;
376 if (n == NULL) {
377 flag_error(self);
378 Py_DECREF(container);
379 return;
380 }
Guido van Rossum4ca94712007-07-23 17:42:32 +0000381 v = conv_string_to_unicode((XML_Char *) atts[i+1]);
Fred Drake85d835f2001-02-08 15:39:08 +0000382 if (v == NULL) {
383 flag_error(self);
384 Py_DECREF(container);
385 Py_DECREF(n);
386 return;
387 }
388 if (self->ordered_attributes) {
389 PyList_SET_ITEM(container, i, n);
390 PyList_SET_ITEM(container, i+1, v);
391 }
392 else if (PyDict_SetItem(container, n, v)) {
393 flag_error(self);
394 Py_DECREF(n);
395 Py_DECREF(v);
396 return;
397 }
398 else {
399 Py_DECREF(n);
400 Py_DECREF(v);
401 }
402 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000403 args = string_intern(self, name);
404 if (args != NULL)
405 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000406 if (args == NULL) {
407 Py_DECREF(container);
408 return;
409 }
410 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000411 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200412 rv = call_with_frame("StartElement", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000413 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000414 self->in_callback = 0;
415 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000416 if (rv == NULL) {
417 flag_error(self);
418 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000419 }
Fred Drake85d835f2001-02-08 15:39:08 +0000420 Py_DECREF(rv);
421 }
422}
423
424#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
425 RETURN, GETUSERDATA) \
426static RC \
427my_##NAME##Handler PARAMS {\
428 xmlparseobject *self = GETUSERDATA ; \
429 PyObject *args = NULL; \
430 PyObject *rv = NULL; \
431 INIT \
432\
Fred Drake71b63ff2002-06-28 22:29:01 +0000433 if (have_handler(self, NAME)) { \
Victor Stinner9e09c262013-07-18 23:17:01 +0200434 if (PyErr_Occurred()) \
435 return RETURN; \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000436 if (flush_character_buffer(self) < 0) \
437 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000438 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000439 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000440 self->in_callback = 1; \
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200441 rv = call_with_frame(#NAME,__LINE__, \
Fred Drake39689c52004-08-13 03:12:57 +0000442 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000443 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000444 Py_DECREF(args); \
445 if (rv == NULL) { \
446 flag_error(self); \
447 return RETURN; \
448 } \
449 CONVERSION \
450 Py_DECREF(rv); \
451 } \
452 return RETURN; \
453}
454
Fred Drake6f987622000-08-25 18:03:30 +0000455#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
457 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000458
Fred Drake6f987622000-08-25 18:03:30 +0000459#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
461 rc = PyLong_AsLong(rv);, rc, \
462 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000463
Fred Drake71b63ff2002-06-28 22:29:01 +0000464VOID_HANDLER(EndElement,
465 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000466 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000467
Fred Drake6f987622000-08-25 18:03:30 +0000468VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000469 (void *userData,
470 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000471 const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000472 ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000473
Fred Drake6f987622000-08-25 18:03:30 +0000474VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000475 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000476 const XML_Char *entityName,
477 const XML_Char *base,
478 const XML_Char *systemId,
479 const XML_Char *publicId,
480 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000481 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000482 string_intern(self, entityName), string_intern(self, base),
483 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000484 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000485
Fred Drake85d835f2001-02-08 15:39:08 +0000486VOID_HANDLER(EntityDecl,
487 (void *userData,
488 const XML_Char *entityName,
489 int is_parameter_entity,
490 const XML_Char *value,
491 int value_length,
492 const XML_Char *base,
493 const XML_Char *systemId,
494 const XML_Char *publicId,
495 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000496 ("NiNNNNN",
497 string_intern(self, entityName), is_parameter_entity,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000498 (conv_string_len_to_unicode(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000499 string_intern(self, base), string_intern(self, systemId),
500 string_intern(self, publicId),
501 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000502
503VOID_HANDLER(XmlDecl,
504 (void *userData,
505 const XML_Char *version,
506 const XML_Char *encoding,
507 int standalone),
508 ("(O&O&i)",
Guido van Rossum4ca94712007-07-23 17:42:32 +0000509 conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000510 standalone))
511
512static PyObject *
513conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000514 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000515{
516 PyObject *result = NULL;
517 PyObject *children = PyTuple_New(model->numchildren);
518 int i;
519
520 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000521 assert(model->numchildren < INT_MAX);
522 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000523 PyObject *child = conv_content_model(&model->children[i],
524 conv_string);
525 if (child == NULL) {
526 Py_XDECREF(children);
527 return NULL;
528 }
529 PyTuple_SET_ITEM(children, i, child);
530 }
531 result = Py_BuildValue("(iiO&N)",
532 model->type, model->quant,
533 conv_string,model->name, children);
534 }
535 return result;
536}
537
Fred Drake06dd8cf2003-02-02 03:54:17 +0000538static void
539my_ElementDeclHandler(void *userData,
540 const XML_Char *name,
541 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000542{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000543 xmlparseobject *self = (xmlparseobject *)userData;
544 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000545
Fred Drake06dd8cf2003-02-02 03:54:17 +0000546 if (have_handler(self, ElementDecl)) {
547 PyObject *rv = NULL;
548 PyObject *modelobj, *nameobj;
549
Victor Stinner9e09c262013-07-18 23:17:01 +0200550 if (PyErr_Occurred())
551 return;
552
Fred Drake06dd8cf2003-02-02 03:54:17 +0000553 if (flush_character_buffer(self) < 0)
554 goto finally;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000555 modelobj = conv_content_model(model, (conv_string_to_unicode));
Fred Drake06dd8cf2003-02-02 03:54:17 +0000556 if (modelobj == NULL) {
557 flag_error(self);
558 goto finally;
559 }
560 nameobj = string_intern(self, name);
561 if (nameobj == NULL) {
562 Py_DECREF(modelobj);
563 flag_error(self);
564 goto finally;
565 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000566 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000567 if (args == NULL) {
568 Py_DECREF(modelobj);
569 flag_error(self);
570 goto finally;
571 }
572 self->in_callback = 1;
Antoine Pitrou0ddbf472014-10-08 20:00:09 +0200573 rv = call_with_frame("ElementDecl", __LINE__,
Fred Drake39689c52004-08-13 03:12:57 +0000574 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000575 self->in_callback = 0;
576 if (rv == NULL) {
577 flag_error(self);
578 goto finally;
579 }
580 Py_DECREF(rv);
581 }
582 finally:
583 Py_XDECREF(args);
584 XML_FreeContentModel(self->itself, model);
585 return;
586}
Fred Drake85d835f2001-02-08 15:39:08 +0000587
588VOID_HANDLER(AttlistDecl,
589 (void *userData,
590 const XML_Char *elname,
591 const XML_Char *attname,
592 const XML_Char *att_type,
593 const XML_Char *dflt,
594 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000595 ("(NNO&O&i)",
596 string_intern(self, elname), string_intern(self, attname),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000597 conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
Fred Drake85d835f2001-02-08 15:39:08 +0000598 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000599
Martin v. Löwisc847f402003-01-21 11:09:21 +0000600#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000601VOID_HANDLER(SkippedEntity,
602 (void *userData,
603 const XML_Char *entityName,
604 int is_parameter_entity),
605 ("Ni",
606 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000607#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000608
Fred Drake71b63ff2002-06-28 22:29:01 +0000609VOID_HANDLER(NotationDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 (void *userData,
611 const XML_Char *notationName,
612 const XML_Char *base,
613 const XML_Char *systemId,
614 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000615 ("(NNNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 string_intern(self, notationName), string_intern(self, base),
617 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000618
Fred Drake6f987622000-08-25 18:03:30 +0000619VOID_HANDLER(StartNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 (void *userData,
621 const XML_Char *prefix,
622 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000623 ("(NN)",
624 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000625
Fred Drake6f987622000-08-25 18:03:30 +0000626VOID_HANDLER(EndNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 (void *userData,
628 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000629 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000630
Fred Drake6f987622000-08-25 18:03:30 +0000631VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000632 (void *userData, const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000633 ("(O&)", conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000634
Fred Drake6f987622000-08-25 18:03:30 +0000635VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000636 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000638
Fred Drake6f987622000-08-25 18:03:30 +0000639VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000640 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000642
Fred Drake6f987622000-08-25 18:03:30 +0000643VOID_HANDLER(Default,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 (void *userData, const XML_Char *s, int len),
645 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000646
Fred Drake6f987622000-08-25 18:03:30 +0000647VOID_HANDLER(DefaultHandlerExpand,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 (void *userData, const XML_Char *s, int len),
649 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000650
Fred Drake71b63ff2002-06-28 22:29:01 +0000651INT_HANDLER(NotStandalone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 (void *userData),
653 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000654
Fred Drake6f987622000-08-25 18:03:30 +0000655RC_HANDLER(int, ExternalEntityRef,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 (XML_Parser parser,
657 const XML_Char *context,
658 const XML_Char *base,
659 const XML_Char *systemId,
660 const XML_Char *publicId),
661 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000662 ("(O&NNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 conv_string_to_unicode ,context, string_intern(self, base),
664 string_intern(self, systemId), string_intern(self, publicId)),
665 rc = PyLong_AsLong(rv);, rc,
666 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000667
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000668/* XXX UnknownEncodingHandler */
669
Fred Drake85d835f2001-02-08 15:39:08 +0000670VOID_HANDLER(StartDoctypeDecl,
671 (void *userData, const XML_Char *doctypeName,
672 const XML_Char *sysid, const XML_Char *pubid,
673 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000674 ("(NNNi)", string_intern(self, doctypeName),
675 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000676 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000677
678VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000679
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000680/* ---------------------------------------------------------------- */
Brett Cannond0aeda82014-08-22 14:23:20 -0400681/*[clinic input]
682class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype"
683[clinic start generated code]*/
684/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2393162385232e1c]*/
685
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000686
Fred Drake71b63ff2002-06-28 22:29:01 +0000687static PyObject *
688get_parse_result(xmlparseobject *self, int rv)
689{
690 if (PyErr_Occurred()) {
691 return NULL;
692 }
693 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000694 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000695 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000696 if (flush_character_buffer(self) < 0) {
697 return NULL;
698 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000699 return PyLong_FromLong(rv);
Fred Drake71b63ff2002-06-28 22:29:01 +0000700}
701
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200702#define MAX_CHUNK_SIZE (1 << 20)
703
Brett Cannond0aeda82014-08-22 14:23:20 -0400704/*[clinic input]
705pyexpat.xmlparser.Parse
706
707 data: object
Serhiy Storchaka8b2e8b62015-05-30 11:30:39 +0300708 isfinal: int(c_default="0") = False
Brett Cannond0aeda82014-08-22 14:23:20 -0400709 /
710
711Parse XML data.
712
713`isfinal' should be true at end of input.
714[clinic start generated code]*/
715
Brett Cannond0aeda82014-08-22 14:23:20 -0400716static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400717pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data,
Serhiy Storchaka8b2e8b62015-05-30 11:30:39 +0300718 int isfinal)
719/*[clinic end generated code: output=f4db843dd1f4ed4b input=199d9e8e92ebbb4b]*/
Brett Cannond0aeda82014-08-22 14:23:20 -0400720{
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200721 const char *s;
722 Py_ssize_t slen;
723 Py_buffer view;
724 int rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000725
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200726 if (PyUnicode_Check(data)) {
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200727 view.buf = NULL;
Serhiy Storchaka36b365c2013-02-04 18:28:01 +0200728 s = PyUnicode_AsUTF8AndSize(data, &slen);
729 if (s == NULL)
730 return NULL;
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200731 /* Explicitly set UTF-8 encoding. Return code ignored. */
732 (void)XML_SetEncoding(self->itself, "utf-8");
733 }
734 else {
735 if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
736 return NULL;
737 s = view.buf;
738 slen = view.len;
739 }
740
741 while (slen > MAX_CHUNK_SIZE) {
742 rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0);
743 if (!rc)
744 goto done;
745 s += MAX_CHUNK_SIZE;
746 slen -= MAX_CHUNK_SIZE;
747 }
Serhiy Storchakafad85aa2015-11-07 15:42:38 +0200748 Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX);
749 assert(slen <= INT_MAX);
Serhiy Storchaka8b2e8b62015-05-30 11:30:39 +0300750 rc = XML_Parse(self->itself, s, (int)slen, isfinal);
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200751
752done:
753 if (view.buf != NULL)
754 PyBuffer_Release(&view);
755 return get_parse_result(self, rc);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000756}
757
Fred Drakeca1f4262000-09-21 20:10:23 +0000758/* File reading copied from cPickle */
759
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000760#define BUF_SIZE 2048
761
Fred Drake0582df92000-07-12 04:49:00 +0000762static int
763readinst(char *buf, int buf_size, PyObject *meth)
764{
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000765 PyObject *str;
766 Py_ssize_t len;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200767 const char *ptr;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000768
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000769 str = PyObject_CallFunction(meth, "n", buf_size);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000770 if (str == NULL)
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000771 goto error;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000772
Christian Heimes72b710a2008-05-26 13:28:38 +0000773 if (PyBytes_Check(str))
774 ptr = PyBytes_AS_STRING(str);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000775 else if (PyByteArray_Check(str))
776 ptr = PyByteArray_AS_STRING(str);
Guido van Rossum98297ee2007-11-06 21:34:58 +0000777 else {
Fred Drake71b63ff2002-06-28 22:29:01 +0000778 PyErr_Format(PyExc_TypeError,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000779 "read() did not return a bytes object (type=%.400s)",
Christian Heimes90aa7642007-12-19 02:45:37 +0000780 Py_TYPE(str)->tp_name);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000781 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000782 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000783 len = Py_SIZE(str);
Fred Drake0582df92000-07-12 04:49:00 +0000784 if (len > buf_size) {
785 PyErr_Format(PyExc_ValueError,
786 "read() returned too much data: "
Victor Stinner9d6f9362011-01-04 22:00:04 +0000787 "%i bytes requested, %zd returned",
Fred Drake0582df92000-07-12 04:49:00 +0000788 buf_size, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000789 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000790 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000791 memcpy(buf, ptr, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000792 Py_DECREF(str);
793 /* len <= buf_size <= INT_MAX */
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000794 return (int)len;
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000795
796error:
797 Py_XDECREF(str);
798 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000799}
800
Brett Cannond0aeda82014-08-22 14:23:20 -0400801/*[clinic input]
802pyexpat.xmlparser.ParseFile
803
804 file: object
805 /
806
807Parse XML data from file-like object.
808[clinic start generated code]*/
809
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000810static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -0400811pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300812/*[clinic end generated code: output=2adc6a13100cc42b input=fbb5a12b6038d735]*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000813{
Fred Drake0582df92000-07-12 04:49:00 +0000814 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000815 PyObject *readmethod = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200816 _Py_IDENTIFIER(read);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000817
Brett Cannond0aeda82014-08-22 14:23:20 -0400818 readmethod = _PyObject_GetAttrId(file, &PyId_read);
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000819 if (readmethod == NULL) {
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000820 PyErr_SetString(PyExc_TypeError,
821 "argument must have 'read' attribute");
822 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000823 }
824 for (;;) {
825 int bytes_read;
826 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000827 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000828 Py_XDECREF(readmethod);
Ned Deilye7d532f2014-03-27 16:39:58 -0700829 return get_parse_result(self, 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000830 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000831
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000832 bytes_read = readinst(buf, BUF_SIZE, readmethod);
833 if (bytes_read < 0) {
834 Py_DECREF(readmethod);
835 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000836 }
837 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000838 if (PyErr_Occurred()) {
839 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000840 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000841 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000842
Fred Drake0582df92000-07-12 04:49:00 +0000843 if (!rv || bytes_read == 0)
844 break;
845 }
Fred Drake7b6caff2003-07-21 17:05:56 +0000846 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +0000847 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000848}
849
Brett Cannond0aeda82014-08-22 14:23:20 -0400850/*[clinic input]
851pyexpat.xmlparser.SetBase
852
853 base: str
854 /
855
856Set the base URL for the parser.
857[clinic start generated code]*/
858
Brett Cannond0aeda82014-08-22 14:23:20 -0400859static PyObject *
860pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300861/*[clinic end generated code: output=c212ddceb607b539 input=c684e5de895ee1a8]*/
Brett Cannond0aeda82014-08-22 14:23:20 -0400862{
Fred Drake0582df92000-07-12 04:49:00 +0000863 if (!XML_SetBase(self->itself, base)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000865 }
Brett Cannond0aeda82014-08-22 14:23:20 -0400866 Py_RETURN_NONE;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000867}
868
Brett Cannond0aeda82014-08-22 14:23:20 -0400869/*[clinic input]
870pyexpat.xmlparser.GetBase
871
872Return base URL string for the parser.
873[clinic start generated code]*/
874
Brett Cannond0aeda82014-08-22 14:23:20 -0400875static PyObject *
876pyexpat_xmlparser_GetBase_impl(xmlparseobject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300877/*[clinic end generated code: output=2886cb21f9a8739a input=918d71c38009620e]*/
Fred Drake0582df92000-07-12 04:49:00 +0000878{
Fred Drake0582df92000-07-12 04:49:00 +0000879 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880}
881
Brett Cannond0aeda82014-08-22 14:23:20 -0400882/*[clinic input]
883pyexpat.xmlparser.GetInputContext
884
885Return the untranslated text of the input that caused the current event.
886
887If the event was generated by a large amount of text (such as a start tag
888for an element with many attributes), not all of the text may be available.
889[clinic start generated code]*/
890
Brett Cannond0aeda82014-08-22 14:23:20 -0400891static PyObject *
892pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300893/*[clinic end generated code: output=a88026d683fc22cc input=034df8712db68379]*/
Fred Drakebd6101c2001-02-14 18:29:45 +0000894{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000895 if (self->in_callback) {
896 int offset, size;
897 const char *buffer
898 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +0000899
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000900 if (buffer != NULL)
Christian Heimes72b710a2008-05-26 13:28:38 +0000901 return PyBytes_FromStringAndSize(buffer + offset,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000902 size - offset);
903 else
904 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000905 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000906 else
907 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +0000908}
Fred Drakebd6101c2001-02-14 18:29:45 +0000909
Brett Cannond0aeda82014-08-22 14:23:20 -0400910/*[clinic input]
911pyexpat.xmlparser.ExternalEntityParserCreate
912
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700913 context: str(accept={str, NoneType})
Brett Cannond0aeda82014-08-22 14:23:20 -0400914 encoding: str = NULL
915 /
916
917Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler.
918[clinic start generated code]*/
919
Brett Cannond0aeda82014-08-22 14:23:20 -0400920static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400921pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self,
922 const char *context,
923 const char *encoding)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700924/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/
Brett Cannond0aeda82014-08-22 14:23:20 -0400925{
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000926 xmlparseobject *new_parser;
927 int i;
928
Martin v. Löwis894258c2001-09-23 10:20:10 +0000929 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake85d835f2001-02-08 15:39:08 +0000930 if (new_parser == NULL)
931 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +0000932 new_parser->buffer_size = self->buffer_size;
933 new_parser->buffer_used = 0;
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000934 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000935 new_parser->ordered_attributes = self->ordered_attributes;
936 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +0000937 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +0000938 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000939 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000941 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000942 new_parser->intern = self->intern;
943 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +0000944 PyObject_GC_Track(new_parser);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000945
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000946 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +0200947 new_parser->buffer = PyMem_Malloc(new_parser->buffer_size);
Victor Stinnerb4ba9862010-09-10 22:25:19 +0000948 if (new_parser->buffer == NULL) {
949 Py_DECREF(new_parser);
950 return PyErr_NoMemory();
951 }
952 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000953 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +0000954 Py_DECREF(new_parser);
955 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000956 }
957
958 XML_SetUserData(new_parser->itself, (void *)new_parser);
959
960 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +0000961 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +0000962 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000963
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200964 new_parser->handlers = PyMem_New(PyObject *, i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000965 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +0000966 Py_DECREF(new_parser);
967 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000968 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000969 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000970
971 /* then copy handlers from self */
972 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000973 PyObject *handler = self->handlers[i];
974 if (handler != NULL) {
975 Py_INCREF(handler);
976 new_parser->handlers[i] = handler;
977 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +0000978 handler_info[i].handler);
979 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000980 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000981 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +0000982}
983
Brett Cannond0aeda82014-08-22 14:23:20 -0400984/*[clinic input]
985pyexpat.xmlparser.SetParamEntityParsing
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000986
Brett Cannond0aeda82014-08-22 14:23:20 -0400987 flag: int
988 /
989
990Controls parsing of parameter entities (including the external DTD subset).
991
992Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,
993XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and
994XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag
995was successful.
996[clinic start generated code]*/
997
Brett Cannond0aeda82014-08-22 14:23:20 -0400998static PyObject *
999pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001000/*[clinic end generated code: output=18668ee8e760d64c input=8aea19b4b15e9af1]*/
Brett Cannond0aeda82014-08-22 14:23:20 -04001001{
1002 flag = XML_SetParamEntityParsing(self->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +00001003 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001004}
1005
Martin v. Löwisc847f402003-01-21 11:09:21 +00001006
1007#if XML_COMBINED_VERSION >= 19505
Brett Cannond0aeda82014-08-22 14:23:20 -04001008/*[clinic input]
1009pyexpat.xmlparser.UseForeignDTD
1010
1011 flag: bool = True
1012 /
1013
1014Allows the application to provide an artificial external subset if one is not specified as part of the document instance.
1015
1016This readily allows the use of a 'default' document type controlled by the
1017application, while still getting the advantage of providing document type
1018information to the parser. 'flag' defaults to True if not provided.
1019[clinic start generated code]*/
1020
Brett Cannond0aeda82014-08-22 14:23:20 -04001021static PyObject *
1022pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001023/*[clinic end generated code: output=cfaa9aa50bb0f65c input=78144c519d116a6e]*/
Brett Cannond0aeda82014-08-22 14:23:20 -04001024{
Martin v. Löwis069dde22003-01-21 10:58:18 +00001025 enum XML_Error rc;
Brett Cannond0aeda82014-08-22 14:23:20 -04001026
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001027 rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);
Martin v. Löwis069dde22003-01-21 10:58:18 +00001028 if (rc != XML_ERROR_NONE) {
1029 return set_error(self, rc);
1030 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001031 Py_RETURN_NONE;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001032}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001033#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001034
Brett Cannond0aeda82014-08-22 14:23:20 -04001035/*[clinic input]
1036pyexpat.xmlparser.__dir__
1037[clinic start generated code]*/
1038
Brett Cannond0aeda82014-08-22 14:23:20 -04001039static PyObject *
1040pyexpat_xmlparser___dir___impl(xmlparseobject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001041/*[clinic end generated code: output=bc22451efb9e4d17 input=76aa455f2a661384]*/
Brett Cannond0aeda82014-08-22 14:23:20 -04001042{
1043#define APPEND(list, str) \
1044 do { \
1045 PyObject *o = PyUnicode_FromString(str); \
1046 if (o != NULL) \
1047 PyList_Append(list, o); \
1048 Py_XDECREF(o); \
1049 } while (0)
1050
1051 int i;
1052 PyObject *rc = PyList_New(0);
1053 if (!rc)
1054 return NULL;
1055 for (i = 0; handler_info[i].name != NULL; i++) {
1056 PyObject *o = get_handler_name(&handler_info[i]);
1057 if (o != NULL)
1058 PyList_Append(rc, o);
1059 Py_XDECREF(o);
1060 }
1061 APPEND(rc, "ErrorCode");
1062 APPEND(rc, "ErrorLineNumber");
1063 APPEND(rc, "ErrorColumnNumber");
1064 APPEND(rc, "ErrorByteIndex");
1065 APPEND(rc, "CurrentLineNumber");
1066 APPEND(rc, "CurrentColumnNumber");
1067 APPEND(rc, "CurrentByteIndex");
1068 APPEND(rc, "buffer_size");
1069 APPEND(rc, "buffer_text");
1070 APPEND(rc, "buffer_used");
1071 APPEND(rc, "namespace_prefixes");
1072 APPEND(rc, "ordered_attributes");
1073 APPEND(rc, "specified_attributes");
1074 APPEND(rc, "intern");
1075
1076#undef APPEND
1077
1078 if (PyErr_Occurred()) {
1079 Py_DECREF(rc);
1080 rc = NULL;
1081 }
1082
1083 return rc;
1084}
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001085
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001086static struct PyMethodDef xmlparse_methods[] = {
Brett Cannond0aeda82014-08-22 14:23:20 -04001087 PYEXPAT_XMLPARSER_PARSE_METHODDEF
1088 PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF
1089 PYEXPAT_XMLPARSER_SETBASE_METHODDEF
1090 PYEXPAT_XMLPARSER_GETBASE_METHODDEF
1091 PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF
1092 PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF
1093 PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF
Martin v. Löwisc847f402003-01-21 11:09:21 +00001094#if XML_COMBINED_VERSION >= 19505
Brett Cannond0aeda82014-08-22 14:23:20 -04001095 PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
Martin v. Löwisc847f402003-01-21 11:09:21 +00001096#endif
Brett Cannond0aeda82014-08-22 14:23:20 -04001097 PYEXPAT_XMLPARSER___DIR___METHODDEF
1098 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001099};
1100
1101/* ---------- */
1102
1103
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001104
Fred Drake71b63ff2002-06-28 22:29:01 +00001105/* pyexpat international encoding support.
1106 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001107*/
1108
Fred Drake71b63ff2002-06-28 22:29:01 +00001109static int
1110PyUnknownEncodingHandler(void *encodingHandlerData,
1111 const XML_Char *name,
1112 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001113{
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001114 static unsigned char template_buffer[256] = {0};
1115 PyObject* u;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001116 int i;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001117 void *data;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001118 unsigned int kind;
Fred Drake71b63ff2002-06-28 22:29:01 +00001119
Victor Stinner9e09c262013-07-18 23:17:01 +02001120 if (PyErr_Occurred())
1121 return XML_STATUS_ERROR;
1122
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001123 if (template_buffer[1] == 0) {
1124 for (i = 0; i < 256; i++)
1125 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001126 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001127
1128 u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace");
Christian Heimesb5821552013-06-29 20:43:13 +02001129 if (u == NULL || PyUnicode_READY(u)) {
Christian Heimes72172422013-06-29 21:49:27 +02001130 Py_XDECREF(u);
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001131 return XML_STATUS_ERROR;
Christian Heimesb5821552013-06-29 20:43:13 +02001132 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001133
1134 if (PyUnicode_GET_LENGTH(u) != 256) {
1135 Py_DECREF(u);
1136 PyErr_SetString(PyExc_ValueError,
1137 "multi-byte encodings are not supported");
1138 return XML_STATUS_ERROR;
1139 }
1140
1141 kind = PyUnicode_KIND(u);
1142 data = PyUnicode_DATA(u);
1143 for (i = 0; i < 256; i++) {
1144 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
1145 if (ch != Py_UNICODE_REPLACEMENT_CHARACTER)
1146 info->map[i] = ch;
1147 else
1148 info->map[i] = -1;
1149 }
1150
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001151 info->data = NULL;
1152 info->convert = NULL;
1153 info->release = NULL;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001154 Py_DECREF(u);
1155
1156 return XML_STATUS_OK;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001157}
1158
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001159
1160static PyObject *
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001161newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001162{
1163 int i;
1164 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001165
Martin v. Löwis894258c2001-09-23 10:20:10 +00001166 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake0582df92000-07-12 04:49:00 +00001167 if (self == NULL)
1168 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001169
Fred Drake2a3d7db2002-06-28 22:56:48 +00001170 self->buffer = NULL;
1171 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1172 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001173 self->ordered_attributes = 0;
1174 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001175 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001176 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001177 self->handlers = NULL;
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001178 self->intern = intern;
1179 Py_XINCREF(self->intern);
1180 PyObject_GC_Track(self);
1181
Christian Heimesfa535f52013-07-07 17:35:11 +02001182 /* namespace_separator is either NULL or contains one char + \0 */
1183 self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler,
1184 namespace_separator);
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001185 if (self->itself == NULL) {
1186 PyErr_SetString(PyExc_RuntimeError,
1187 "XML_ParserCreate failed");
1188 Py_DECREF(self);
1189 return NULL;
1190 }
Serhiy Storchaka22e707f2017-03-09 09:47:52 +02001191#if XML_COMBINED_VERSION >= 20100 || defined(XML_HAS_SET_HASH_SALT)
Gregory P. Smith25227712012-03-14 18:10:37 -07001192 /* This feature was added upstream in libexpat 2.1.0. Our expat copy
1193 * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
1194 * to indicate that we can still use it. */
Gregory P. Smith8e91cf62012-03-14 14:26:55 -07001195 XML_SetHashSalt(self->itself,
Christian Heimes985ecdc2013-11-20 11:46:18 +01001196 (unsigned long)_Py_HashSecret.expat.hashsalt);
Gregory P. Smith25227712012-03-14 18:10:37 -07001197#endif
Fred Drake0582df92000-07-12 04:49:00 +00001198 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001199 XML_SetUnknownEncodingHandler(self->itself,
1200 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001201
Fred Drake2a3d7db2002-06-28 22:56:48 +00001202 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001203 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001204
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001205 self->handlers = PyMem_New(PyObject *, i);
Fred Drake7c75bf22002-07-01 14:02:31 +00001206 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001207 Py_DECREF(self);
1208 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001209 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001210 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001211
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001212 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001213}
1214
1215
1216static void
Fred Drake0582df92000-07-12 04:49:00 +00001217xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001218{
Fred Drake0582df92000-07-12 04:49:00 +00001219 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001220 PyObject_GC_UnTrack(self);
Fred Drake85d835f2001-02-08 15:39:08 +00001221 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001222 XML_ParserFree(self->itself);
1223 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001224
Fred Drake85d835f2001-02-08 15:39:08 +00001225 if (self->handlers != NULL) {
Serhiy Storchaka1ed017a2015-12-27 15:51:32 +02001226 for (i = 0; handler_info[i].name != NULL; i++)
1227 Py_CLEAR(self->handlers[i]);
Victor Stinnerb6404912013-07-07 16:21:41 +02001228 PyMem_Free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001229 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001230 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001231 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001232 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001233 self->buffer = NULL;
1234 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001235 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001236 PyObject_GC_Del(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001237}
1238
Fred Drake0582df92000-07-12 04:49:00 +00001239static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001240handlername2int(PyObject *name)
Fred Drake0582df92000-07-12 04:49:00 +00001241{
1242 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001243 for (i = 0; handler_info[i].name != NULL; i++) {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001244 if (_PyUnicode_EqualToASCIIString(name, handler_info[i].name)) {
Fred Drake0582df92000-07-12 04:49:00 +00001245 return i;
1246 }
1247 }
1248 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001249}
1250
1251static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001252get_pybool(int istrue)
1253{
1254 PyObject *result = istrue ? Py_True : Py_False;
1255 Py_INCREF(result);
1256 return result;
1257}
1258
1259static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001260xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001261{
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001262 Py_UCS4 first_char;
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001263 int handlernum = -1;
1264
Alexander Belopolskye239d232010-12-08 23:31:48 +00001265 if (!PyUnicode_Check(nameobj))
1266 goto generic;
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001267 if (PyUnicode_READY(nameobj))
1268 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269
Alexander Belopolskye239d232010-12-08 23:31:48 +00001270 handlernum = handlername2int(nameobj);
Fred Drake71b63ff2002-06-28 22:29:01 +00001271
1272 if (handlernum != -1) {
1273 PyObject *result = self->handlers[handlernum];
1274 if (result == NULL)
1275 result = Py_None;
1276 Py_INCREF(result);
1277 return result;
1278 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001279
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001280 first_char = PyUnicode_READ_CHAR(nameobj, 0);
1281 if (first_char == 'E') {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001282 if (_PyUnicode_EqualToASCIIString(nameobj, "ErrorCode"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001283 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001284 XML_GetErrorCode(self->itself));
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001285 if (_PyUnicode_EqualToASCIIString(nameobj, "ErrorLineNumber"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001286 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001287 XML_GetErrorLineNumber(self->itself));
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001288 if (_PyUnicode_EqualToASCIIString(nameobj, "ErrorColumnNumber"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001289 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001290 XML_GetErrorColumnNumber(self->itself));
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001291 if (_PyUnicode_EqualToASCIIString(nameobj, "ErrorByteIndex"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001292 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001293 XML_GetErrorByteIndex(self->itself));
1294 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001295 if (first_char == 'C') {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001296 if (_PyUnicode_EqualToASCIIString(nameobj, "CurrentLineNumber"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001297 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001298 XML_GetCurrentLineNumber(self->itself));
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001299 if (_PyUnicode_EqualToASCIIString(nameobj, "CurrentColumnNumber"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001300 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001301 XML_GetCurrentColumnNumber(self->itself));
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001302 if (_PyUnicode_EqualToASCIIString(nameobj, "CurrentByteIndex"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001303 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001304 XML_GetCurrentByteIndex(self->itself));
1305 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001306 if (first_char == 'b') {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001307 if (_PyUnicode_EqualToASCIIString(nameobj, "buffer_size"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001308 return PyLong_FromLong((long) self->buffer_size);
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001309 if (_PyUnicode_EqualToASCIIString(nameobj, "buffer_text"))
Fred Drake2a3d7db2002-06-28 22:56:48 +00001310 return get_pybool(self->buffer != NULL);
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001311 if (_PyUnicode_EqualToASCIIString(nameobj, "buffer_used"))
Christian Heimes217cfd12007-12-02 14:31:20 +00001312 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001313 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001314 if (_PyUnicode_EqualToASCIIString(nameobj, "namespace_prefixes"))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001315 return get_pybool(self->ns_prefixes);
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001316 if (_PyUnicode_EqualToASCIIString(nameobj, "ordered_attributes"))
Fred Drake71b63ff2002-06-28 22:29:01 +00001317 return get_pybool(self->ordered_attributes);
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001318 if (_PyUnicode_EqualToASCIIString(nameobj, "specified_attributes"))
Fred Drake71b63ff2002-06-28 22:29:01 +00001319 return get_pybool((long) self->specified_attributes);
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001320 if (_PyUnicode_EqualToASCIIString(nameobj, "intern")) {
Fred Drakeb91a36b2002-06-27 19:40:48 +00001321 if (self->intern == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001322 Py_RETURN_NONE;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001323 }
1324 else {
1325 Py_INCREF(self->intern);
1326 return self->intern;
1327 }
1328 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001329 generic:
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001330 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001331}
1332
Fred Drake6f987622000-08-25 18:03:30 +00001333static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001334sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001335{
1336 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001337 if (handlernum >= 0) {
1338 xmlhandler c_handler = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001339
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001340 if (v == Py_None) {
1341 /* If this is the character data handler, and a character
1342 data handler is already active, we need to be more
1343 careful. What we can safely do is replace the existing
1344 character data handler callback function with a no-op
1345 function that will refuse to call Python. The downside
1346 is that this doesn't completely remove the character
1347 data handler from the C layer if there's any callback
1348 active, so Expat does a little more work than it
1349 otherwise would, but that's really an odd case. A more
1350 elaborate system of handlers and state could remove the
1351 C handler more effectively. */
1352 if (handlernum == CharacterData && self->in_callback)
1353 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001354 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001355 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001356 else if (v != NULL) {
1357 Py_INCREF(v);
1358 c_handler = handler_info[handlernum].handler;
1359 }
Serhiy Storchakaec397562016-04-06 09:50:03 +03001360 Py_XSETREF(self->handlers[handlernum], v);
Fred Drake71b63ff2002-06-28 22:29:01 +00001361 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001362 return 1;
1363 }
1364 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001365}
1366
1367static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001368xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001369{
Fred Drake6f987622000-08-25 18:03:30 +00001370 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Serhiy Storchaka931331a2015-09-07 22:37:02 +03001371 if (!PyUnicode_Check(name)) {
1372 PyErr_Format(PyExc_TypeError,
1373 "attribute name must be string, not '%.200s'",
1374 name->ob_type->tp_name);
1375 return -1;
1376 }
Fred Drake85d835f2001-02-08 15:39:08 +00001377 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001378 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1379 return -1;
1380 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001381 if (_PyUnicode_EqualToASCIIString(name, "buffer_text")) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001382 int b = PyObject_IsTrue(v);
1383 if (b < 0)
1384 return -1;
1385 if (b) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001386 if (self->buffer == NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001387 self->buffer = PyMem_Malloc(self->buffer_size);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001388 if (self->buffer == NULL) {
1389 PyErr_NoMemory();
1390 return -1;
1391 }
1392 self->buffer_used = 0;
1393 }
1394 }
1395 else if (self->buffer != NULL) {
1396 if (flush_character_buffer(self) < 0)
1397 return -1;
Victor Stinnerb6404912013-07-07 16:21:41 +02001398 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001399 self->buffer = NULL;
1400 }
1401 return 0;
1402 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001403 if (_PyUnicode_EqualToASCIIString(name, "namespace_prefixes")) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001404 int b = PyObject_IsTrue(v);
1405 if (b < 0)
1406 return -1;
1407 self->ns_prefixes = b;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001408 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1409 return 0;
1410 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001411 if (_PyUnicode_EqualToASCIIString(name, "ordered_attributes")) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001412 int b = PyObject_IsTrue(v);
1413 if (b < 0)
1414 return -1;
1415 self->ordered_attributes = b;
Fred Drake85d835f2001-02-08 15:39:08 +00001416 return 0;
1417 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001418 if (_PyUnicode_EqualToASCIIString(name, "specified_attributes")) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001419 int b = PyObject_IsTrue(v);
1420 if (b < 0)
1421 return -1;
1422 self->specified_attributes = b;
Fred Drake6f987622000-08-25 18:03:30 +00001423 return 0;
1424 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001425
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001426 if (_PyUnicode_EqualToASCIIString(name, "buffer_size")) {
Christian Heimes2380ac72008-01-09 00:17:24 +00001427 long new_buffer_size;
1428 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1430 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001431 }
1432
Serhiy Storchakade5f9f42015-09-07 22:51:56 +03001433 new_buffer_size = PyLong_AsLong(v);
1434 if (new_buffer_size <= 0) {
1435 if (!PyErr_Occurred())
1436 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1437 return -1;
1438 }
1439
Christian Heimes2380ac72008-01-09 00:17:24 +00001440 /* trivial case -- no change */
1441 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001443 }
1444
Christian Heimes2380ac72008-01-09 00:17:24 +00001445 /* check maximum */
1446 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 char errmsg[100];
1448 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1449 PyErr_SetString(PyExc_ValueError, errmsg);
1450 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001451 }
1452
1453 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 /* there is already a buffer */
1455 if (self->buffer_used != 0) {
Christian Heimes09994a92013-07-20 22:41:58 +02001456 if (flush_character_buffer(self) < 0) {
1457 return -1;
1458 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 }
1460 /* free existing buffer */
Victor Stinnerb6404912013-07-07 16:21:41 +02001461 PyMem_Free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001462 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001463 self->buffer = PyMem_Malloc(new_buffer_size);
Christian Heimes2380ac72008-01-09 00:17:24 +00001464 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 PyErr_NoMemory();
1466 return -1;
1467 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001468 self->buffer_size = new_buffer_size;
1469 return 0;
1470 }
1471
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001472 if (_PyUnicode_EqualToASCIIString(name, "CharacterDataHandler")) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001473 /* If we're changing the character data handler, flush all
1474 * cached data with the old handler. Not sure there's a
1475 * "right" thing to do, though, but this probably won't
1476 * happen.
1477 */
1478 if (flush_character_buffer(self) < 0)
1479 return -1;
1480 }
Fred Drake6f987622000-08-25 18:03:30 +00001481 if (sethandler(self, name, v)) {
1482 return 0;
1483 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001484 PyErr_SetObject(PyExc_AttributeError, name);
Fred Drake6f987622000-08-25 18:03:30 +00001485 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001486}
1487
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001488static int
1489xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1490{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001491 int i;
1492 for (i = 0; handler_info[i].name != NULL; i++)
1493 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001494 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001495}
1496
1497static int
1498xmlparse_clear(xmlparseobject *op)
1499{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001500 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001501 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001502 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001503}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001505PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001506
1507static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 PyVarObject_HEAD_INIT(NULL, 0)
1509 "pyexpat.xmlparser", /*tp_name*/
Antoine Pitrou23683ef2011-01-04 00:00:31 +00001510 sizeof(xmlparseobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 0, /*tp_itemsize*/
1512 /* methods */
1513 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1514 (printfunc)0, /*tp_print*/
1515 0, /*tp_getattr*/
Alexander Belopolskye239d232010-12-08 23:31:48 +00001516 0, /*tp_setattr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 0, /*tp_reserved*/
1518 (reprfunc)0, /*tp_repr*/
1519 0, /*tp_as_number*/
1520 0, /*tp_as_sequence*/
1521 0, /*tp_as_mapping*/
1522 (hashfunc)0, /*tp_hash*/
1523 (ternaryfunc)0, /*tp_call*/
1524 (reprfunc)0, /*tp_str*/
1525 (getattrofunc)xmlparse_getattro, /* tp_getattro */
Alexander Belopolskye239d232010-12-08 23:31:48 +00001526 (setattrofunc)xmlparse_setattro, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 0, /* tp_as_buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1530 (traverseproc)xmlparse_traverse, /* tp_traverse */
1531 (inquiry)xmlparse_clear, /* tp_clear */
1532 0, /* tp_richcompare */
1533 0, /* tp_weaklistoffset */
1534 0, /* tp_iter */
1535 0, /* tp_iternext */
1536 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001537};
1538
1539/* End of code for xmlparser objects */
1540/* -------------------------------------------------------- */
1541
Brett Cannond0aeda82014-08-22 14:23:20 -04001542/*[clinic input]
1543pyexpat.ParserCreate
1544
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001545 encoding: str(accept={str, NoneType}) = NULL
1546 namespace_separator: str(accept={str, NoneType}) = NULL
Brett Cannond0aeda82014-08-22 14:23:20 -04001547 intern: object = NULL
1548
1549Return a new XML parser object.
1550[clinic start generated code]*/
1551
Brett Cannond0aeda82014-08-22 14:23:20 -04001552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001553pyexpat_ParserCreate_impl(PyObject *module, const char *encoding,
Larry Hastings89964c42015-04-14 18:07:59 -04001554 const char *namespace_separator, PyObject *intern)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001555/*[clinic end generated code: output=295c0cf01ab1146c input=23d29704acad385d]*/
Brett Cannond0aeda82014-08-22 14:23:20 -04001556{
Fred Drakeb91a36b2002-06-27 19:40:48 +00001557 PyObject *result;
1558 int intern_decref = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001559
Fred Drakecde79132001-04-25 16:01:30 +00001560 if (namespace_separator != NULL
1561 && strlen(namespace_separator) > 1) {
1562 PyErr_SetString(PyExc_ValueError,
1563 "namespace_separator must be at most one"
1564 " character, omitted, or None");
1565 return NULL;
1566 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001567 /* Explicitly passing None means no interning is desired.
1568 Not passing anything means that a new dictionary is used. */
1569 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001571 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 intern = PyDict_New();
1573 if (!intern)
1574 return NULL;
1575 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001576 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001577 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1579 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001580 }
1581
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001582 result = newxmlparseobject(encoding, namespace_separator, intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001583 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001585 }
1586 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001587}
1588
Brett Cannond0aeda82014-08-22 14:23:20 -04001589/*[clinic input]
1590pyexpat.ErrorString
1591
1592 code: long
1593 /
1594
1595Returns string error for given number.
1596[clinic start generated code]*/
1597
Brett Cannond0aeda82014-08-22 14:23:20 -04001598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001599pyexpat_ErrorString_impl(PyObject *module, long code)
1600/*[clinic end generated code: output=2feae50d166f2174 input=cc67de010d9e62b3]*/
Brett Cannond0aeda82014-08-22 14:23:20 -04001601{
Fred Drake0582df92000-07-12 04:49:00 +00001602 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001603}
1604
1605/* List of methods defined in the module */
1606
1607static struct PyMethodDef pyexpat_methods[] = {
Brett Cannond0aeda82014-08-22 14:23:20 -04001608 PYEXPAT_PARSERCREATE_METHODDEF
1609 PYEXPAT_ERRORSTRING_METHODDEF
1610 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001611};
1612
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001613/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001615PyDoc_STRVAR(pyexpat_module_documentation,
1616"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001617
Fred Drakecde79132001-04-25 16:01:30 +00001618/* Initialization function for the module */
1619
1620#ifndef MODULE_NAME
1621#define MODULE_NAME "pyexpat"
1622#endif
1623
1624#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001625#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00001626#endif
1627
Martin v. Löwis1a214512008-06-11 05:26:20 +00001628static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 PyModuleDef_HEAD_INIT,
1630 MODULE_NAME,
1631 pyexpat_module_documentation,
1632 -1,
1633 pyexpat_methods,
1634 NULL,
1635 NULL,
1636 NULL,
1637 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001638};
1639
Martin v. Löwis069dde22003-01-21 10:58:18 +00001640PyMODINIT_FUNC
1641MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001642{
1643 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001644 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001645 PyObject *errors_module;
1646 PyObject *modelmod_name;
1647 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001648 PyObject *sys_modules;
Georg Brandlb4dac712010-10-15 14:46:48 +00001649 PyObject *tmpnum, *tmpstr;
1650 PyObject *codes_dict;
1651 PyObject *rev_codes_dict;
1652 int res;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001653 static struct PyExpat_CAPI capi;
Georg Brandlb4dac712010-10-15 14:46:48 +00001654 PyObject *capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001655
Fred Drake6f987622000-08-25 18:03:30 +00001656 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001657 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00001658 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001659 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001660 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00001661
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001662 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001664
Fred Drake0582df92000-07-12 04:49:00 +00001665 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001666 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001667 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001669
Fred Drake0582df92000-07-12 04:49:00 +00001670 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001671 if (ErrorObject == NULL) {
1672 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001673 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001674 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001675 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001676 }
1677 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001678 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001679 Py_INCREF(ErrorObject);
1680 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001681 Py_INCREF(&Xmlparsetype);
1682 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001683
Fred Drake738293d2000-12-21 17:25:07 +00001684 PyModule_AddStringConstant(m, "EXPAT_VERSION",
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001685 XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001686 {
1687 XML_Expat_Version info = XML_ExpatVersionInfo();
1688 PyModule_AddObject(m, "version_info",
1689 Py_BuildValue("(iii)", info.major,
1690 info.minor, info.micro));
1691 }
Fred Drake0582df92000-07-12 04:49:00 +00001692 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001693 compiled, this should check and set native_encoding
1694 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001695 */
Fred Drake93adb692000-09-23 04:55:48 +00001696 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001697
Fred Drake85d835f2001-02-08 15:39:08 +00001698 sys_modules = PySys_GetObject("modules");
Christian Heimes7a5457b2016-09-09 00:13:35 +02001699 if (sys_modules == NULL) {
1700 Py_DECREF(m);
1701 return NULL;
1702 }
Fred Drake93adb692000-09-23 04:55:48 +00001703 d = PyModule_GetDict(m);
Christian Heimes7a5457b2016-09-09 00:13:35 +02001704 if (d == NULL) {
1705 Py_DECREF(m);
1706 return NULL;
1707 }
Fred Drake6f987622000-08-25 18:03:30 +00001708 errors_module = PyDict_GetItem(d, errmod_name);
1709 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001710 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001711 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001712 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001713 /* gives away the reference to errors_module */
1714 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001715 }
1716 }
Fred Drake6f987622000-08-25 18:03:30 +00001717 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001718 model_module = PyDict_GetItem(d, modelmod_name);
1719 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001720 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001721 if (model_module != NULL) {
1722 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1723 /* gives away the reference to model_module */
1724 PyModule_AddObject(m, "model", model_module);
1725 }
1726 }
1727 Py_DECREF(modelmod_name);
Christian Heimes7a5457b2016-09-09 00:13:35 +02001728 if (errors_module == NULL || model_module == NULL) {
Fred Drake85d835f2001-02-08 15:39:08 +00001729 /* Don't core dump later! */
Christian Heimes7a5457b2016-09-09 00:13:35 +02001730 Py_DECREF(m);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001731 return NULL;
Christian Heimes7a5457b2016-09-09 00:13:35 +02001732 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733
Martin v. Löwisc847f402003-01-21 11:09:21 +00001734#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001735 {
1736 const XML_Feature *features = XML_GetFeatureList();
1737 PyObject *list = PyList_New(0);
1738 if (list == NULL)
1739 /* just ignore it */
1740 PyErr_Clear();
1741 else {
1742 int i = 0;
1743 for (; features[i].feature != XML_FEATURE_END; ++i) {
1744 int ok;
1745 PyObject *item = Py_BuildValue("si", features[i].name,
1746 features[i].value);
1747 if (item == NULL) {
1748 Py_DECREF(list);
1749 list = NULL;
1750 break;
1751 }
1752 ok = PyList_Append(list, item);
1753 Py_DECREF(item);
1754 if (ok < 0) {
1755 PyErr_Clear();
1756 break;
1757 }
1758 }
1759 if (list != NULL)
1760 PyModule_AddObject(m, "features", list);
1761 }
1762 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001763#endif
Fred Drake6f987622000-08-25 18:03:30 +00001764
Georg Brandlb4dac712010-10-15 14:46:48 +00001765 codes_dict = PyDict_New();
1766 rev_codes_dict = PyDict_New();
1767 if (codes_dict == NULL || rev_codes_dict == NULL) {
1768 Py_XDECREF(codes_dict);
1769 Py_XDECREF(rev_codes_dict);
1770 return NULL;
1771 }
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001772
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001773#define MYCONST(name) \
Georg Brandlb4dac712010-10-15 14:46:48 +00001774 if (PyModule_AddStringConstant(errors_module, #name, \
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001775 XML_ErrorString(name)) < 0) \
Georg Brandlb4dac712010-10-15 14:46:48 +00001776 return NULL; \
1777 tmpnum = PyLong_FromLong(name); \
1778 if (tmpnum == NULL) return NULL; \
1779 res = PyDict_SetItemString(codes_dict, \
1780 XML_ErrorString(name), tmpnum); \
1781 if (res < 0) return NULL; \
1782 tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \
1783 if (tmpstr == NULL) return NULL; \
1784 res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \
1785 Py_DECREF(tmpstr); \
1786 Py_DECREF(tmpnum); \
1787 if (res < 0) return NULL; \
Fred Drake7bd9f412000-07-04 23:51:31 +00001788
Fred Drake0582df92000-07-12 04:49:00 +00001789 MYCONST(XML_ERROR_NO_MEMORY);
1790 MYCONST(XML_ERROR_SYNTAX);
1791 MYCONST(XML_ERROR_NO_ELEMENTS);
1792 MYCONST(XML_ERROR_INVALID_TOKEN);
1793 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1794 MYCONST(XML_ERROR_PARTIAL_CHAR);
1795 MYCONST(XML_ERROR_TAG_MISMATCH);
1796 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1797 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1798 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1799 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1800 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1801 MYCONST(XML_ERROR_ASYNC_ENTITY);
1802 MYCONST(XML_ERROR_BAD_CHAR_REF);
1803 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1804 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1805 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1806 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1807 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001808 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1809 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1810 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001811 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1812 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1813 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1814 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1815 /* Added in Expat 1.95.7. */
1816 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1817 /* Added in Expat 1.95.8. */
1818 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1819 MYCONST(XML_ERROR_INCOMPLETE_PE);
1820 MYCONST(XML_ERROR_XML_DECL);
1821 MYCONST(XML_ERROR_TEXT_DECL);
1822 MYCONST(XML_ERROR_PUBLICID);
1823 MYCONST(XML_ERROR_SUSPENDED);
1824 MYCONST(XML_ERROR_NOT_SUSPENDED);
1825 MYCONST(XML_ERROR_ABORTED);
1826 MYCONST(XML_ERROR_FINISHED);
1827 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001828
Georg Brandlb4dac712010-10-15 14:46:48 +00001829 if (PyModule_AddStringConstant(errors_module, "__doc__",
1830 "Constants used to describe "
1831 "error conditions.") < 0)
1832 return NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001833
Georg Brandlb4dac712010-10-15 14:46:48 +00001834 if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0)
1835 return NULL;
1836 if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0)
1837 return NULL;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00001838
Fred Drake93adb692000-09-23 04:55:48 +00001839#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001840
Fred Drake85d835f2001-02-08 15:39:08 +00001841#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001842 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1843 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1844 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001845#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001846
Fred Drake85d835f2001-02-08 15:39:08 +00001847#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1848 PyModule_AddStringConstant(model_module, "__doc__",
1849 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001850
Fred Drake85d835f2001-02-08 15:39:08 +00001851 MYCONST(XML_CTYPE_EMPTY);
1852 MYCONST(XML_CTYPE_ANY);
1853 MYCONST(XML_CTYPE_MIXED);
1854 MYCONST(XML_CTYPE_NAME);
1855 MYCONST(XML_CTYPE_CHOICE);
1856 MYCONST(XML_CTYPE_SEQ);
1857
1858 MYCONST(XML_CQUANT_NONE);
1859 MYCONST(XML_CQUANT_OPT);
1860 MYCONST(XML_CQUANT_REP);
1861 MYCONST(XML_CQUANT_PLUS);
1862#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001863
1864 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001865 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001866 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001867 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1868 capi.MINOR_VERSION = XML_MINOR_VERSION;
1869 capi.MICRO_VERSION = XML_MICRO_VERSION;
1870 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001871 capi.GetErrorCode = XML_GetErrorCode;
1872 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1873 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001874 capi.Parse = XML_Parse;
1875 capi.ParserCreate_MM = XML_ParserCreate_MM;
1876 capi.ParserFree = XML_ParserFree;
1877 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1878 capi.SetCommentHandler = XML_SetCommentHandler;
1879 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1880 capi.SetElementHandler = XML_SetElementHandler;
1881 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1882 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1883 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1884 capi.SetUserData = XML_SetUserData;
Eli Bendersky2b6b73e2012-06-01 11:32:34 +03001885 capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
Serhiy Storchaka66d53fa2013-05-22 17:07:51 +03001886 capi.SetEncoding = XML_SetEncoding;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001887 capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888
Benjamin Petersonb173f782009-05-05 22:31:58 +00001889 /* export using capsule */
1890 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001891 if (capi_object)
1892 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001893 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001894}
1895
Fred Drake6f987622000-08-25 18:03:30 +00001896static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001897clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001898{
Fred Drakecde79132001-04-25 16:01:30 +00001899 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001900
Fred Drake71b63ff2002-06-28 22:29:01 +00001901 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001902 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 self->handlers[i] = NULL;
1904 else {
Serhiy Storchaka1ed017a2015-12-27 15:51:32 +02001905 Py_CLEAR(self->handlers[i]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00001907 }
Fred Drakecde79132001-04-25 16:01:30 +00001908 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001909}
1910
Tim Peters0c322792002-07-17 16:49:03 +00001911static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00001912 {"StartElementHandler",
1913 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001914 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001915 {"EndElementHandler",
1916 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001917 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001918 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001919 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1920 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001921 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001922 (xmlhandlersetter)XML_SetCharacterDataHandler,
1923 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001924 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001925 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001926 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001927 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00001928 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001929 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001930 {"StartNamespaceDeclHandler",
1931 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001932 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00001933 {"EndNamespaceDeclHandler",
1934 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001935 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00001936 {"CommentHandler",
1937 (xmlhandlersetter)XML_SetCommentHandler,
1938 (xmlhandler)my_CommentHandler},
1939 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001940 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001941 (xmlhandler)my_StartCdataSectionHandler},
1942 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001943 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00001944 (xmlhandler)my_EndCdataSectionHandler},
1945 {"DefaultHandler",
1946 (xmlhandlersetter)XML_SetDefaultHandler,
1947 (xmlhandler)my_DefaultHandler},
1948 {"DefaultHandlerExpand",
1949 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1950 (xmlhandler)my_DefaultHandlerExpandHandler},
1951 {"NotStandaloneHandler",
1952 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1953 (xmlhandler)my_NotStandaloneHandler},
1954 {"ExternalEntityRefHandler",
1955 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00001956 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001957 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001958 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001959 (xmlhandler)my_StartDoctypeDeclHandler},
1960 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00001961 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001962 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00001963 {"EntityDeclHandler",
1964 (xmlhandlersetter)XML_SetEntityDeclHandler,
1965 (xmlhandler)my_EntityDeclHandler},
1966 {"XmlDeclHandler",
1967 (xmlhandlersetter)XML_SetXmlDeclHandler,
1968 (xmlhandler)my_XmlDeclHandler},
1969 {"ElementDeclHandler",
1970 (xmlhandlersetter)XML_SetElementDeclHandler,
1971 (xmlhandler)my_ElementDeclHandler},
1972 {"AttlistDeclHandler",
1973 (xmlhandlersetter)XML_SetAttlistDeclHandler,
1974 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001975#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00001976 {"SkippedEntityHandler",
1977 (xmlhandlersetter)XML_SetSkippedEntityHandler,
1978 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001979#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001980
Fred Drake0582df92000-07-12 04:49:00 +00001981 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001982};