blob: 88984e705c21aad42694b17e17ec9b76eaf378f0 [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
Jeremy Hylton9263f572003-06-27 16:13:17 +000018#define FIX_TRACE
Martin v. Löwis339d0f72001-08-17 18:39:25 +000019
Christian Heimesfa535f52013-07-07 17:35:11 +020020static XML_Memory_Handling_Suite ExpatMemoryHandler = {
21 PyObject_Malloc, PyObject_Realloc, PyObject_Free};
22
Fred Drake0582df92000-07-12 04:49:00 +000023enum HandlerTypes {
24 StartElement,
25 EndElement,
26 ProcessingInstruction,
27 CharacterData,
28 UnparsedEntityDecl,
29 NotationDecl,
30 StartNamespaceDecl,
31 EndNamespaceDecl,
32 Comment,
33 StartCdataSection,
34 EndCdataSection,
35 Default,
36 DefaultHandlerExpand,
37 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000038 ExternalEntityRef,
39 StartDoctypeDecl,
40 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000041 EntityDecl,
42 XmlDecl,
43 ElementDecl,
44 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000045#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000046 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000047#endif
Fred Drake85d835f2001-02-08 15:39:08 +000048 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000049};
50
51static PyObject *ErrorObject;
52
53/* ----------------------------------------------------- */
54
55/* Declarations for objects of type xmlparser */
56
57typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000058 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000059
Fred Drake0582df92000-07-12 04:49:00 +000060 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000061 int ordered_attributes; /* Return attributes as a list. */
62 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000063 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000064 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000065 XML_Char *buffer; /* Buffer used when accumulating characters */
66 /* NULL if not enabled */
67 int buffer_size; /* Size of buffer, in XML_Char units */
68 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000069 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000070 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000071} xmlparseobject;
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
94set_error_attr(PyObject *err, char *name, int value)
95{
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;
122 err = PyObject_CallFunction(ErrorObject, "O", buffer);
123 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) {
164 Py_INCREF(Py_None);
165 return Py_None;
166 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000167 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000168}
169
Fred Drake0582df92000-07-12 04:49:00 +0000170static PyObject *
171conv_string_len_to_unicode(const XML_Char *str, int len)
172{
Fred Drake71b63ff2002-06-28 22:29:01 +0000173 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000174 and hence in UTF-8. */
175 /* UTF-8 from Expat, Unicode desired */
176 if (str == NULL) {
177 Py_INCREF(Py_None);
178 return Py_None;
179 }
Fred Drake6f987622000-08-25 18:03:30 +0000180 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000181}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000182
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000183/* Callback routines */
184
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000185static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000186
Martin v. Löwis069dde22003-01-21 10:58:18 +0000187/* This handler is used when an error has been detected, in the hope
188 that actual parsing can be terminated early. This will only help
189 if an external entity reference is encountered. */
190static int
191error_external_entity_ref_handler(XML_Parser parser,
192 const XML_Char *context,
193 const XML_Char *base,
194 const XML_Char *systemId,
195 const XML_Char *publicId)
196{
197 return 0;
198}
199
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000200/* Dummy character data handler used when an error (exception) has
201 been detected, and the actual parsing can be terminated early.
202 This is needed since character data handler can't be safely removed
203 from within the character data handler, but can be replaced. It is
204 used only from the character data handler trampoline, and must be
205 used right after `flag_error()` is called. */
206static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207noop_character_data_handler(void *userData, const XML_Char *data, int len)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000208{
209 /* Do nothing. */
210}
211
Fred Drake6f987622000-08-25 18:03:30 +0000212static void
213flag_error(xmlparseobject *self)
214{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000215 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000216 XML_SetExternalEntityRefHandler(self->itself,
217 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000218}
219
220static PyCodeObject*
221getcode(enum HandlerTypes slot, char* func_name, int lineno)
222{
Fred Drakebd6101c2001-02-14 18:29:45 +0000223 if (handler_info[slot].tb_code == NULL) {
Fred Drakebd6101c2001-02-14 18:29:45 +0000224 handler_info[slot].tb_code =
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000225 PyCode_NewEmpty(__FILE__, func_name, lineno);
Fred Drakebd6101c2001-02-14 18:29:45 +0000226 }
227 return handler_info[slot].tb_code;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000228}
229
Jeremy Hylton9263f572003-06-27 16:13:17 +0000230#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000231static int
232trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
233{
234 int result = 0;
235 if (!tstate->use_tracing || tstate->tracing)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 return 0;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000237 if (tstate->c_profilefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 tstate->tracing++;
239 result = tstate->c_profilefunc(tstate->c_profileobj,
240 f, code , val);
241 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
242 || (tstate->c_profilefunc != NULL));
243 tstate->tracing--;
244 if (result)
245 return result;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000246 }
247 if (tstate->c_tracefunc != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 tstate->tracing++;
249 result = tstate->c_tracefunc(tstate->c_traceobj,
250 f, code , val);
251 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
252 || (tstate->c_profilefunc != NULL));
253 tstate->tracing--;
254 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000255 return result;
256}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000257
258static int
259trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
260{
261 PyObject *type, *value, *traceback, *arg;
262 int err;
263
264 if (tstate->c_tracefunc == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000266
267 PyErr_Fetch(&type, &value, &traceback);
268 if (value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 value = Py_None;
270 Py_INCREF(value);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000271 }
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000272 arg = PyTuple_Pack(3, type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000273 if (arg == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 PyErr_Restore(type, value, traceback);
275 return 0;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000276 }
277 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
278 Py_DECREF(arg);
279 if (err == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 PyErr_Restore(type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000281 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 Py_XDECREF(type);
283 Py_XDECREF(value);
284 Py_XDECREF(traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000285 }
286 return err;
287}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000288#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000289
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000290static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000291call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
292 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000293{
Fred Drakebd6101c2001-02-14 18:29:45 +0000294 PyThreadState *tstate = PyThreadState_GET();
295 PyFrameObject *f;
Christian Heimesa6404ad2013-07-20 22:54:25 +0200296 PyObject *res, *globals;
Fred Drakebd6101c2001-02-14 18:29:45 +0000297
298 if (c == NULL)
299 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300
Christian Heimesa6404ad2013-07-20 22:54:25 +0200301 globals = PyEval_GetGlobals();
302 if (globals == NULL) {
303 return NULL;
304 }
305
306 f = PyFrame_New(tstate, c, globals, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000307 if (f == NULL)
308 return NULL;
309 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000310#ifdef FIX_TRACE
311 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000313 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000314#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000315 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000316 if (res == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 if (tstate->curexc_traceback == NULL)
318 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000319 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000320#ifdef FIX_TRACE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 if (trace_frame_exc(tstate, f) < 0) {
322 return NULL;
323 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000324 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000325 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200327 Py_CLEAR(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000329 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000330#else
331 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000332#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000333 tstate->frame = f->f_back;
334 Py_DECREF(f);
335 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000336}
337
Fred Drakeb91a36b2002-06-27 19:40:48 +0000338static PyObject*
339string_intern(xmlparseobject *self, const char* str)
340{
Guido van Rossum4ca94712007-07-23 17:42:32 +0000341 PyObject *result = conv_string_to_unicode(str);
Fred Drakeb91a36b2002-06-27 19:40:48 +0000342 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000343 /* result can be NULL if the unicode conversion failed. */
344 if (!result)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000346 if (!self->intern)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000348 value = PyDict_GetItem(self->intern, result);
349 if (!value) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if (PyDict_SetItem(self->intern, result, result) == 0)
Fred Drakeb91a36b2002-06-27 19:40:48 +0000351 return result;
352 else
353 return NULL;
354 }
355 Py_INCREF(value);
356 Py_DECREF(result);
357 return value;
358}
359
Fred Drake2a3d7db2002-06-28 22:56:48 +0000360/* Return 0 on success, -1 on exception.
361 * flag_error() will be called before return if needed.
362 */
363static int
364call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
365{
366 PyObject *args;
367 PyObject *temp;
368
Georg Brandlc01537f2010-10-15 16:26:08 +0000369 if (!have_handler(self, CharacterData))
370 return -1;
371
Fred Drake2a3d7db2002-06-28 22:56:48 +0000372 args = PyTuple_New(1);
373 if (args == NULL)
374 return -1;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000375 temp = (conv_string_len_to_unicode(buffer, len));
Fred Drake2a3d7db2002-06-28 22:56:48 +0000376 if (temp == NULL) {
377 Py_DECREF(args);
378 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000379 XML_SetCharacterDataHandler(self->itself,
380 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000381 return -1;
382 }
383 PyTuple_SET_ITEM(args, 0, temp);
384 /* temp is now a borrowed reference; consider it unused. */
385 self->in_callback = 1;
386 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000387 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000388 /* temp is an owned reference again, or NULL */
389 self->in_callback = 0;
390 Py_DECREF(args);
391 if (temp == NULL) {
392 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000393 XML_SetCharacterDataHandler(self->itself,
394 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000395 return -1;
396 }
397 Py_DECREF(temp);
398 return 0;
399}
400
401static int
402flush_character_buffer(xmlparseobject *self)
403{
404 int rc;
405 if (self->buffer == NULL || self->buffer_used == 0)
406 return 0;
407 rc = call_character_handler(self, self->buffer, self->buffer_used);
408 self->buffer_used = 0;
409 return rc;
410}
411
412static void
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
Fred Drake2a3d7db2002-06-28 22:56:48 +0000414{
415 xmlparseobject *self = (xmlparseobject *) userData;
Victor Stinner9e09c262013-07-18 23:17:01 +0200416
417 if (PyErr_Occurred())
418 return;
419
Fred Drake2a3d7db2002-06-28 22:56:48 +0000420 if (self->buffer == NULL)
421 call_character_handler(self, data, len);
422 else {
423 if ((self->buffer_used + len) > self->buffer_size) {
424 if (flush_character_buffer(self) < 0)
425 return;
426 /* handler might have changed; drop the rest on the floor
427 * if there isn't a handler anymore
428 */
429 if (!have_handler(self, CharacterData))
430 return;
431 }
432 if (len > self->buffer_size) {
433 call_character_handler(self, data, len);
434 self->buffer_used = 0;
435 }
436 else {
437 memcpy(self->buffer + self->buffer_used,
438 data, len * sizeof(XML_Char));
439 self->buffer_used += len;
440 }
441 }
442}
443
Fred Drake85d835f2001-02-08 15:39:08 +0000444static void
445my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000446 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000447{
448 xmlparseobject *self = (xmlparseobject *)userData;
449
Fred Drake71b63ff2002-06-28 22:29:01 +0000450 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000451 PyObject *container, *rv, *args;
452 int i, max;
453
Victor Stinner9e09c262013-07-18 23:17:01 +0200454 if (PyErr_Occurred())
455 return;
456
Fred Drake2a3d7db2002-06-28 22:56:48 +0000457 if (flush_character_buffer(self) < 0)
458 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000459 /* Set max to the number of slots filled in atts[]; max/2 is
460 * the number of attributes we need to process.
461 */
462 if (self->specified_attributes) {
463 max = XML_GetSpecifiedAttributeCount(self->itself);
464 }
465 else {
466 max = 0;
467 while (atts[max] != NULL)
468 max += 2;
469 }
470 /* Build the container. */
471 if (self->ordered_attributes)
472 container = PyList_New(max);
473 else
474 container = PyDict_New();
475 if (container == NULL) {
476 flag_error(self);
477 return;
478 }
479 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000480 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000481 PyObject *v;
482 if (n == NULL) {
483 flag_error(self);
484 Py_DECREF(container);
485 return;
486 }
Guido van Rossum4ca94712007-07-23 17:42:32 +0000487 v = conv_string_to_unicode((XML_Char *) atts[i+1]);
Fred Drake85d835f2001-02-08 15:39:08 +0000488 if (v == NULL) {
489 flag_error(self);
490 Py_DECREF(container);
491 Py_DECREF(n);
492 return;
493 }
494 if (self->ordered_attributes) {
495 PyList_SET_ITEM(container, i, n);
496 PyList_SET_ITEM(container, i+1, v);
497 }
498 else if (PyDict_SetItem(container, n, v)) {
499 flag_error(self);
500 Py_DECREF(n);
501 Py_DECREF(v);
502 return;
503 }
504 else {
505 Py_DECREF(n);
506 Py_DECREF(v);
507 }
508 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000509 args = string_intern(self, name);
510 if (args != NULL)
511 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000512 if (args == NULL) {
513 Py_DECREF(container);
514 return;
515 }
516 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000517 self->in_callback = 1;
518 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000519 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000520 self->in_callback = 0;
521 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000522 if (rv == NULL) {
523 flag_error(self);
524 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000525 }
Fred Drake85d835f2001-02-08 15:39:08 +0000526 Py_DECREF(rv);
527 }
528}
529
530#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
531 RETURN, GETUSERDATA) \
532static RC \
533my_##NAME##Handler PARAMS {\
534 xmlparseobject *self = GETUSERDATA ; \
535 PyObject *args = NULL; \
536 PyObject *rv = NULL; \
537 INIT \
538\
Fred Drake71b63ff2002-06-28 22:29:01 +0000539 if (have_handler(self, NAME)) { \
Victor Stinner9e09c262013-07-18 23:17:01 +0200540 if (PyErr_Occurred()) \
541 return RETURN; \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000542 if (flush_character_buffer(self) < 0) \
543 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000544 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000545 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000546 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000547 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
Fred Drake39689c52004-08-13 03:12:57 +0000548 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000549 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000550 Py_DECREF(args); \
551 if (rv == NULL) { \
552 flag_error(self); \
553 return RETURN; \
554 } \
555 CONVERSION \
556 Py_DECREF(rv); \
557 } \
558 return RETURN; \
559}
560
Fred Drake6f987622000-08-25 18:03:30 +0000561#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
563 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000564
Fred Drake6f987622000-08-25 18:03:30 +0000565#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
567 rc = PyLong_AsLong(rv);, rc, \
568 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000569
Fred Drake71b63ff2002-06-28 22:29:01 +0000570VOID_HANDLER(EndElement,
571 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000572 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000573
Fred Drake6f987622000-08-25 18:03:30 +0000574VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000575 (void *userData,
576 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000577 const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000578 ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000579
Fred Drake6f987622000-08-25 18:03:30 +0000580VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000581 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000582 const XML_Char *entityName,
583 const XML_Char *base,
584 const XML_Char *systemId,
585 const XML_Char *publicId,
586 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000587 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000588 string_intern(self, entityName), string_intern(self, base),
589 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000590 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000591
Fred Drake85d835f2001-02-08 15:39:08 +0000592VOID_HANDLER(EntityDecl,
593 (void *userData,
594 const XML_Char *entityName,
595 int is_parameter_entity,
596 const XML_Char *value,
597 int value_length,
598 const XML_Char *base,
599 const XML_Char *systemId,
600 const XML_Char *publicId,
601 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000602 ("NiNNNNN",
603 string_intern(self, entityName), is_parameter_entity,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000604 (conv_string_len_to_unicode(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000605 string_intern(self, base), string_intern(self, systemId),
606 string_intern(self, publicId),
607 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000608
609VOID_HANDLER(XmlDecl,
610 (void *userData,
611 const XML_Char *version,
612 const XML_Char *encoding,
613 int standalone),
614 ("(O&O&i)",
Guido van Rossum4ca94712007-07-23 17:42:32 +0000615 conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000616 standalone))
617
618static PyObject *
619conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000620 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000621{
622 PyObject *result = NULL;
623 PyObject *children = PyTuple_New(model->numchildren);
624 int i;
625
626 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000627 assert(model->numchildren < INT_MAX);
628 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000629 PyObject *child = conv_content_model(&model->children[i],
630 conv_string);
631 if (child == NULL) {
632 Py_XDECREF(children);
633 return NULL;
634 }
635 PyTuple_SET_ITEM(children, i, child);
636 }
637 result = Py_BuildValue("(iiO&N)",
638 model->type, model->quant,
639 conv_string,model->name, children);
640 }
641 return result;
642}
643
Fred Drake06dd8cf2003-02-02 03:54:17 +0000644static void
645my_ElementDeclHandler(void *userData,
646 const XML_Char *name,
647 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000648{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000649 xmlparseobject *self = (xmlparseobject *)userData;
650 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000651
Fred Drake06dd8cf2003-02-02 03:54:17 +0000652 if (have_handler(self, ElementDecl)) {
653 PyObject *rv = NULL;
654 PyObject *modelobj, *nameobj;
655
Victor Stinner9e09c262013-07-18 23:17:01 +0200656 if (PyErr_Occurred())
657 return;
658
Fred Drake06dd8cf2003-02-02 03:54:17 +0000659 if (flush_character_buffer(self) < 0)
660 goto finally;
Guido van Rossum4ca94712007-07-23 17:42:32 +0000661 modelobj = conv_content_model(model, (conv_string_to_unicode));
Fred Drake06dd8cf2003-02-02 03:54:17 +0000662 if (modelobj == NULL) {
663 flag_error(self);
664 goto finally;
665 }
666 nameobj = string_intern(self, name);
667 if (nameobj == NULL) {
668 Py_DECREF(modelobj);
669 flag_error(self);
670 goto finally;
671 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000672 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000673 if (args == NULL) {
674 Py_DECREF(modelobj);
675 flag_error(self);
676 goto finally;
677 }
678 self->in_callback = 1;
679 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000680 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000681 self->in_callback = 0;
682 if (rv == NULL) {
683 flag_error(self);
684 goto finally;
685 }
686 Py_DECREF(rv);
687 }
688 finally:
689 Py_XDECREF(args);
690 XML_FreeContentModel(self->itself, model);
691 return;
692}
Fred Drake85d835f2001-02-08 15:39:08 +0000693
694VOID_HANDLER(AttlistDecl,
695 (void *userData,
696 const XML_Char *elname,
697 const XML_Char *attname,
698 const XML_Char *att_type,
699 const XML_Char *dflt,
700 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000701 ("(NNO&O&i)",
702 string_intern(self, elname), string_intern(self, attname),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000703 conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
Fred Drake85d835f2001-02-08 15:39:08 +0000704 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000705
Martin v. Löwisc847f402003-01-21 11:09:21 +0000706#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000707VOID_HANDLER(SkippedEntity,
708 (void *userData,
709 const XML_Char *entityName,
710 int is_parameter_entity),
711 ("Ni",
712 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000713#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000714
Fred Drake71b63ff2002-06-28 22:29:01 +0000715VOID_HANDLER(NotationDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 (void *userData,
717 const XML_Char *notationName,
718 const XML_Char *base,
719 const XML_Char *systemId,
720 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000721 ("(NNNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 string_intern(self, notationName), string_intern(self, base),
723 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000724
Fred Drake6f987622000-08-25 18:03:30 +0000725VOID_HANDLER(StartNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 (void *userData,
727 const XML_Char *prefix,
728 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000729 ("(NN)",
730 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000731
Fred Drake6f987622000-08-25 18:03:30 +0000732VOID_HANDLER(EndNamespaceDecl,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 (void *userData,
734 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000735 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000736
Fred Drake6f987622000-08-25 18:03:30 +0000737VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000738 (void *userData, const XML_Char *data),
Guido van Rossum4ca94712007-07-23 17:42:32 +0000739 ("(O&)", conv_string_to_unicode ,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000740
Fred Drake6f987622000-08-25 18:03:30 +0000741VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000742 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000744
Fred Drake6f987622000-08-25 18:03:30 +0000745VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000746 (void *userData),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000748
Fred Drake6f987622000-08-25 18:03:30 +0000749VOID_HANDLER(Default,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 (void *userData, const XML_Char *s, int len),
751 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000752
Fred Drake6f987622000-08-25 18:03:30 +0000753VOID_HANDLER(DefaultHandlerExpand,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 (void *userData, const XML_Char *s, int len),
755 ("(N)", (conv_string_len_to_unicode(s,len))))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000756
Fred Drake71b63ff2002-06-28 22:29:01 +0000757INT_HANDLER(NotStandalone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 (void *userData),
759 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000760
Fred Drake6f987622000-08-25 18:03:30 +0000761RC_HANDLER(int, ExternalEntityRef,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 (XML_Parser parser,
763 const XML_Char *context,
764 const XML_Char *base,
765 const XML_Char *systemId,
766 const XML_Char *publicId),
767 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000768 ("(O&NNN)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 conv_string_to_unicode ,context, string_intern(self, base),
770 string_intern(self, systemId), string_intern(self, publicId)),
771 rc = PyLong_AsLong(rv);, rc,
772 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000773
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000774/* XXX UnknownEncodingHandler */
775
Fred Drake85d835f2001-02-08 15:39:08 +0000776VOID_HANDLER(StartDoctypeDecl,
777 (void *userData, const XML_Char *doctypeName,
778 const XML_Char *sysid, const XML_Char *pubid,
779 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000780 ("(NNNi)", string_intern(self, doctypeName),
781 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000782 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000783
784VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000785
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000786/* ---------------------------------------------------------------- */
Brett Cannond0aeda82014-08-22 14:23:20 -0400787/*[clinic input]
788class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype"
789[clinic start generated code]*/
790/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2393162385232e1c]*/
791
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000792
Fred Drake71b63ff2002-06-28 22:29:01 +0000793static PyObject *
794get_parse_result(xmlparseobject *self, int rv)
795{
796 if (PyErr_Occurred()) {
797 return NULL;
798 }
799 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000800 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000801 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000802 if (flush_character_buffer(self) < 0) {
803 return NULL;
804 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000805 return PyLong_FromLong(rv);
Fred Drake71b63ff2002-06-28 22:29:01 +0000806}
807
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200808#define MAX_CHUNK_SIZE (1 << 20)
809
Brett Cannond0aeda82014-08-22 14:23:20 -0400810/*[clinic input]
811pyexpat.xmlparser.Parse
812
813 data: object
814 isFinal: int = 0
815 /
816
817Parse XML data.
818
819`isfinal' should be true at end of input.
820[clinic start generated code]*/
821
822PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__,
823"Parse($self, data, isFinal=0, /)\n"
824"--\n"
825"\n"
826"Parse XML data.\n"
827"\n"
828"`isfinal\' should be true at end of input.");
829
830#define PYEXPAT_XMLPARSER_PARSE_METHODDEF \
831 {"Parse", (PyCFunction)pyexpat_xmlparser_Parse, METH_VARARGS, pyexpat_xmlparser_Parse__doc__},
832
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000833static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -0400834pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, int isFinal);
835
836static PyObject *
837pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000838{
Brett Cannond0aeda82014-08-22 14:23:20 -0400839 PyObject *return_value = NULL;
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200840 PyObject *data;
Fred Drake0582df92000-07-12 04:49:00 +0000841 int isFinal = 0;
Brett Cannond0aeda82014-08-22 14:23:20 -0400842
843 if (!PyArg_ParseTuple(args,
844 "O|i:Parse",
845 &data, &isFinal))
846 goto exit;
847 return_value = pyexpat_xmlparser_Parse_impl(self, data, isFinal);
848
849exit:
850 return return_value;
851}
852
853static PyObject *
854pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, int isFinal)
855/*[clinic end generated code: output=65b1652b01f20856 input=e37b81b8948ca7e0]*/
856{
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200857 const char *s;
858 Py_ssize_t slen;
859 Py_buffer view;
860 int rc;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000861
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200862 if (PyUnicode_Check(data)) {
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200863 view.buf = NULL;
Serhiy Storchaka36b365c2013-02-04 18:28:01 +0200864 s = PyUnicode_AsUTF8AndSize(data, &slen);
865 if (s == NULL)
866 return NULL;
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200867 /* Explicitly set UTF-8 encoding. Return code ignored. */
868 (void)XML_SetEncoding(self->itself, "utf-8");
869 }
870 else {
871 if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
872 return NULL;
873 s = view.buf;
874 slen = view.len;
875 }
876
877 while (slen > MAX_CHUNK_SIZE) {
878 rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0);
879 if (!rc)
880 goto done;
881 s += MAX_CHUNK_SIZE;
882 slen -= MAX_CHUNK_SIZE;
883 }
Christian Heimesba723202013-11-22 00:46:18 +0100884 assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX);
885 rc = XML_Parse(self->itself, s, (int)slen, isFinal);
Serhiy Storchaka43536e92013-02-04 18:26:15 +0200886
887done:
888 if (view.buf != NULL)
889 PyBuffer_Release(&view);
890 return get_parse_result(self, rc);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000891}
892
Fred Drakeca1f4262000-09-21 20:10:23 +0000893/* File reading copied from cPickle */
894
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000895#define BUF_SIZE 2048
896
Fred Drake0582df92000-07-12 04:49:00 +0000897static int
898readinst(char *buf, int buf_size, PyObject *meth)
899{
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000900 PyObject *str;
901 Py_ssize_t len;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000902 char *ptr;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000903
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000904 str = PyObject_CallFunction(meth, "n", buf_size);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000905 if (str == NULL)
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000906 goto error;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000907
Christian Heimes72b710a2008-05-26 13:28:38 +0000908 if (PyBytes_Check(str))
909 ptr = PyBytes_AS_STRING(str);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000910 else if (PyByteArray_Check(str))
911 ptr = PyByteArray_AS_STRING(str);
Guido van Rossum98297ee2007-11-06 21:34:58 +0000912 else {
Fred Drake71b63ff2002-06-28 22:29:01 +0000913 PyErr_Format(PyExc_TypeError,
Guido van Rossum4ca94712007-07-23 17:42:32 +0000914 "read() did not return a bytes object (type=%.400s)",
Christian Heimes90aa7642007-12-19 02:45:37 +0000915 Py_TYPE(str)->tp_name);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000916 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000917 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000918 len = Py_SIZE(str);
Fred Drake0582df92000-07-12 04:49:00 +0000919 if (len > buf_size) {
920 PyErr_Format(PyExc_ValueError,
921 "read() returned too much data: "
Victor Stinner9d6f9362011-01-04 22:00:04 +0000922 "%i bytes requested, %zd returned",
Fred Drake0582df92000-07-12 04:49:00 +0000923 buf_size, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000924 goto error;
Fred Drake0582df92000-07-12 04:49:00 +0000925 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000926 memcpy(buf, ptr, len);
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000927 Py_DECREF(str);
928 /* len <= buf_size <= INT_MAX */
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000929 return (int)len;
Victor Stinner95f1dfc2011-01-10 23:00:36 +0000930
931error:
932 Py_XDECREF(str);
933 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000934}
935
Brett Cannond0aeda82014-08-22 14:23:20 -0400936/*[clinic input]
937pyexpat.xmlparser.ParseFile
938
939 file: object
940 /
941
942Parse XML data from file-like object.
943[clinic start generated code]*/
944
945PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__,
946"ParseFile($self, file, /)\n"
947"--\n"
948"\n"
949"Parse XML data from file-like object.");
950
951#define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \
952 {"ParseFile", (PyCFunction)pyexpat_xmlparser_ParseFile, METH_O, pyexpat_xmlparser_ParseFile__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000953
954static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -0400955pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file)
956/*[clinic end generated code: output=2e13803c3d8c22b2 input=fbb5a12b6038d735]*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000957{
Fred Drake0582df92000-07-12 04:49:00 +0000958 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000959 PyObject *readmethod = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200960 _Py_IDENTIFIER(read);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000961
Brett Cannond0aeda82014-08-22 14:23:20 -0400962 readmethod = _PyObject_GetAttrId(file, &PyId_read);
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000963 if (readmethod == NULL) {
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000964 PyErr_SetString(PyExc_TypeError,
965 "argument must have 'read' attribute");
966 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000967 }
968 for (;;) {
969 int bytes_read;
970 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000971 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000972 Py_XDECREF(readmethod);
Ned Deilye7d532f2014-03-27 16:39:58 -0700973 return get_parse_result(self, 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000974 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000975
Benjamin Peterson4e7f2852010-08-08 16:54:58 +0000976 bytes_read = readinst(buf, BUF_SIZE, readmethod);
977 if (bytes_read < 0) {
978 Py_DECREF(readmethod);
979 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000980 }
981 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000982 if (PyErr_Occurred()) {
983 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000984 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000985 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000986
Fred Drake0582df92000-07-12 04:49:00 +0000987 if (!rv || bytes_read == 0)
988 break;
989 }
Fred Drake7b6caff2003-07-21 17:05:56 +0000990 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +0000991 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000992}
993
Brett Cannond0aeda82014-08-22 14:23:20 -0400994/*[clinic input]
995pyexpat.xmlparser.SetBase
996
997 base: str
998 /
999
1000Set the base URL for the parser.
1001[clinic start generated code]*/
1002
1003PyDoc_STRVAR(pyexpat_xmlparser_SetBase__doc__,
1004"SetBase($self, base, /)\n"
1005"--\n"
1006"\n"
1007"Set the base URL for the parser.");
1008
1009#define PYEXPAT_XMLPARSER_SETBASE_METHODDEF \
1010 {"SetBase", (PyCFunction)pyexpat_xmlparser_SetBase, METH_VARARGS, pyexpat_xmlparser_SetBase__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001011
1012static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001013pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001014
Brett Cannond0aeda82014-08-22 14:23:20 -04001015static PyObject *
1016pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *args)
1017{
1018 PyObject *return_value = NULL;
1019 const char *base;
1020
1021 if (!PyArg_ParseTuple(args,
1022 "s:SetBase",
1023 &base))
1024 goto exit;
1025 return_value = pyexpat_xmlparser_SetBase_impl(self, base);
1026
1027exit:
1028 return return_value;
1029}
1030
1031static PyObject *
1032pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base)
1033/*[clinic end generated code: output=5bdb49f6689a5f93 input=c684e5de895ee1a8]*/
1034{
Fred Drake0582df92000-07-12 04:49:00 +00001035 if (!XML_SetBase(self->itself, base)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001037 }
Brett Cannond0aeda82014-08-22 14:23:20 -04001038 Py_RETURN_NONE;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001039}
1040
Brett Cannond0aeda82014-08-22 14:23:20 -04001041/*[clinic input]
1042pyexpat.xmlparser.GetBase
1043
1044Return base URL string for the parser.
1045[clinic start generated code]*/
1046
1047PyDoc_STRVAR(pyexpat_xmlparser_GetBase__doc__,
1048"GetBase($self, /)\n"
1049"--\n"
1050"\n"
1051"Return base URL string for the parser.");
1052
1053#define PYEXPAT_XMLPARSER_GETBASE_METHODDEF \
1054 {"GetBase", (PyCFunction)pyexpat_xmlparser_GetBase, METH_NOARGS, pyexpat_xmlparser_GetBase__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001055
1056static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001057pyexpat_xmlparser_GetBase_impl(xmlparseobject *self);
1058
1059static PyObject *
1060pyexpat_xmlparser_GetBase(xmlparseobject *self, PyObject *Py_UNUSED(ignored))
1061{
1062 return pyexpat_xmlparser_GetBase_impl(self);
1063}
1064
1065static PyObject *
1066pyexpat_xmlparser_GetBase_impl(xmlparseobject *self)
1067/*[clinic end generated code: output=ef6046ee28f2b8ee input=918d71c38009620e]*/
Fred Drake0582df92000-07-12 04:49:00 +00001068{
Fred Drake0582df92000-07-12 04:49:00 +00001069 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001070}
1071
Brett Cannond0aeda82014-08-22 14:23:20 -04001072/*[clinic input]
1073pyexpat.xmlparser.GetInputContext
1074
1075Return the untranslated text of the input that caused the current event.
1076
1077If the event was generated by a large amount of text (such as a start tag
1078for an element with many attributes), not all of the text may be available.
1079[clinic start generated code]*/
1080
1081PyDoc_STRVAR(pyexpat_xmlparser_GetInputContext__doc__,
1082"GetInputContext($self, /)\n"
1083"--\n"
1084"\n"
1085"Return the untranslated text of the input that caused the current event.\n"
1086"\n"
1087"If the event was generated by a large amount of text (such as a start tag\n"
1088"for an element with many attributes), not all of the text may be available.");
1089
1090#define PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF \
1091 {"GetInputContext", (PyCFunction)pyexpat_xmlparser_GetInputContext, METH_NOARGS, pyexpat_xmlparser_GetInputContext__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001092
1093static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001094pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self);
1095
1096static PyObject *
1097pyexpat_xmlparser_GetInputContext(xmlparseobject *self, PyObject *Py_UNUSED(ignored))
1098{
1099 return pyexpat_xmlparser_GetInputContext_impl(self);
1100}
1101
1102static PyObject *
1103pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self)
1104/*[clinic end generated code: output=62ff03390f074cd2 input=034df8712db68379]*/
Fred Drakebd6101c2001-02-14 18:29:45 +00001105{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001106 if (self->in_callback) {
1107 int offset, size;
1108 const char *buffer
1109 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +00001110
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001111 if (buffer != NULL)
Christian Heimes72b710a2008-05-26 13:28:38 +00001112 return PyBytes_FromStringAndSize(buffer + offset,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001113 size - offset);
1114 else
1115 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001116 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001117 else
1118 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001119}
Fred Drakebd6101c2001-02-14 18:29:45 +00001120
Brett Cannond0aeda82014-08-22 14:23:20 -04001121/*[clinic input]
1122pyexpat.xmlparser.ExternalEntityParserCreate
1123
1124 context: str(nullable=True)
1125 encoding: str = NULL
1126 /
1127
1128Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler.
1129[clinic start generated code]*/
1130
1131PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__,
1132"ExternalEntityParserCreate($self, context, encoding=None, /)\n"
1133"--\n"
1134"\n"
1135"Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler.");
1136
1137#define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \
1138 {"ExternalEntityParserCreate", (PyCFunction)pyexpat_xmlparser_ExternalEntityParserCreate, METH_VARARGS, pyexpat_xmlparser_ExternalEntityParserCreate__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001139
1140static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001141pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, const char *context, const char *encoding);
1142
1143static PyObject *
1144pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001145{
Brett Cannond0aeda82014-08-22 14:23:20 -04001146 PyObject *return_value = NULL;
1147 const char *context;
1148 const char *encoding = NULL;
1149
1150 if (!PyArg_ParseTuple(args,
1151 "z|s:ExternalEntityParserCreate",
1152 &context, &encoding))
1153 goto exit;
1154 return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding);
1155
1156exit:
1157 return return_value;
1158}
1159
1160static PyObject *
1161pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, const char *context, const char *encoding)
1162/*[clinic end generated code: output=4948c35f3dd01133 input=283206575d960272]*/
1163{
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001164 xmlparseobject *new_parser;
1165 int i;
1166
Martin v. Löwis894258c2001-09-23 10:20:10 +00001167 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake85d835f2001-02-08 15:39:08 +00001168 if (new_parser == NULL)
1169 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001170 new_parser->buffer_size = self->buffer_size;
1171 new_parser->buffer_used = 0;
Victor Stinnerb4ba9862010-09-10 22:25:19 +00001172 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001173 new_parser->ordered_attributes = self->ordered_attributes;
1174 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001175 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001176 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001177 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 encoding);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001179 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001180 new_parser->intern = self->intern;
1181 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001182 PyObject_GC_Track(new_parser);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001183
Victor Stinnerb4ba9862010-09-10 22:25:19 +00001184 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001185 new_parser->buffer = PyMem_Malloc(new_parser->buffer_size);
Victor Stinnerb4ba9862010-09-10 22:25:19 +00001186 if (new_parser->buffer == NULL) {
1187 Py_DECREF(new_parser);
1188 return PyErr_NoMemory();
1189 }
1190 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001191 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001192 Py_DECREF(new_parser);
1193 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001194 }
1195
1196 XML_SetUserData(new_parser->itself, (void *)new_parser);
1197
1198 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001199 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001200 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001201
Victor Stinnerb6404912013-07-07 16:21:41 +02001202 new_parser->handlers = PyMem_Malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001203 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001204 Py_DECREF(new_parser);
1205 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001206 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001207 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001208
1209 /* then copy handlers from self */
1210 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001211 PyObject *handler = self->handlers[i];
1212 if (handler != NULL) {
1213 Py_INCREF(handler);
1214 new_parser->handlers[i] = handler;
1215 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001216 handler_info[i].handler);
1217 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001218 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001219 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001220}
1221
Brett Cannond0aeda82014-08-22 14:23:20 -04001222/*[clinic input]
1223pyexpat.xmlparser.SetParamEntityParsing
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001224
Brett Cannond0aeda82014-08-22 14:23:20 -04001225 flag: int
1226 /
1227
1228Controls parsing of parameter entities (including the external DTD subset).
1229
1230Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,
1231XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and
1232XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag
1233was successful.
1234[clinic start generated code]*/
1235
1236PyDoc_STRVAR(pyexpat_xmlparser_SetParamEntityParsing__doc__,
1237"SetParamEntityParsing($self, flag, /)\n"
1238"--\n"
1239"\n"
1240"Controls parsing of parameter entities (including the external DTD subset).\n"
1241"\n"
1242"Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n"
1243"XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n"
1244"XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n"
1245"was successful.");
1246
1247#define PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF \
1248 {"SetParamEntityParsing", (PyCFunction)pyexpat_xmlparser_SetParamEntityParsing, METH_VARARGS, pyexpat_xmlparser_SetParamEntityParsing__doc__},
1249
1250static PyObject *
1251pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag);
1252
1253static PyObject *
1254pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001255{
Brett Cannond0aeda82014-08-22 14:23:20 -04001256 PyObject *return_value = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001257 int flag;
Brett Cannond0aeda82014-08-22 14:23:20 -04001258
1259 if (!PyArg_ParseTuple(args,
1260 "i:SetParamEntityParsing",
1261 &flag))
1262 goto exit;
1263 return_value = pyexpat_xmlparser_SetParamEntityParsing_impl(self, flag);
1264
1265exit:
1266 return return_value;
1267}
1268
1269static PyObject *
1270pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag)
1271/*[clinic end generated code: output=0f820882bc7768cc input=8aea19b4b15e9af1]*/
1272{
1273 flag = XML_SetParamEntityParsing(self->itself, flag);
Christian Heimes217cfd12007-12-02 14:31:20 +00001274 return PyLong_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001275}
1276
Martin v. Löwisc847f402003-01-21 11:09:21 +00001277
1278#if XML_COMBINED_VERSION >= 19505
Brett Cannond0aeda82014-08-22 14:23:20 -04001279/*[clinic input]
1280pyexpat.xmlparser.UseForeignDTD
1281
1282 flag: bool = True
1283 /
1284
1285Allows the application to provide an artificial external subset if one is not specified as part of the document instance.
1286
1287This readily allows the use of a 'default' document type controlled by the
1288application, while still getting the advantage of providing document type
1289information to the parser. 'flag' defaults to True if not provided.
1290[clinic start generated code]*/
1291
1292PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__,
1293"UseForeignDTD($self, flag=True, /)\n"
1294"--\n"
1295"\n"
1296"Allows the application to provide an artificial external subset if one is not specified as part of the document instance.\n"
1297"\n"
1298"This readily allows the use of a \'default\' document type controlled by the\n"
1299"application, while still getting the advantage of providing document type\n"
1300"information to the parser. \'flag\' defaults to True if not provided.");
1301
1302#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \
1303 {"UseForeignDTD", (PyCFunction)pyexpat_xmlparser_UseForeignDTD, METH_VARARGS, pyexpat_xmlparser_UseForeignDTD__doc__},
Martin v. Löwis069dde22003-01-21 10:58:18 +00001304
1305static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001306pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag);
1307
1308static PyObject *
1309pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *args)
Martin v. Löwis069dde22003-01-21 10:58:18 +00001310{
Brett Cannond0aeda82014-08-22 14:23:20 -04001311 PyObject *return_value = NULL;
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001312 int flag = 1;
Brett Cannond0aeda82014-08-22 14:23:20 -04001313
1314 if (!PyArg_ParseTuple(args,
1315 "|p:UseForeignDTD",
1316 &flag))
1317 goto exit;
1318 return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag);
1319
1320exit:
1321 return return_value;
1322}
1323
1324static PyObject *
1325pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag)
1326/*[clinic end generated code: output=22e924ae6cad67d6 input=78144c519d116a6e]*/
1327{
Martin v. Löwis069dde22003-01-21 10:58:18 +00001328 enum XML_Error rc;
Brett Cannond0aeda82014-08-22 14:23:20 -04001329
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001330 rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);
Martin v. Löwis069dde22003-01-21 10:58:18 +00001331 if (rc != XML_ERROR_NONE) {
1332 return set_error(self, rc);
1333 }
1334 Py_INCREF(Py_None);
1335 return Py_None;
1336}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001337#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001338
Brett Cannond0aeda82014-08-22 14:23:20 -04001339/*[clinic input]
1340pyexpat.xmlparser.__dir__
1341[clinic start generated code]*/
1342
1343PyDoc_STRVAR(pyexpat_xmlparser___dir____doc__,
1344"__dir__($self, /)\n"
1345"--");
1346
1347#define PYEXPAT_XMLPARSER___DIR___METHODDEF \
1348 {"__dir__", (PyCFunction)pyexpat_xmlparser___dir__, METH_NOARGS, pyexpat_xmlparser___dir____doc__},
1349
1350static PyObject *
1351pyexpat_xmlparser___dir___impl(xmlparseobject *self);
1352
1353static PyObject *
1354pyexpat_xmlparser___dir__(xmlparseobject *self, PyObject *Py_UNUSED(ignored))
1355{
1356 return pyexpat_xmlparser___dir___impl(self);
1357}
1358
1359static PyObject *
1360pyexpat_xmlparser___dir___impl(xmlparseobject *self)
1361/*[clinic end generated code: output=1ed6efe83bc304cc input=76aa455f2a661384]*/
1362{
1363#define APPEND(list, str) \
1364 do { \
1365 PyObject *o = PyUnicode_FromString(str); \
1366 if (o != NULL) \
1367 PyList_Append(list, o); \
1368 Py_XDECREF(o); \
1369 } while (0)
1370
1371 int i;
1372 PyObject *rc = PyList_New(0);
1373 if (!rc)
1374 return NULL;
1375 for (i = 0; handler_info[i].name != NULL; i++) {
1376 PyObject *o = get_handler_name(&handler_info[i]);
1377 if (o != NULL)
1378 PyList_Append(rc, o);
1379 Py_XDECREF(o);
1380 }
1381 APPEND(rc, "ErrorCode");
1382 APPEND(rc, "ErrorLineNumber");
1383 APPEND(rc, "ErrorColumnNumber");
1384 APPEND(rc, "ErrorByteIndex");
1385 APPEND(rc, "CurrentLineNumber");
1386 APPEND(rc, "CurrentColumnNumber");
1387 APPEND(rc, "CurrentByteIndex");
1388 APPEND(rc, "buffer_size");
1389 APPEND(rc, "buffer_text");
1390 APPEND(rc, "buffer_used");
1391 APPEND(rc, "namespace_prefixes");
1392 APPEND(rc, "ordered_attributes");
1393 APPEND(rc, "specified_attributes");
1394 APPEND(rc, "intern");
1395
1396#undef APPEND
1397
1398 if (PyErr_Occurred()) {
1399 Py_DECREF(rc);
1400 rc = NULL;
1401 }
1402
1403 return rc;
1404}
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001405
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001406static struct PyMethodDef xmlparse_methods[] = {
Brett Cannond0aeda82014-08-22 14:23:20 -04001407 PYEXPAT_XMLPARSER_PARSE_METHODDEF
1408 PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF
1409 PYEXPAT_XMLPARSER_SETBASE_METHODDEF
1410 PYEXPAT_XMLPARSER_GETBASE_METHODDEF
1411 PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF
1412 PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF
1413 PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF
Martin v. Löwisc847f402003-01-21 11:09:21 +00001414#if XML_COMBINED_VERSION >= 19505
Brett Cannond0aeda82014-08-22 14:23:20 -04001415 PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
Martin v. Löwisc847f402003-01-21 11:09:21 +00001416#endif
Brett Cannond0aeda82014-08-22 14:23:20 -04001417 PYEXPAT_XMLPARSER___DIR___METHODDEF
1418 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001419};
1420
1421/* ---------- */
1422
1423
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001424
Fred Drake71b63ff2002-06-28 22:29:01 +00001425/* pyexpat international encoding support.
1426 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001427*/
1428
Fred Drake71b63ff2002-06-28 22:29:01 +00001429static int
1430PyUnknownEncodingHandler(void *encodingHandlerData,
1431 const XML_Char *name,
1432 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001433{
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001434 static unsigned char template_buffer[256] = {0};
1435 PyObject* u;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001436 int i;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001437 void *data;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001438 unsigned int kind;
Fred Drake71b63ff2002-06-28 22:29:01 +00001439
Victor Stinner9e09c262013-07-18 23:17:01 +02001440 if (PyErr_Occurred())
1441 return XML_STATUS_ERROR;
1442
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001443 if (template_buffer[1] == 0) {
1444 for (i = 0; i < 256; i++)
1445 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001446 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001447
1448 u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace");
Christian Heimesb5821552013-06-29 20:43:13 +02001449 if (u == NULL || PyUnicode_READY(u)) {
Christian Heimes72172422013-06-29 21:49:27 +02001450 Py_XDECREF(u);
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001451 return XML_STATUS_ERROR;
Christian Heimesb5821552013-06-29 20:43:13 +02001452 }
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001453
1454 if (PyUnicode_GET_LENGTH(u) != 256) {
1455 Py_DECREF(u);
1456 PyErr_SetString(PyExc_ValueError,
1457 "multi-byte encodings are not supported");
1458 return XML_STATUS_ERROR;
1459 }
1460
1461 kind = PyUnicode_KIND(u);
1462 data = PyUnicode_DATA(u);
1463 for (i = 0; i < 256; i++) {
1464 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
1465 if (ch != Py_UNICODE_REPLACEMENT_CHARACTER)
1466 info->map[i] = ch;
1467 else
1468 info->map[i] = -1;
1469 }
1470
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001471 info->data = NULL;
1472 info->convert = NULL;
1473 info->release = NULL;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07001474 Py_DECREF(u);
1475
1476 return XML_STATUS_OK;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001477}
1478
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001479
1480static PyObject *
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001481newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001482{
1483 int i;
1484 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001485
Martin v. Löwis894258c2001-09-23 10:20:10 +00001486 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
Fred Drake0582df92000-07-12 04:49:00 +00001487 if (self == NULL)
1488 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001489
Fred Drake2a3d7db2002-06-28 22:56:48 +00001490 self->buffer = NULL;
1491 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1492 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001493 self->ordered_attributes = 0;
1494 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001495 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001496 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001497 self->handlers = NULL;
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001498 self->intern = intern;
1499 Py_XINCREF(self->intern);
1500 PyObject_GC_Track(self);
1501
Christian Heimesfa535f52013-07-07 17:35:11 +02001502 /* namespace_separator is either NULL or contains one char + \0 */
1503 self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler,
1504 namespace_separator);
Victor Stinner54b2d2e2013-07-15 17:15:57 +02001505 if (self->itself == NULL) {
1506 PyErr_SetString(PyExc_RuntimeError,
1507 "XML_ParserCreate failed");
1508 Py_DECREF(self);
1509 return NULL;
1510 }
Gregory P. Smith25227712012-03-14 18:10:37 -07001511#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)
1512 /* This feature was added upstream in libexpat 2.1.0. Our expat copy
1513 * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
1514 * to indicate that we can still use it. */
Gregory P. Smith8e91cf62012-03-14 14:26:55 -07001515 XML_SetHashSalt(self->itself,
Christian Heimes985ecdc2013-11-20 11:46:18 +01001516 (unsigned long)_Py_HashSecret.expat.hashsalt);
Gregory P. Smith25227712012-03-14 18:10:37 -07001517#endif
Fred Drake0582df92000-07-12 04:49:00 +00001518 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001519 XML_SetUnknownEncodingHandler(self->itself,
1520 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001521
Fred Drake2a3d7db2002-06-28 22:56:48 +00001522 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001523 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001524
Victor Stinnerb6404912013-07-07 16:21:41 +02001525 self->handlers = PyMem_Malloc(sizeof(PyObject *) * i);
Fred Drake7c75bf22002-07-01 14:02:31 +00001526 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001527 Py_DECREF(self);
1528 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001529 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001530 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001531
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001532 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001533}
1534
1535
1536static void
Fred Drake0582df92000-07-12 04:49:00 +00001537xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001538{
Fred Drake0582df92000-07-12 04:49:00 +00001539 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001540 PyObject_GC_UnTrack(self);
Fred Drake85d835f2001-02-08 15:39:08 +00001541 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001542 XML_ParserFree(self->itself);
1543 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001544
Fred Drake85d835f2001-02-08 15:39:08 +00001545 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001546 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001547 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001548 temp = self->handlers[i];
1549 self->handlers[i] = NULL;
1550 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001551 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001552 PyMem_Free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001553 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001554 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001555 if (self->buffer != NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001556 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001557 self->buffer = NULL;
1558 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001559 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001560 PyObject_GC_Del(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001561}
1562
Fred Drake0582df92000-07-12 04:49:00 +00001563static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001564handlername2int(PyObject *name)
Fred Drake0582df92000-07-12 04:49:00 +00001565{
1566 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001567 for (i = 0; handler_info[i].name != NULL; i++) {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001568 if (PyUnicode_CompareWithASCIIString(
1569 name, handler_info[i].name) == 0) {
Fred Drake0582df92000-07-12 04:49:00 +00001570 return i;
1571 }
1572 }
1573 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001574}
1575
1576static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001577get_pybool(int istrue)
1578{
1579 PyObject *result = istrue ? Py_True : Py_False;
1580 Py_INCREF(result);
1581 return result;
1582}
1583
1584static PyObject *
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001585xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001586{
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001587 Py_UCS4 first_char;
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001588 int handlernum = -1;
1589
Alexander Belopolskye239d232010-12-08 23:31:48 +00001590 if (!PyUnicode_Check(nameobj))
1591 goto generic;
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001592 if (PyUnicode_READY(nameobj))
1593 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594
Alexander Belopolskye239d232010-12-08 23:31:48 +00001595 handlernum = handlername2int(nameobj);
Fred Drake71b63ff2002-06-28 22:29:01 +00001596
1597 if (handlernum != -1) {
1598 PyObject *result = self->handlers[handlernum];
1599 if (result == NULL)
1600 result = Py_None;
1601 Py_INCREF(result);
1602 return result;
1603 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001604
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001605 first_char = PyUnicode_READ_CHAR(nameobj, 0);
1606 if (first_char == 'E') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001607 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorCode") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001608 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001609 XML_GetErrorCode(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001610 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001611 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001612 XML_GetErrorLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001613 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001614 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001615 XML_GetErrorColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001616 if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001617 return PyLong_FromLong((long)
Fred Drake71b63ff2002-06-28 22:29:01 +00001618 XML_GetErrorByteIndex(self->itself));
1619 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001620 if (first_char == 'C') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001621 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentLineNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001622 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001623 XML_GetCurrentLineNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001624 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentColumnNumber") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001625 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001626 XML_GetCurrentColumnNumber(self->itself));
Alexander Belopolskye239d232010-12-08 23:31:48 +00001627 if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentByteIndex") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001628 return PyLong_FromLong((long)
Dave Cole3203efb2004-08-26 00:37:31 +00001629 XML_GetCurrentByteIndex(self->itself));
1630 }
Victor Stinner9e5bd6c2011-10-01 01:05:40 +02001631 if (first_char == 'b') {
Alexander Belopolskye239d232010-12-08 23:31:48 +00001632 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_size") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001633 return PyLong_FromLong((long) self->buffer_size);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001634 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_text") == 0)
Fred Drake2a3d7db2002-06-28 22:56:48 +00001635 return get_pybool(self->buffer != NULL);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001636 if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_used") == 0)
Christian Heimes217cfd12007-12-02 14:31:20 +00001637 return PyLong_FromLong((long) self->buffer_used);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001638 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001639 if (PyUnicode_CompareWithASCIIString(nameobj, "namespace_prefixes") == 0)
Martin v. Löwis069dde22003-01-21 10:58:18 +00001640 return get_pybool(self->ns_prefixes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001641 if (PyUnicode_CompareWithASCIIString(nameobj, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001642 return get_pybool(self->ordered_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001643 if (PyUnicode_CompareWithASCIIString(nameobj, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001644 return get_pybool((long) self->specified_attributes);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001645 if (PyUnicode_CompareWithASCIIString(nameobj, "intern") == 0) {
Fred Drakeb91a36b2002-06-27 19:40:48 +00001646 if (self->intern == NULL) {
1647 Py_INCREF(Py_None);
1648 return Py_None;
1649 }
1650 else {
1651 Py_INCREF(self->intern);
1652 return self->intern;
1653 }
1654 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001655 generic:
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00001656 return PyObject_GenericGetAttr((PyObject*)self, nameobj);
Neal Norwitz8dfc4a92007-08-11 06:39:53 +00001657}
1658
Fred Drake6f987622000-08-25 18:03:30 +00001659static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001660sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001661{
1662 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001663 if (handlernum >= 0) {
1664 xmlhandler c_handler = NULL;
1665 PyObject *temp = self->handlers[handlernum];
1666
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001667 if (v == Py_None) {
1668 /* If this is the character data handler, and a character
1669 data handler is already active, we need to be more
1670 careful. What we can safely do is replace the existing
1671 character data handler callback function with a no-op
1672 function that will refuse to call Python. The downside
1673 is that this doesn't completely remove the character
1674 data handler from the C layer if there's any callback
1675 active, so Expat does a little more work than it
1676 otherwise would, but that's really an odd case. A more
1677 elaborate system of handlers and state could remove the
1678 C handler more effectively. */
1679 if (handlernum == CharacterData && self->in_callback)
1680 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001681 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001682 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001683 else if (v != NULL) {
1684 Py_INCREF(v);
1685 c_handler = handler_info[handlernum].handler;
1686 }
Fred Drake0582df92000-07-12 04:49:00 +00001687 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001688 Py_XDECREF(temp);
1689 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001690 return 1;
1691 }
1692 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001693}
1694
1695static int
Alexander Belopolskye239d232010-12-08 23:31:48 +00001696xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001697{
Fred Drake6f987622000-08-25 18:03:30 +00001698 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001699 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001700 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1701 return -1;
1702 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001703 assert(PyUnicode_Check(name));
1704 if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001705 int b = PyObject_IsTrue(v);
1706 if (b < 0)
1707 return -1;
1708 if (b) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001709 if (self->buffer == NULL) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001710 self->buffer = PyMem_Malloc(self->buffer_size);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001711 if (self->buffer == NULL) {
1712 PyErr_NoMemory();
1713 return -1;
1714 }
1715 self->buffer_used = 0;
1716 }
1717 }
1718 else if (self->buffer != NULL) {
1719 if (flush_character_buffer(self) < 0)
1720 return -1;
Victor Stinnerb6404912013-07-07 16:21:41 +02001721 PyMem_Free(self->buffer);
Fred Drake2a3d7db2002-06-28 22:56:48 +00001722 self->buffer = NULL;
1723 }
1724 return 0;
1725 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001726 if (PyUnicode_CompareWithASCIIString(name, "namespace_prefixes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001727 int b = PyObject_IsTrue(v);
1728 if (b < 0)
1729 return -1;
1730 self->ns_prefixes = b;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001731 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1732 return 0;
1733 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001734 if (PyUnicode_CompareWithASCIIString(name, "ordered_attributes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001735 int b = PyObject_IsTrue(v);
1736 if (b < 0)
1737 return -1;
1738 self->ordered_attributes = b;
Fred Drake85d835f2001-02-08 15:39:08 +00001739 return 0;
1740 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001741 if (PyUnicode_CompareWithASCIIString(name, "specified_attributes") == 0) {
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001742 int b = PyObject_IsTrue(v);
1743 if (b < 0)
1744 return -1;
1745 self->specified_attributes = b;
Fred Drake6f987622000-08-25 18:03:30 +00001746 return 0;
1747 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001748
Alexander Belopolskye239d232010-12-08 23:31:48 +00001749 if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
Christian Heimes2380ac72008-01-09 00:17:24 +00001750 long new_buffer_size;
1751 if (!PyLong_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
1753 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001754 }
1755
1756 new_buffer_size=PyLong_AS_LONG(v);
1757 /* trivial case -- no change */
1758 if (new_buffer_size == self->buffer_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 return 0;
Christian Heimes2380ac72008-01-09 00:17:24 +00001760 }
1761
1762 if (new_buffer_size <= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
1764 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001765 }
1766
1767 /* check maximum */
1768 if (new_buffer_size > INT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 char errmsg[100];
1770 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
1771 PyErr_SetString(PyExc_ValueError, errmsg);
1772 return -1;
Christian Heimes2380ac72008-01-09 00:17:24 +00001773 }
1774
1775 if (self->buffer != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 /* there is already a buffer */
1777 if (self->buffer_used != 0) {
Christian Heimes09994a92013-07-20 22:41:58 +02001778 if (flush_character_buffer(self) < 0) {
1779 return -1;
1780 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 }
1782 /* free existing buffer */
Victor Stinnerb6404912013-07-07 16:21:41 +02001783 PyMem_Free(self->buffer);
Christian Heimes2380ac72008-01-09 00:17:24 +00001784 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001785 self->buffer = PyMem_Malloc(new_buffer_size);
Christian Heimes2380ac72008-01-09 00:17:24 +00001786 if (self->buffer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 PyErr_NoMemory();
1788 return -1;
1789 }
Christian Heimes2380ac72008-01-09 00:17:24 +00001790 self->buffer_size = new_buffer_size;
1791 return 0;
1792 }
1793
Alexander Belopolskye239d232010-12-08 23:31:48 +00001794 if (PyUnicode_CompareWithASCIIString(name, "CharacterDataHandler") == 0) {
Fred Drake2a3d7db2002-06-28 22:56:48 +00001795 /* If we're changing the character data handler, flush all
1796 * cached data with the old handler. Not sure there's a
1797 * "right" thing to do, though, but this probably won't
1798 * happen.
1799 */
1800 if (flush_character_buffer(self) < 0)
1801 return -1;
1802 }
Fred Drake6f987622000-08-25 18:03:30 +00001803 if (sethandler(self, name, v)) {
1804 return 0;
1805 }
Alexander Belopolskye239d232010-12-08 23:31:48 +00001806 PyErr_SetObject(PyExc_AttributeError, name);
Fred Drake6f987622000-08-25 18:03:30 +00001807 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001808}
1809
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001810static int
1811xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1812{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001813 int i;
1814 for (i = 0; handler_info[i].name != NULL; i++)
1815 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001816 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001817}
1818
1819static int
1820xmlparse_clear(xmlparseobject *op)
1821{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001822 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001823 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001824 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001825}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001828
1829static PyTypeObject Xmlparsetype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 PyVarObject_HEAD_INIT(NULL, 0)
1831 "pyexpat.xmlparser", /*tp_name*/
Antoine Pitrou23683ef2011-01-04 00:00:31 +00001832 sizeof(xmlparseobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 0, /*tp_itemsize*/
1834 /* methods */
1835 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1836 (printfunc)0, /*tp_print*/
1837 0, /*tp_getattr*/
Alexander Belopolskye239d232010-12-08 23:31:48 +00001838 0, /*tp_setattr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 0, /*tp_reserved*/
1840 (reprfunc)0, /*tp_repr*/
1841 0, /*tp_as_number*/
1842 0, /*tp_as_sequence*/
1843 0, /*tp_as_mapping*/
1844 (hashfunc)0, /*tp_hash*/
1845 (ternaryfunc)0, /*tp_call*/
1846 (reprfunc)0, /*tp_str*/
1847 (getattrofunc)xmlparse_getattro, /* tp_getattro */
Alexander Belopolskye239d232010-12-08 23:31:48 +00001848 (setattrofunc)xmlparse_setattro, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 0, /* tp_as_buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 Xmlparsetype__doc__, /* tp_doc - Documentation string */
1852 (traverseproc)xmlparse_traverse, /* tp_traverse */
1853 (inquiry)xmlparse_clear, /* tp_clear */
1854 0, /* tp_richcompare */
1855 0, /* tp_weaklistoffset */
1856 0, /* tp_iter */
1857 0, /* tp_iternext */
1858 xmlparse_methods, /* tp_methods */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001859};
1860
1861/* End of code for xmlparser objects */
1862/* -------------------------------------------------------- */
1863
Brett Cannond0aeda82014-08-22 14:23:20 -04001864/*[clinic input]
1865pyexpat.ParserCreate
1866
1867 encoding: str(nullable=True) = NULL
1868 namespace_separator: str(nullable=True) = NULL
1869 intern: object = NULL
1870
1871Return a new XML parser object.
1872[clinic start generated code]*/
1873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001874PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Brett Cannond0aeda82014-08-22 14:23:20 -04001875"ParserCreate($module, /, encoding=None, namespace_separator=None,\n"
1876" intern=None)\n"
1877"--\n"
1878"\n"
1879"Return a new XML parser object.");
1880
1881#define PYEXPAT_PARSERCREATE_METHODDEF \
1882 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate, METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001883
1884static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001885pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, const char *namespace_separator, PyObject *intern);
1886
1887static PyObject *
1888pyexpat_ParserCreate(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Fred Drake0582df92000-07-12 04:49:00 +00001889{
Brett Cannond0aeda82014-08-22 14:23:20 -04001890 PyObject *return_value = NULL;
1891 static char *_keywords[] = {"encoding", "namespace_separator", "intern", NULL};
1892 const char *encoding = NULL;
1893 const char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001894 PyObject *intern = NULL;
Brett Cannond0aeda82014-08-22 14:23:20 -04001895
1896 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1897 "|zzO:ParserCreate", _keywords,
1898 &encoding, &namespace_separator, &intern))
1899 goto exit;
1900 return_value = pyexpat_ParserCreate_impl(module, encoding, namespace_separator, intern);
1901
1902exit:
1903 return return_value;
1904}
1905
1906static PyObject *
1907pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, const char *namespace_separator, PyObject *intern)
1908/*[clinic end generated code: output=4fc027dd33b7a2ac input=71b9f471aa6f8f86]*/
1909{
Fred Drakeb91a36b2002-06-27 19:40:48 +00001910 PyObject *result;
1911 int intern_decref = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001912
Fred Drakecde79132001-04-25 16:01:30 +00001913 if (namespace_separator != NULL
1914 && strlen(namespace_separator) > 1) {
1915 PyErr_SetString(PyExc_ValueError,
1916 "namespace_separator must be at most one"
1917 " character, omitted, or None");
1918 return NULL;
1919 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001920 /* Explicitly passing None means no interning is desired.
1921 Not passing anything means that a new dictionary is used. */
1922 if (intern == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 intern = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001924 else if (intern == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 intern = PyDict_New();
1926 if (!intern)
1927 return NULL;
1928 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001929 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001930 else if (!PyDict_Check(intern)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1932 return NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001933 }
1934
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03001935 result = newxmlparseobject(encoding, namespace_separator, intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001936 if (intern_decref) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 Py_DECREF(intern);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001938 }
1939 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001940}
1941
Brett Cannond0aeda82014-08-22 14:23:20 -04001942/*[clinic input]
1943pyexpat.ErrorString
1944
1945 code: long
1946 /
1947
1948Returns string error for given number.
1949[clinic start generated code]*/
1950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Brett Cannond0aeda82014-08-22 14:23:20 -04001952"ErrorString($module, code, /)\n"
1953"--\n"
1954"\n"
1955"Returns string error for given number.");
1956
1957#define PYEXPAT_ERRORSTRING_METHODDEF \
1958 {"ErrorString", (PyCFunction)pyexpat_ErrorString, METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001959
1960static PyObject *
Brett Cannond0aeda82014-08-22 14:23:20 -04001961pyexpat_ErrorString_impl(PyModuleDef *module, long code);
Fred Drake0582df92000-07-12 04:49:00 +00001962
Brett Cannond0aeda82014-08-22 14:23:20 -04001963static PyObject *
1964pyexpat_ErrorString(PyModuleDef *module, PyObject *args)
1965{
1966 PyObject *return_value = NULL;
1967 long code;
1968
1969 if (!PyArg_ParseTuple(args,
1970 "l:ErrorString",
1971 &code))
1972 goto exit;
1973 return_value = pyexpat_ErrorString_impl(module, code);
1974
1975exit:
1976 return return_value;
1977}
1978
1979static PyObject *
1980pyexpat_ErrorString_impl(PyModuleDef *module, long code)
1981/*[clinic end generated code: output=c70f3cd82bfaf067 input=cc67de010d9e62b3]*/
1982{
Fred Drake0582df92000-07-12 04:49:00 +00001983 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001984}
1985
1986/* List of methods defined in the module */
1987
1988static struct PyMethodDef pyexpat_methods[] = {
Brett Cannond0aeda82014-08-22 14:23:20 -04001989 PYEXPAT_PARSERCREATE_METHODDEF
1990 PYEXPAT_ERRORSTRING_METHODDEF
1991 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001992};
1993
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001994/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996PyDoc_STRVAR(pyexpat_module_documentation,
1997"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001998
Fred Drakecde79132001-04-25 16:01:30 +00001999/* Initialization function for the module */
2000
2001#ifndef MODULE_NAME
2002#define MODULE_NAME "pyexpat"
2003#endif
2004
2005#ifndef MODULE_INITFUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002006#define MODULE_INITFUNC PyInit_pyexpat
Fred Drakecde79132001-04-25 16:01:30 +00002007#endif
2008
Martin v. Löwis069dde22003-01-21 10:58:18 +00002009#ifndef PyMODINIT_FUNC
2010# ifdef MS_WINDOWS
2011# define PyMODINIT_FUNC __declspec(dllexport) void
2012# else
2013# define PyMODINIT_FUNC void
2014# endif
2015#endif
2016
Mark Hammond8235ea12002-07-19 06:55:41 +00002017PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00002018
Martin v. Löwis1a214512008-06-11 05:26:20 +00002019static struct PyModuleDef pyexpatmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 PyModuleDef_HEAD_INIT,
2021 MODULE_NAME,
2022 pyexpat_module_documentation,
2023 -1,
2024 pyexpat_methods,
2025 NULL,
2026 NULL,
2027 NULL,
2028 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002029};
2030
Martin v. Löwis069dde22003-01-21 10:58:18 +00002031PyMODINIT_FUNC
2032MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00002033{
2034 PyObject *m, *d;
Neal Norwitz392c5be2007-08-25 17:20:32 +00002035 PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00002036 PyObject *errors_module;
2037 PyObject *modelmod_name;
2038 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00002039 PyObject *sys_modules;
Georg Brandlb4dac712010-10-15 14:46:48 +00002040 PyObject *tmpnum, *tmpstr;
2041 PyObject *codes_dict;
2042 PyObject *rev_codes_dict;
2043 int res;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002044 static struct PyExpat_CAPI capi;
Georg Brandlb4dac712010-10-15 14:46:48 +00002045 PyObject *capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002046
Fred Drake6f987622000-08-25 18:03:30 +00002047 if (errmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002048 return NULL;
Neal Norwitz392c5be2007-08-25 17:20:32 +00002049 modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00002050 if (modelmod_name == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002051 return NULL;
Fred Drake6f987622000-08-25 18:03:30 +00002052
Amaury Forgeot d'Arcba4105c2008-07-02 21:41:01 +00002053 if (PyType_Ready(&Xmlparsetype) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002055
Fred Drake0582df92000-07-12 04:49:00 +00002056 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00002057 m = PyModule_Create(&pyexpatmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00002058 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002060
Fred Drake0582df92000-07-12 04:49:00 +00002061 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00002062 if (ErrorObject == NULL) {
2063 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00002064 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00002065 if (ErrorObject == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002066 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00002067 }
2068 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00002069 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00002070 Py_INCREF(ErrorObject);
2071 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00002072 Py_INCREF(&Xmlparsetype);
2073 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002074
Fred Drake738293d2000-12-21 17:25:07 +00002075 PyModule_AddStringConstant(m, "EXPAT_VERSION",
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03002076 XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00002077 {
2078 XML_Expat_Version info = XML_ExpatVersionInfo();
2079 PyModule_AddObject(m, "version_info",
2080 Py_BuildValue("(iii)", info.major,
2081 info.minor, info.micro));
2082 }
Fred Drake0582df92000-07-12 04:49:00 +00002083 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00002084 compiled, this should check and set native_encoding
2085 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00002086 */
Fred Drake93adb692000-09-23 04:55:48 +00002087 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00002088
Fred Drake85d835f2001-02-08 15:39:08 +00002089 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00002090 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00002091 errors_module = PyDict_GetItem(d, errmod_name);
2092 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00002093 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00002094 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00002095 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00002096 /* gives away the reference to errors_module */
2097 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00002098 }
2099 }
Fred Drake6f987622000-08-25 18:03:30 +00002100 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00002101 model_module = PyDict_GetItem(d, modelmod_name);
2102 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00002103 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00002104 if (model_module != NULL) {
2105 PyDict_SetItem(sys_modules, modelmod_name, model_module);
2106 /* gives away the reference to model_module */
2107 PyModule_AddObject(m, "model", model_module);
2108 }
2109 }
2110 Py_DECREF(modelmod_name);
2111 if (errors_module == NULL || model_module == NULL)
2112 /* Don't core dump later! */
Martin v. Löwis1a214512008-06-11 05:26:20 +00002113 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114
Martin v. Löwisc847f402003-01-21 11:09:21 +00002115#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00002116 {
2117 const XML_Feature *features = XML_GetFeatureList();
2118 PyObject *list = PyList_New(0);
2119 if (list == NULL)
2120 /* just ignore it */
2121 PyErr_Clear();
2122 else {
2123 int i = 0;
2124 for (; features[i].feature != XML_FEATURE_END; ++i) {
2125 int ok;
2126 PyObject *item = Py_BuildValue("si", features[i].name,
2127 features[i].value);
2128 if (item == NULL) {
2129 Py_DECREF(list);
2130 list = NULL;
2131 break;
2132 }
2133 ok = PyList_Append(list, item);
2134 Py_DECREF(item);
2135 if (ok < 0) {
2136 PyErr_Clear();
2137 break;
2138 }
2139 }
2140 if (list != NULL)
2141 PyModule_AddObject(m, "features", list);
2142 }
2143 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00002144#endif
Fred Drake6f987622000-08-25 18:03:30 +00002145
Georg Brandlb4dac712010-10-15 14:46:48 +00002146 codes_dict = PyDict_New();
2147 rev_codes_dict = PyDict_New();
2148 if (codes_dict == NULL || rev_codes_dict == NULL) {
2149 Py_XDECREF(codes_dict);
2150 Py_XDECREF(rev_codes_dict);
2151 return NULL;
2152 }
Victor Stinner0fcab4a2011-01-04 12:59:15 +00002153
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002154#define MYCONST(name) \
Georg Brandlb4dac712010-10-15 14:46:48 +00002155 if (PyModule_AddStringConstant(errors_module, #name, \
Serhiy Storchaka20b39b22014-09-28 11:27:24 +03002156 XML_ErrorString(name)) < 0) \
Georg Brandlb4dac712010-10-15 14:46:48 +00002157 return NULL; \
2158 tmpnum = PyLong_FromLong(name); \
2159 if (tmpnum == NULL) return NULL; \
2160 res = PyDict_SetItemString(codes_dict, \
2161 XML_ErrorString(name), tmpnum); \
2162 if (res < 0) return NULL; \
2163 tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \
2164 if (tmpstr == NULL) return NULL; \
2165 res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \
2166 Py_DECREF(tmpstr); \
2167 Py_DECREF(tmpnum); \
2168 if (res < 0) return NULL; \
Fred Drake7bd9f412000-07-04 23:51:31 +00002169
Fred Drake0582df92000-07-12 04:49:00 +00002170 MYCONST(XML_ERROR_NO_MEMORY);
2171 MYCONST(XML_ERROR_SYNTAX);
2172 MYCONST(XML_ERROR_NO_ELEMENTS);
2173 MYCONST(XML_ERROR_INVALID_TOKEN);
2174 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
2175 MYCONST(XML_ERROR_PARTIAL_CHAR);
2176 MYCONST(XML_ERROR_TAG_MISMATCH);
2177 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
2178 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
2179 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
2180 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
2181 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
2182 MYCONST(XML_ERROR_ASYNC_ENTITY);
2183 MYCONST(XML_ERROR_BAD_CHAR_REF);
2184 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
2185 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
2186 MYCONST(XML_ERROR_MISPLACED_XML_PI);
2187 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
2188 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002189 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
2190 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
2191 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00002192 MYCONST(XML_ERROR_UNEXPECTED_STATE);
2193 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
2194 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
2195 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
2196 /* Added in Expat 1.95.7. */
2197 MYCONST(XML_ERROR_UNBOUND_PREFIX);
2198 /* Added in Expat 1.95.8. */
2199 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
2200 MYCONST(XML_ERROR_INCOMPLETE_PE);
2201 MYCONST(XML_ERROR_XML_DECL);
2202 MYCONST(XML_ERROR_TEXT_DECL);
2203 MYCONST(XML_ERROR_PUBLICID);
2204 MYCONST(XML_ERROR_SUSPENDED);
2205 MYCONST(XML_ERROR_NOT_SUSPENDED);
2206 MYCONST(XML_ERROR_ABORTED);
2207 MYCONST(XML_ERROR_FINISHED);
2208 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002209
Georg Brandlb4dac712010-10-15 14:46:48 +00002210 if (PyModule_AddStringConstant(errors_module, "__doc__",
2211 "Constants used to describe "
2212 "error conditions.") < 0)
2213 return NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00002214
Georg Brandlb4dac712010-10-15 14:46:48 +00002215 if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0)
2216 return NULL;
2217 if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0)
2218 return NULL;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00002219
Fred Drake93adb692000-09-23 04:55:48 +00002220#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002221
Fred Drake85d835f2001-02-08 15:39:08 +00002222#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002223 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
2224 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
2225 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00002226#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002227
Fred Drake85d835f2001-02-08 15:39:08 +00002228#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
2229 PyModule_AddStringConstant(model_module, "__doc__",
2230 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002231
Fred Drake85d835f2001-02-08 15:39:08 +00002232 MYCONST(XML_CTYPE_EMPTY);
2233 MYCONST(XML_CTYPE_ANY);
2234 MYCONST(XML_CTYPE_MIXED);
2235 MYCONST(XML_CTYPE_NAME);
2236 MYCONST(XML_CTYPE_CHOICE);
2237 MYCONST(XML_CTYPE_SEQ);
2238
2239 MYCONST(XML_CQUANT_NONE);
2240 MYCONST(XML_CQUANT_OPT);
2241 MYCONST(XML_CQUANT_REP);
2242 MYCONST(XML_CQUANT_PLUS);
2243#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00002244
2245 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002246 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002247 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002248 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
2249 capi.MINOR_VERSION = XML_MINOR_VERSION;
2250 capi.MICRO_VERSION = XML_MICRO_VERSION;
2251 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00002252 capi.GetErrorCode = XML_GetErrorCode;
2253 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
2254 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002255 capi.Parse = XML_Parse;
2256 capi.ParserCreate_MM = XML_ParserCreate_MM;
2257 capi.ParserFree = XML_ParserFree;
2258 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
2259 capi.SetCommentHandler = XML_SetCommentHandler;
2260 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
2261 capi.SetElementHandler = XML_SetElementHandler;
2262 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
2263 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
2264 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
2265 capi.SetUserData = XML_SetUserData;
Eli Bendersky2b6b73e2012-06-01 11:32:34 +03002266 capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
Serhiy Storchaka66d53fa2013-05-22 17:07:51 +03002267 capi.SetEncoding = XML_SetEncoding;
Eli Bendersky6dc32b32013-05-25 05:25:48 -07002268 capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269
Benjamin Petersonb173f782009-05-05 22:31:58 +00002270 /* export using capsule */
2271 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00002272 if (capi_object)
2273 PyModule_AddObject(m, "expat_CAPI", capi_object);
Martin v. Löwis1a214512008-06-11 05:26:20 +00002274 return m;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002275}
2276
Fred Drake6f987622000-08-25 18:03:30 +00002277static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002278clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00002279{
Fred Drakecde79132001-04-25 16:01:30 +00002280 int i = 0;
2281 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002282
Fred Drake71b63ff2002-06-28 22:29:01 +00002283 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002284 if (initial)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 self->handlers[i] = NULL;
2286 else {
Fred Drakecde79132001-04-25 16:01:30 +00002287 temp = self->handlers[i];
2288 self->handlers[i] = NULL;
2289 Py_XDECREF(temp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002291 }
Fred Drakecde79132001-04-25 16:01:30 +00002292 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002293}
2294
Tim Peters0c322792002-07-17 16:49:03 +00002295static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002296 {"StartElementHandler",
2297 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002298 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002299 {"EndElementHandler",
2300 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002301 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002302 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002303 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2304 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002305 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002306 (xmlhandlersetter)XML_SetCharacterDataHandler,
2307 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002308 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002309 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002310 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002311 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002312 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002313 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002314 {"StartNamespaceDeclHandler",
2315 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002316 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002317 {"EndNamespaceDeclHandler",
2318 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002319 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002320 {"CommentHandler",
2321 (xmlhandlersetter)XML_SetCommentHandler,
2322 (xmlhandler)my_CommentHandler},
2323 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002324 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002325 (xmlhandler)my_StartCdataSectionHandler},
2326 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002327 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002328 (xmlhandler)my_EndCdataSectionHandler},
2329 {"DefaultHandler",
2330 (xmlhandlersetter)XML_SetDefaultHandler,
2331 (xmlhandler)my_DefaultHandler},
2332 {"DefaultHandlerExpand",
2333 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2334 (xmlhandler)my_DefaultHandlerExpandHandler},
2335 {"NotStandaloneHandler",
2336 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2337 (xmlhandler)my_NotStandaloneHandler},
2338 {"ExternalEntityRefHandler",
2339 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002340 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002341 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002342 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002343 (xmlhandler)my_StartDoctypeDeclHandler},
2344 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002345 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002346 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002347 {"EntityDeclHandler",
2348 (xmlhandlersetter)XML_SetEntityDeclHandler,
2349 (xmlhandler)my_EntityDeclHandler},
2350 {"XmlDeclHandler",
2351 (xmlhandlersetter)XML_SetXmlDeclHandler,
2352 (xmlhandler)my_XmlDeclHandler},
2353 {"ElementDeclHandler",
2354 (xmlhandlersetter)XML_SetElementDeclHandler,
2355 (xmlhandler)my_ElementDeclHandler},
2356 {"AttlistDeclHandler",
2357 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2358 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002359#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002360 {"SkippedEntityHandler",
2361 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2362 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002363#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002364
Fred Drake0582df92000-07-12 04:49:00 +00002365 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002366};
Brett Cannond0aeda82014-08-22 14:23:20 -04002367
2368/*[clinic input]
2369dump buffer
2370[clinic start generated code]*/
2371
2372#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
2373 #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
2374#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */
2375/*[clinic end generated code: output=a7880cb78bbd58ce input=524ce2e021e4eba6]*/