blob: c583edf28fb2a319b416bc96632ba0396bcadeb2 [file] [log] [blame]
Martin v. Löwis7090ed12001-09-19 10:37:50 +00001#include "Python.h"
Fred Drake4113b132001-03-24 19:58:26 +00002#include <ctype.h>
3
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00004#include "frameobject.h"
Fred Drakea77254a2000-09-29 19:23:29 +00005#include "expat.h"
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00006
Fredrik Lundhc3345042005-12-13 19:49:55 +00007#include "pyexpat.h"
8
Martin v. Löwisc847f402003-01-21 11:09:21 +00009#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
10
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000011#ifndef PyDoc_STRVAR
Martin v. Löwis069dde22003-01-21 10:58:18 +000012
13/*
14 * fdrake says:
15 * Don't change the PyDoc_STR macro definition to (str), because
16 * '''the parentheses cause compile failures
17 * ("non-constant static initializer" or something like that)
18 * on some platforms (Irix?)'''
19 */
Fred Drakef57b22a2002-09-02 15:54:06 +000020#define PyDoc_STR(str) str
Fred Drake7c75bf22002-07-01 14:02:31 +000021#define PyDoc_VAR(name) static char name[]
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000022#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000023#endif
24
Jeremy Hylton9263f572003-06-27 16:13:17 +000025#define FIX_TRACE
Martin v. Löwis339d0f72001-08-17 18:39:25 +000026
Fred Drake0582df92000-07-12 04:49:00 +000027enum HandlerTypes {
28 StartElement,
29 EndElement,
30 ProcessingInstruction,
31 CharacterData,
32 UnparsedEntityDecl,
33 NotationDecl,
34 StartNamespaceDecl,
35 EndNamespaceDecl,
36 Comment,
37 StartCdataSection,
38 EndCdataSection,
39 Default,
40 DefaultHandlerExpand,
41 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000042 ExternalEntityRef,
43 StartDoctypeDecl,
44 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000045 EntityDecl,
46 XmlDecl,
47 ElementDecl,
48 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000049#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000050 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000051#endif
Fred Drake85d835f2001-02-08 15:39:08 +000052 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000053};
54
55static PyObject *ErrorObject;
56
57/* ----------------------------------------------------- */
58
59/* Declarations for objects of type xmlparser */
60
61typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000062 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000063
Fred Drake0582df92000-07-12 04:49:00 +000064 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000065 int returns_unicode; /* True if Unicode strings are returned;
66 if false, UTF-8 strings are returned */
67 int ordered_attributes; /* Return attributes as a list. */
68 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000069 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000070 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000071 XML_Char *buffer; /* Buffer used when accumulating characters */
72 /* NULL if not enabled */
73 int buffer_size; /* Size of buffer, in XML_Char units */
74 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000075 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000076 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000077} xmlparseobject;
78
Fred Drake2a3d7db2002-06-28 22:56:48 +000079#define CHARACTER_DATA_BUFFER_SIZE 8192
80
Jeremy Hylton938ace62002-07-17 16:30:39 +000081static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000082
Fred Drake117ac852002-09-24 16:24:54 +000083typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000084typedef void* xmlhandler;
85
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000086struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000087 const char *name;
88 xmlhandlersetter setter;
89 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000090 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000091 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000092};
93
Jeremy Hylton938ace62002-07-17 16:30:39 +000094static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000095
Fred Drakebd6101c2001-02-14 18:29:45 +000096/* Set an integer attribute on the error object; return true on success,
97 * false on an exception.
98 */
99static int
100set_error_attr(PyObject *err, char *name, int value)
101{
102 PyObject *v = PyInt_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +0000103
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000104 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
105 Py_XDECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000106 return 0;
107 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000108 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000109 return 1;
110}
111
112/* Build and set an Expat exception, including positioning
113 * information. Always returns NULL.
114 */
Fred Drake85d835f2001-02-08 15:39:08 +0000115static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000116set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000117{
118 PyObject *err;
119 char buffer[256];
120 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000121 int lineno = XML_GetErrorLineNumber(parser);
122 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000123
Martin v. Löwis6b2cf0e2002-06-30 06:03:35 +0000124 /* There is no risk of overflowing this buffer, since
125 even for 64-bit integers, there is sufficient space. */
126 sprintf(buffer, "%.200s: line %i, column %i",
Fred Drakebd6101c2001-02-14 18:29:45 +0000127 XML_ErrorString(code), lineno, column);
Fred Drake85d835f2001-02-08 15:39:08 +0000128 err = PyObject_CallFunction(ErrorObject, "s", buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000129 if ( err != NULL
130 && set_error_attr(err, "code", code)
131 && set_error_attr(err, "offset", column)
132 && set_error_attr(err, "lineno", lineno)) {
133 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000134 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000135 Py_XDECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000136 return NULL;
137}
138
Fred Drake71b63ff2002-06-28 22:29:01 +0000139static int
140have_handler(xmlparseobject *self, int type)
141{
142 PyObject *handler = self->handlers[type];
143 return handler != NULL;
144}
145
146static PyObject *
147get_handler_name(struct HandlerInfo *hinfo)
148{
149 PyObject *name = hinfo->nameobj;
150 if (name == NULL) {
151 name = PyString_FromString(hinfo->name);
152 hinfo->nameobj = name;
153 }
154 Py_XINCREF(name);
155 return name;
156}
157
Fred Drake85d835f2001-02-08 15:39:08 +0000158
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000159/* Convert a string of XML_Chars into a Unicode string.
160 Returns None if str is a null pointer. */
161
Fred Drake0582df92000-07-12 04:49:00 +0000162static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000163conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000164{
Fred Drake71b63ff2002-06-28 22:29:01 +0000165 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000166 and hence in UTF-8. */
167 /* UTF-8 from Expat, Unicode desired */
168 if (str == NULL) {
169 Py_INCREF(Py_None);
170 return Py_None;
171 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000172 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000173}
174
Fred Drake0582df92000-07-12 04:49:00 +0000175static PyObject *
176conv_string_len_to_unicode(const XML_Char *str, int len)
177{
Fred Drake71b63ff2002-06-28 22:29:01 +0000178 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000179 and hence in UTF-8. */
180 /* UTF-8 from Expat, Unicode desired */
181 if (str == NULL) {
182 Py_INCREF(Py_None);
183 return Py_None;
184 }
Fred Drake6f987622000-08-25 18:03:30 +0000185 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000186}
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000187
188/* Convert a string of XML_Chars into an 8-bit Python string.
189 Returns None if str is a null pointer. */
190
Fred Drake6f987622000-08-25 18:03:30 +0000191static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000192conv_string_to_utf8(const XML_Char *str)
Fred Drake6f987622000-08-25 18:03:30 +0000193{
Fred Drake71b63ff2002-06-28 22:29:01 +0000194 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000195 and hence in UTF-8. */
196 /* UTF-8 from Expat, UTF-8 desired */
197 if (str == NULL) {
198 Py_INCREF(Py_None);
199 return Py_None;
200 }
Fred Drakeb91a36b2002-06-27 19:40:48 +0000201 return PyString_FromString(str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000202}
203
Fred Drake6f987622000-08-25 18:03:30 +0000204static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +0000205conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000206{
Fred Drake71b63ff2002-06-28 22:29:01 +0000207 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000208 and hence in UTF-8. */
209 /* UTF-8 from Expat, UTF-8 desired */
210 if (str == NULL) {
211 Py_INCREF(Py_None);
212 return Py_None;
213 }
214 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000215}
216
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000217/* Callback routines */
218
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000219static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000220
Martin v. Löwis069dde22003-01-21 10:58:18 +0000221/* This handler is used when an error has been detected, in the hope
222 that actual parsing can be terminated early. This will only help
223 if an external entity reference is encountered. */
224static int
225error_external_entity_ref_handler(XML_Parser parser,
226 const XML_Char *context,
227 const XML_Char *base,
228 const XML_Char *systemId,
229 const XML_Char *publicId)
230{
231 return 0;
232}
233
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000234/* Dummy character data handler used when an error (exception) has
235 been detected, and the actual parsing can be terminated early.
236 This is needed since character data handler can't be safely removed
237 from within the character data handler, but can be replaced. It is
238 used only from the character data handler trampoline, and must be
239 used right after `flag_error()` is called. */
240static void
241noop_character_data_handler(void *userData, const XML_Char *data, int len)
242{
243 /* Do nothing. */
244}
245
Fred Drake6f987622000-08-25 18:03:30 +0000246static void
247flag_error(xmlparseobject *self)
248{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000249 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000250 XML_SetExternalEntityRefHandler(self->itself,
251 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000252}
253
254static PyCodeObject*
255getcode(enum HandlerTypes slot, char* func_name, int lineno)
256{
Fred Drakebd6101c2001-02-14 18:29:45 +0000257 PyObject *code = NULL;
258 PyObject *name = NULL;
259 PyObject *nulltuple = NULL;
260 PyObject *filename = NULL;
261
262 if (handler_info[slot].tb_code == NULL) {
263 code = PyString_FromString("");
264 if (code == NULL)
265 goto failed;
266 name = PyString_FromString(func_name);
267 if (name == NULL)
268 goto failed;
269 nulltuple = PyTuple_New(0);
270 if (nulltuple == NULL)
271 goto failed;
272 filename = PyString_FromString(__FILE__);
273 handler_info[slot].tb_code =
274 PyCode_New(0, /* argcount */
Guido van Rossum4f72a782006-10-27 23:31:49 +0000275 0, /* kwonlyargcount */
Fred Drakebd6101c2001-02-14 18:29:45 +0000276 0, /* nlocals */
277 0, /* stacksize */
278 0, /* flags */
279 code, /* code */
280 nulltuple, /* consts */
281 nulltuple, /* names */
282 nulltuple, /* varnames */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000283#if PYTHON_API_VERSION >= 1010
Fred Drakebd6101c2001-02-14 18:29:45 +0000284 nulltuple, /* freevars */
285 nulltuple, /* cellvars */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000286#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000287 filename, /* filename */
288 name, /* name */
289 lineno, /* firstlineno */
290 code /* lnotab */
291 );
292 if (handler_info[slot].tb_code == NULL)
293 goto failed;
294 Py_DECREF(code);
295 Py_DECREF(nulltuple);
296 Py_DECREF(filename);
297 Py_DECREF(name);
298 }
299 return handler_info[slot].tb_code;
300 failed:
301 Py_XDECREF(code);
302 Py_XDECREF(name);
303 return NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000304}
305
Jeremy Hylton9263f572003-06-27 16:13:17 +0000306#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000307static int
308trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
309{
310 int result = 0;
311 if (!tstate->use_tracing || tstate->tracing)
312 return 0;
313 if (tstate->c_profilefunc != NULL) {
314 tstate->tracing++;
315 result = tstate->c_profilefunc(tstate->c_profileobj,
316 f, code , val);
317 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
318 || (tstate->c_profilefunc != NULL));
319 tstate->tracing--;
320 if (result)
321 return result;
322 }
323 if (tstate->c_tracefunc != NULL) {
324 tstate->tracing++;
325 result = tstate->c_tracefunc(tstate->c_traceobj,
326 f, code , val);
327 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
328 || (tstate->c_profilefunc != NULL));
329 tstate->tracing--;
330 }
331 return result;
332}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000333
334static int
335trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
336{
337 PyObject *type, *value, *traceback, *arg;
338 int err;
339
340 if (tstate->c_tracefunc == NULL)
341 return 0;
342
343 PyErr_Fetch(&type, &value, &traceback);
344 if (value == NULL) {
345 value = Py_None;
346 Py_INCREF(value);
347 }
Martin v. Löwis9171f022004-10-13 19:50:11 +0000348#if PY_VERSION_HEX < 0x02040000
349 arg = Py_BuildValue("(OOO)", type, value, traceback);
350#else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000351 arg = PyTuple_Pack(3, type, value, traceback);
Martin v. Löwis9171f022004-10-13 19:50:11 +0000352#endif
Jeremy Hylton9263f572003-06-27 16:13:17 +0000353 if (arg == NULL) {
354 PyErr_Restore(type, value, traceback);
355 return 0;
356 }
357 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
358 Py_DECREF(arg);
359 if (err == 0)
360 PyErr_Restore(type, value, traceback);
361 else {
362 Py_XDECREF(type);
363 Py_XDECREF(value);
364 Py_XDECREF(traceback);
365 }
366 return err;
367}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000368#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000369
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000370static PyObject*
Fred Drake39689c52004-08-13 03:12:57 +0000371call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
372 xmlparseobject *self)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000373{
Fred Drakebd6101c2001-02-14 18:29:45 +0000374 PyThreadState *tstate = PyThreadState_GET();
375 PyFrameObject *f;
376 PyObject *res;
377
378 if (c == NULL)
379 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000380
Jeremy Hylton9263f572003-06-27 16:13:17 +0000381 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000382 if (f == NULL)
383 return NULL;
384 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000385#ifdef FIX_TRACE
386 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000387 return NULL;
388 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000389#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000390 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000391 if (res == NULL) {
392 if (tstate->curexc_traceback == NULL)
393 PyTraceBack_Here(f);
Fred Drake39689c52004-08-13 03:12:57 +0000394 XML_StopParser(self->itself, XML_FALSE);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000395#ifdef FIX_TRACE
396 if (trace_frame_exc(tstate, f) < 0) {
397 return NULL;
398 }
399 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000400 else {
Jeremy Hylton9263f572003-06-27 16:13:17 +0000401 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000402 Py_XDECREF(res);
403 res = NULL;
404 }
405 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000406#else
407 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000408#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000409 tstate->frame = f->f_back;
410 Py_DECREF(f);
411 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000412}
413
Martin v. Löwis069dde22003-01-21 10:58:18 +0000414/* Python 2.0 and later versions, when built with Unicode support */
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000415#define STRING_CONV_FUNC (self->returns_unicode \
416 ? conv_string_to_unicode : conv_string_to_utf8)
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000417
Fred Drakeb91a36b2002-06-27 19:40:48 +0000418static PyObject*
419string_intern(xmlparseobject *self, const char* str)
420{
421 PyObject *result = STRING_CONV_FUNC(str);
422 PyObject *value;
Neal Norwitz484d9a42005-09-30 04:46:49 +0000423 /* result can be NULL if the unicode conversion failed. */
424 if (!result)
425 return result;
Fred Drakeb91a36b2002-06-27 19:40:48 +0000426 if (!self->intern)
427 return result;
428 value = PyDict_GetItem(self->intern, result);
429 if (!value) {
430 if (PyDict_SetItem(self->intern, result, result) == 0)
431 return result;
432 else
433 return NULL;
434 }
435 Py_INCREF(value);
436 Py_DECREF(result);
437 return value;
438}
439
Fred Drake2a3d7db2002-06-28 22:56:48 +0000440/* Return 0 on success, -1 on exception.
441 * flag_error() will be called before return if needed.
442 */
443static int
444call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
445{
446 PyObject *args;
447 PyObject *temp;
448
449 args = PyTuple_New(1);
450 if (args == NULL)
451 return -1;
Fred Drake2a3d7db2002-06-28 22:56:48 +0000452 temp = (self->returns_unicode
453 ? conv_string_len_to_unicode(buffer, len)
454 : conv_string_len_to_utf8(buffer, len));
Fred Drake2a3d7db2002-06-28 22:56:48 +0000455 if (temp == NULL) {
456 Py_DECREF(args);
457 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000458 XML_SetCharacterDataHandler(self->itself,
459 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000460 return -1;
461 }
462 PyTuple_SET_ITEM(args, 0, temp);
463 /* temp is now a borrowed reference; consider it unused. */
464 self->in_callback = 1;
465 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000466 self->handlers[CharacterData], args, self);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000467 /* temp is an owned reference again, or NULL */
468 self->in_callback = 0;
469 Py_DECREF(args);
470 if (temp == NULL) {
471 flag_error(self);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000472 XML_SetCharacterDataHandler(self->itself,
473 noop_character_data_handler);
Fred Drake2a3d7db2002-06-28 22:56:48 +0000474 return -1;
475 }
476 Py_DECREF(temp);
477 return 0;
478}
479
480static int
481flush_character_buffer(xmlparseobject *self)
482{
483 int rc;
484 if (self->buffer == NULL || self->buffer_used == 0)
485 return 0;
486 rc = call_character_handler(self, self->buffer, self->buffer_used);
487 self->buffer_used = 0;
488 return rc;
489}
490
491static void
492my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
493{
494 xmlparseobject *self = (xmlparseobject *) userData;
495 if (self->buffer == NULL)
496 call_character_handler(self, data, len);
497 else {
498 if ((self->buffer_used + len) > self->buffer_size) {
499 if (flush_character_buffer(self) < 0)
500 return;
501 /* handler might have changed; drop the rest on the floor
502 * if there isn't a handler anymore
503 */
504 if (!have_handler(self, CharacterData))
505 return;
506 }
507 if (len > self->buffer_size) {
508 call_character_handler(self, data, len);
509 self->buffer_used = 0;
510 }
511 else {
512 memcpy(self->buffer + self->buffer_used,
513 data, len * sizeof(XML_Char));
514 self->buffer_used += len;
515 }
516 }
517}
518
Fred Drake85d835f2001-02-08 15:39:08 +0000519static void
520my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000521 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000522{
523 xmlparseobject *self = (xmlparseobject *)userData;
524
Fred Drake71b63ff2002-06-28 22:29:01 +0000525 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000526 PyObject *container, *rv, *args;
527 int i, max;
528
Fred Drake2a3d7db2002-06-28 22:56:48 +0000529 if (flush_character_buffer(self) < 0)
530 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000531 /* Set max to the number of slots filled in atts[]; max/2 is
532 * the number of attributes we need to process.
533 */
534 if (self->specified_attributes) {
535 max = XML_GetSpecifiedAttributeCount(self->itself);
536 }
537 else {
538 max = 0;
539 while (atts[max] != NULL)
540 max += 2;
541 }
542 /* Build the container. */
543 if (self->ordered_attributes)
544 container = PyList_New(max);
545 else
546 container = PyDict_New();
547 if (container == NULL) {
548 flag_error(self);
549 return;
550 }
551 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000552 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000553 PyObject *v;
554 if (n == NULL) {
555 flag_error(self);
556 Py_DECREF(container);
557 return;
558 }
559 v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
560 if (v == NULL) {
561 flag_error(self);
562 Py_DECREF(container);
563 Py_DECREF(n);
564 return;
565 }
566 if (self->ordered_attributes) {
567 PyList_SET_ITEM(container, i, n);
568 PyList_SET_ITEM(container, i+1, v);
569 }
570 else if (PyDict_SetItem(container, n, v)) {
571 flag_error(self);
572 Py_DECREF(n);
573 Py_DECREF(v);
574 return;
575 }
576 else {
577 Py_DECREF(n);
578 Py_DECREF(v);
579 }
580 }
Neal Norwitz484d9a42005-09-30 04:46:49 +0000581 args = string_intern(self, name);
582 if (args != NULL)
583 args = Py_BuildValue("(NN)", args, container);
Fred Drake85d835f2001-02-08 15:39:08 +0000584 if (args == NULL) {
585 Py_DECREF(container);
586 return;
587 }
588 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000589 self->in_callback = 1;
590 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000591 self->handlers[StartElement], args, self);
Fred Drakebd6101c2001-02-14 18:29:45 +0000592 self->in_callback = 0;
593 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000594 if (rv == NULL) {
595 flag_error(self);
596 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000597 }
Fred Drake85d835f2001-02-08 15:39:08 +0000598 Py_DECREF(rv);
599 }
600}
601
602#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
603 RETURN, GETUSERDATA) \
604static RC \
605my_##NAME##Handler PARAMS {\
606 xmlparseobject *self = GETUSERDATA ; \
607 PyObject *args = NULL; \
608 PyObject *rv = NULL; \
609 INIT \
610\
Fred Drake71b63ff2002-06-28 22:29:01 +0000611 if (have_handler(self, NAME)) { \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000612 if (flush_character_buffer(self) < 0) \
613 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000614 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000615 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000616 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000617 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
Fred Drake39689c52004-08-13 03:12:57 +0000618 self->handlers[NAME], args, self); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000619 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000620 Py_DECREF(args); \
621 if (rv == NULL) { \
622 flag_error(self); \
623 return RETURN; \
624 } \
625 CONVERSION \
626 Py_DECREF(rv); \
627 } \
628 return RETURN; \
629}
630
Fred Drake6f987622000-08-25 18:03:30 +0000631#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
632 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
633 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000634
Fred Drake6f987622000-08-25 18:03:30 +0000635#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
636 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
637 rc = PyInt_AsLong(rv);, rc, \
638 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000639
Fred Drake71b63ff2002-06-28 22:29:01 +0000640VOID_HANDLER(EndElement,
641 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000642 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000643
Fred Drake6f987622000-08-25 18:03:30 +0000644VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000645 (void *userData,
646 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000647 const XML_Char *data),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000648 ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000649
Fred Drake6f987622000-08-25 18:03:30 +0000650VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000651 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000652 const XML_Char *entityName,
653 const XML_Char *base,
654 const XML_Char *systemId,
655 const XML_Char *publicId,
656 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000657 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000658 string_intern(self, entityName), string_intern(self, base),
659 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000660 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000661
Fred Drake85d835f2001-02-08 15:39:08 +0000662VOID_HANDLER(EntityDecl,
663 (void *userData,
664 const XML_Char *entityName,
665 int is_parameter_entity,
666 const XML_Char *value,
667 int value_length,
668 const XML_Char *base,
669 const XML_Char *systemId,
670 const XML_Char *publicId,
671 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000672 ("NiNNNNN",
673 string_intern(self, entityName), is_parameter_entity,
Fred Drake71b63ff2002-06-28 22:29:01 +0000674 (self->returns_unicode
675 ? conv_string_len_to_unicode(value, value_length)
Fred Drake85d835f2001-02-08 15:39:08 +0000676 : conv_string_len_to_utf8(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000677 string_intern(self, base), string_intern(self, systemId),
678 string_intern(self, publicId),
679 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000680
681VOID_HANDLER(XmlDecl,
682 (void *userData,
683 const XML_Char *version,
684 const XML_Char *encoding,
685 int standalone),
686 ("(O&O&i)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000687 STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000688 standalone))
689
690static PyObject *
691conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000692 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000693{
694 PyObject *result = NULL;
695 PyObject *children = PyTuple_New(model->numchildren);
696 int i;
697
698 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000699 assert(model->numchildren < INT_MAX);
700 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000701 PyObject *child = conv_content_model(&model->children[i],
702 conv_string);
703 if (child == NULL) {
704 Py_XDECREF(children);
705 return NULL;
706 }
707 PyTuple_SET_ITEM(children, i, child);
708 }
709 result = Py_BuildValue("(iiO&N)",
710 model->type, model->quant,
711 conv_string,model->name, children);
712 }
713 return result;
714}
715
Fred Drake06dd8cf2003-02-02 03:54:17 +0000716static void
717my_ElementDeclHandler(void *userData,
718 const XML_Char *name,
719 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000720{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000721 xmlparseobject *self = (xmlparseobject *)userData;
722 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000723
Fred Drake06dd8cf2003-02-02 03:54:17 +0000724 if (have_handler(self, ElementDecl)) {
725 PyObject *rv = NULL;
726 PyObject *modelobj, *nameobj;
727
728 if (flush_character_buffer(self) < 0)
729 goto finally;
Fred Drake06dd8cf2003-02-02 03:54:17 +0000730 modelobj = conv_content_model(model,
731 (self->returns_unicode
732 ? conv_string_to_unicode
733 : conv_string_to_utf8));
Fred Drake06dd8cf2003-02-02 03:54:17 +0000734 if (modelobj == NULL) {
735 flag_error(self);
736 goto finally;
737 }
738 nameobj = string_intern(self, name);
739 if (nameobj == NULL) {
740 Py_DECREF(modelobj);
741 flag_error(self);
742 goto finally;
743 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000744 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000745 if (args == NULL) {
746 Py_DECREF(modelobj);
747 flag_error(self);
748 goto finally;
749 }
750 self->in_callback = 1;
751 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
Fred Drake39689c52004-08-13 03:12:57 +0000752 self->handlers[ElementDecl], args, self);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000753 self->in_callback = 0;
754 if (rv == NULL) {
755 flag_error(self);
756 goto finally;
757 }
758 Py_DECREF(rv);
759 }
760 finally:
761 Py_XDECREF(args);
762 XML_FreeContentModel(self->itself, model);
763 return;
764}
Fred Drake85d835f2001-02-08 15:39:08 +0000765
766VOID_HANDLER(AttlistDecl,
767 (void *userData,
768 const XML_Char *elname,
769 const XML_Char *attname,
770 const XML_Char *att_type,
771 const XML_Char *dflt,
772 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000773 ("(NNO&O&i)",
774 string_intern(self, elname), string_intern(self, attname),
Fred Drake85d835f2001-02-08 15:39:08 +0000775 STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
776 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000777
Martin v. Löwisc847f402003-01-21 11:09:21 +0000778#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000779VOID_HANDLER(SkippedEntity,
780 (void *userData,
781 const XML_Char *entityName,
782 int is_parameter_entity),
783 ("Ni",
784 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000785#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000786
Fred Drake71b63ff2002-06-28 22:29:01 +0000787VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000788 (void *userData,
789 const XML_Char *notationName,
790 const XML_Char *base,
791 const XML_Char *systemId,
792 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000793 ("(NNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000794 string_intern(self, notationName), string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000795 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000796
Fred Drake6f987622000-08-25 18:03:30 +0000797VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000798 (void *userData,
799 const XML_Char *prefix,
800 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000801 ("(NN)",
802 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000803
Fred Drake6f987622000-08-25 18:03:30 +0000804VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000805 (void *userData,
806 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000807 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000808
Fred Drake6f987622000-08-25 18:03:30 +0000809VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000810 (void *userData, const XML_Char *data),
811 ("(O&)", STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000812
Fred Drake6f987622000-08-25 18:03:30 +0000813VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000814 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000815 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000816
Fred Drake6f987622000-08-25 18:03:30 +0000817VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000818 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000819 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000820
Fred Drake6f987622000-08-25 18:03:30 +0000821VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000822 (void *userData, const XML_Char *s, int len),
823 ("(N)", (self->returns_unicode
824 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000825 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000826
Fred Drake6f987622000-08-25 18:03:30 +0000827VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000828 (void *userData, const XML_Char *s, int len),
829 ("(N)", (self->returns_unicode
830 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000831 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000832
Fred Drake71b63ff2002-06-28 22:29:01 +0000833INT_HANDLER(NotStandalone,
834 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000835 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000836
Fred Drake6f987622000-08-25 18:03:30 +0000837RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000838 (XML_Parser parser,
839 const XML_Char *context,
840 const XML_Char *base,
841 const XML_Char *systemId,
842 const XML_Char *publicId),
843 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000844 ("(O&NNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000845 STRING_CONV_FUNC,context, string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000846 string_intern(self, systemId), string_intern(self, publicId)),
Fred Drake6f987622000-08-25 18:03:30 +0000847 rc = PyInt_AsLong(rv);, rc,
848 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000849
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000850/* XXX UnknownEncodingHandler */
851
Fred Drake85d835f2001-02-08 15:39:08 +0000852VOID_HANDLER(StartDoctypeDecl,
853 (void *userData, const XML_Char *doctypeName,
854 const XML_Char *sysid, const XML_Char *pubid,
855 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000856 ("(NNNi)", string_intern(self, doctypeName),
857 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000858 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000859
860VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000861
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000862/* ---------------------------------------------------------------- */
863
Fred Drake71b63ff2002-06-28 22:29:01 +0000864static PyObject *
865get_parse_result(xmlparseobject *self, int rv)
866{
867 if (PyErr_Occurred()) {
868 return NULL;
869 }
870 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000871 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000872 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000873 if (flush_character_buffer(self) < 0) {
874 return NULL;
875 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000876 return PyInt_FromLong(rv);
877}
878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000879PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000880"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000881Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000882
883static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000884xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000885{
Fred Drake0582df92000-07-12 04:49:00 +0000886 char *s;
887 int slen;
888 int isFinal = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000889
Fred Drake0582df92000-07-12 04:49:00 +0000890 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
891 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000892
893 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000894}
895
Fred Drakeca1f4262000-09-21 20:10:23 +0000896/* File reading copied from cPickle */
897
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000898#define BUF_SIZE 2048
899
Fred Drake0582df92000-07-12 04:49:00 +0000900static int
901readinst(char *buf, int buf_size, PyObject *meth)
902{
903 PyObject *arg = NULL;
904 PyObject *bytes = NULL;
905 PyObject *str = NULL;
906 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000907
Fred Drake676940b2000-09-22 15:21:31 +0000908 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000909 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000910
Fred Drake7b6caff2003-07-21 17:05:56 +0000911 if ((arg = PyTuple_New(1)) == NULL) {
912 Py_DECREF(bytes);
Fred Drake0582df92000-07-12 04:49:00 +0000913 goto finally;
Fred Drake7b6caff2003-07-21 17:05:56 +0000914 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000915
Tim Peters954eef72000-09-22 06:01:11 +0000916 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000917
Martin v. Löwis9171f022004-10-13 19:50:11 +0000918#if PY_VERSION_HEX < 0x02020000
919 str = PyObject_CallObject(meth, arg);
920#else
921 str = PyObject_Call(meth, arg, NULL);
922#endif
923 if (str == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000924 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000925
Fred Drake0582df92000-07-12 04:49:00 +0000926 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000927 if (!PyString_Check(str)) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000928 PyErr_Format(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000929 "read() did not return a string object (type=%.400s)",
930 str->ob_type->tp_name);
931 goto finally;
932 }
933 len = PyString_GET_SIZE(str);
934 if (len > buf_size) {
935 PyErr_Format(PyExc_ValueError,
936 "read() returned too much data: "
937 "%i bytes requested, %i returned",
938 buf_size, len);
Fred Drake0582df92000-07-12 04:49:00 +0000939 goto finally;
940 }
941 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000942finally:
Fred Drake0582df92000-07-12 04:49:00 +0000943 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000944 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000945 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000946}
947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000948PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000949"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000950Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000951
952static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000953xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000954{
Fred Drake0582df92000-07-12 04:49:00 +0000955 int rv = 1;
Fred Drake0582df92000-07-12 04:49:00 +0000956 FILE *fp;
957 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000958
Guido van Rossumda5b8f22007-06-12 23:30:11 +0000959 {
Fred Drake0582df92000-07-12 04:49:00 +0000960 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000961 readmethod = PyObject_GetAttrString(f, "read");
962 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000963 PyErr_Clear();
Fred Drake71b63ff2002-06-28 22:29:01 +0000964 PyErr_SetString(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000965 "argument must have 'read' attribute");
Fred Drake814f9fe2002-07-19 22:03:03 +0000966 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000967 }
968 }
969 for (;;) {
970 int bytes_read;
971 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000972 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000973 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000974 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +0000975 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000976
Fred Drake0582df92000-07-12 04:49:00 +0000977 if (fp) {
978 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
979 if (bytes_read < 0) {
980 PyErr_SetFromErrno(PyExc_IOError);
981 return NULL;
982 }
983 }
984 else {
985 bytes_read = readinst(buf, BUF_SIZE, readmethod);
Fred Drake7b6caff2003-07-21 17:05:56 +0000986 if (bytes_read < 0) {
987 Py_DECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000988 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000989 }
Fred Drake0582df92000-07-12 04:49:00 +0000990 }
991 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000992 if (PyErr_Occurred()) {
993 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000994 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000995 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000996
Fred Drake0582df92000-07-12 04:49:00 +0000997 if (!rv || bytes_read == 0)
998 break;
999 }
Fred Drake7b6caff2003-07-21 17:05:56 +00001000 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +00001001 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001002}
1003
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001004PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001005"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001006Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001007
1008static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001009xmlparse_SetBase(xmlparseobject *self, PyObject *args)
1010{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001011 char *base;
1012
Fred Drake0582df92000-07-12 04:49:00 +00001013 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001014 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001015 if (!XML_SetBase(self->itself, base)) {
1016 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001017 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001018 Py_INCREF(Py_None);
1019 return Py_None;
1020}
1021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001022PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001023"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001024Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001025
1026static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001027xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +00001028{
Fred Drake0582df92000-07-12 04:49:00 +00001029 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001030}
1031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001032PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +00001033"GetInputContext() -> string\n\
1034Return the untranslated text of the input that caused the current event.\n\
1035If the event was generated by a large amount of text (such as a start tag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001036for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +00001037
1038static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001039xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +00001040{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001041 if (self->in_callback) {
1042 int offset, size;
1043 const char *buffer
1044 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +00001045
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001046 if (buffer != NULL)
1047 return PyString_FromStringAndSize(buffer + offset,
1048 size - offset);
1049 else
1050 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001051 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001052 else
1053 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001054}
Fred Drakebd6101c2001-02-14 18:29:45 +00001055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001056PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +00001057"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +00001058Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001059information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001060
1061static PyObject *
1062xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
1063{
1064 char *context;
1065 char *encoding = NULL;
1066 xmlparseobject *new_parser;
1067 int i;
1068
Martin v. Löwisc57428d2001-09-19 09:55:09 +00001069 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +00001070 &context, &encoding)) {
1071 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001072 }
1073
Martin v. Löwis894258c2001-09-23 10:20:10 +00001074#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001075 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001076 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001077#else
1078 /* Python versions 2.2 and later */
1079 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1080#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001081
1082 if (new_parser == NULL)
1083 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001084 new_parser->buffer_size = self->buffer_size;
1085 new_parser->buffer_used = 0;
1086 if (self->buffer != NULL) {
1087 new_parser->buffer = malloc(new_parser->buffer_size);
1088 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +00001089#ifndef Py_TPFLAGS_HAVE_GC
1090 /* Code for versions 2.0 and 2.1 */
1091 PyObject_Del(new_parser);
1092#else
1093 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001094 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +00001095#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +00001096 return PyErr_NoMemory();
1097 }
1098 }
1099 else
1100 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001101 new_parser->returns_unicode = self->returns_unicode;
1102 new_parser->ordered_attributes = self->ordered_attributes;
1103 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001104 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001105 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001106 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001107 encoding);
1108 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001109 new_parser->intern = self->intern;
1110 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001111#ifdef Py_TPFLAGS_HAVE_GC
1112 PyObject_GC_Track(new_parser);
1113#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001114 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001115#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001116
1117 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001118 Py_DECREF(new_parser);
1119 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001120 }
1121
1122 XML_SetUserData(new_parser->itself, (void *)new_parser);
1123
1124 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001125 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001126 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001127
Fred Drake2a3d7db2002-06-28 22:56:48 +00001128 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001129 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001130 Py_DECREF(new_parser);
1131 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001132 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001133 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001134
1135 /* then copy handlers from self */
1136 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001137 PyObject *handler = self->handlers[i];
1138 if (handler != NULL) {
1139 Py_INCREF(handler);
1140 new_parser->handlers[i] = handler;
1141 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001142 handler_info[i].handler);
1143 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001144 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001145 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001146}
1147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001148PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001149"SetParamEntityParsing(flag) -> success\n\
1150Controls parsing of parameter entities (including the external DTD\n\
1151subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1152XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1153XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001154was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001155
1156static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001157xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001158{
Fred Drake85d835f2001-02-08 15:39:08 +00001159 int flag;
1160 if (!PyArg_ParseTuple(args, "i", &flag))
1161 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001162 flag = XML_SetParamEntityParsing(p->itself, flag);
Fred Drake85d835f2001-02-08 15:39:08 +00001163 return PyInt_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001164}
1165
Martin v. Löwisc847f402003-01-21 11:09:21 +00001166
1167#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001168PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1169"UseForeignDTD([flag])\n\
1170Allows the application to provide an artificial external subset if one is\n\
1171not specified as part of the document instance. This readily allows the\n\
1172use of a 'default' document type controlled by the application, while still\n\
1173getting the advantage of providing document type information to the parser.\n\
1174'flag' defaults to True if not provided.");
1175
1176static PyObject *
1177xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1178{
1179 PyObject *flagobj = NULL;
1180 XML_Bool flag = XML_TRUE;
1181 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001182 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001183 return NULL;
1184 if (flagobj != NULL)
1185 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1186 rc = XML_UseForeignDTD(self->itself, flag);
1187 if (rc != XML_ERROR_NONE) {
1188 return set_error(self, rc);
1189 }
1190 Py_INCREF(Py_None);
1191 return Py_None;
1192}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001193#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001194
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001195static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001196 {"Parse", (PyCFunction)xmlparse_Parse,
Fred Drakebd6101c2001-02-14 18:29:45 +00001197 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001198 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001199 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001200 {"SetBase", (PyCFunction)xmlparse_SetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001201 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001202 {"GetBase", (PyCFunction)xmlparse_GetBase,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001203 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001204 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001205 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001206 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
1207 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001208 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001209 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001210#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001211 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
1212 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001213#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001214 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001215};
1216
1217/* ---------- */
1218
1219
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001220
Fred Drake71b63ff2002-06-28 22:29:01 +00001221/* pyexpat international encoding support.
1222 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001223*/
1224
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001225static char template_buffer[257];
Fred Drakebb66a202001-03-01 20:48:17 +00001226PyObject *template_string = NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001227
Fred Drake71b63ff2002-06-28 22:29:01 +00001228static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001229init_template_buffer(void)
1230{
1231 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001232 for (i = 0; i < 256; i++) {
1233 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001234 }
Fred Drakebb66a202001-03-01 20:48:17 +00001235 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001236}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001237
Fred Drake71b63ff2002-06-28 22:29:01 +00001238static int
1239PyUnknownEncodingHandler(void *encodingHandlerData,
1240 const XML_Char *name,
1241 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001242{
Fred Drakebb66a202001-03-01 20:48:17 +00001243 PyUnicodeObject *_u_string = NULL;
1244 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001245 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001246
Fred Drakebb66a202001-03-01 20:48:17 +00001247 /* Yes, supports only 8bit encodings */
1248 _u_string = (PyUnicodeObject *)
1249 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001250
Fred Drakebb66a202001-03-01 20:48:17 +00001251 if (_u_string == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001252 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001253
Fred Drakebb66a202001-03-01 20:48:17 +00001254 for (i = 0; i < 256; i++) {
1255 /* Stupid to access directly, but fast */
1256 Py_UNICODE c = _u_string->str[i];
1257 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001258 info->map[i] = -1;
Fred Drakebb66a202001-03-01 20:48:17 +00001259 else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001260 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001261 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001262 info->data = NULL;
1263 info->convert = NULL;
1264 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001265 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001266 Py_DECREF(_u_string);
1267 return result;
1268}
1269
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001270
1271static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001272newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001273{
1274 int i;
1275 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001276
Martin v. Löwis894258c2001-09-23 10:20:10 +00001277#ifdef Py_TPFLAGS_HAVE_GC
1278 /* Code for versions 2.2 and later */
1279 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1280#else
Fred Drake0582df92000-07-12 04:49:00 +00001281 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001282#endif
Fred Drake0582df92000-07-12 04:49:00 +00001283 if (self == NULL)
1284 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001285
Fred Drake0582df92000-07-12 04:49:00 +00001286 self->returns_unicode = 1;
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001287
Fred Drake2a3d7db2002-06-28 22:56:48 +00001288 self->buffer = NULL;
1289 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1290 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001291 self->ordered_attributes = 0;
1292 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001293 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001294 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001295 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001296 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001297 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1298 }
Fred Drake85d835f2001-02-08 15:39:08 +00001299 else {
Fred Drake0582df92000-07-12 04:49:00 +00001300 self->itself = XML_ParserCreate(encoding);
1301 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001302 self->intern = intern;
1303 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001304#ifdef Py_TPFLAGS_HAVE_GC
1305 PyObject_GC_Track(self);
1306#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001307 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001308#endif
Fred Drake0582df92000-07-12 04:49:00 +00001309 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001310 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001311 "XML_ParserCreate failed");
1312 Py_DECREF(self);
1313 return NULL;
1314 }
1315 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001316 XML_SetUnknownEncodingHandler(self->itself,
1317 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001318
Fred Drake2a3d7db2002-06-28 22:56:48 +00001319 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001320 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001321
Fred Drake7c75bf22002-07-01 14:02:31 +00001322 self->handlers = malloc(sizeof(PyObject *) * i);
1323 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001324 Py_DECREF(self);
1325 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001326 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001327 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001328
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001329 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001330}
1331
1332
1333static void
Fred Drake0582df92000-07-12 04:49:00 +00001334xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001335{
Fred Drake0582df92000-07-12 04:49:00 +00001336 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001337#ifdef Py_TPFLAGS_HAVE_GC
1338 PyObject_GC_UnTrack(self);
1339#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001340 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001341#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001342 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001343 XML_ParserFree(self->itself);
1344 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001345
Fred Drake85d835f2001-02-08 15:39:08 +00001346 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001347 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001348 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001349 temp = self->handlers[i];
1350 self->handlers[i] = NULL;
1351 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001352 }
1353 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001354 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001355 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001356 if (self->buffer != NULL) {
1357 free(self->buffer);
1358 self->buffer = NULL;
1359 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001360 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001361#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001362 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001363 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001364#else
1365 /* Code for versions 2.2 and later. */
1366 PyObject_GC_Del(self);
1367#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001368}
1369
Fred Drake0582df92000-07-12 04:49:00 +00001370static int
1371handlername2int(const char *name)
1372{
1373 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001374 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001375 if (strcmp(name, handler_info[i].name) == 0) {
1376 return i;
1377 }
1378 }
1379 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001380}
1381
1382static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001383get_pybool(int istrue)
1384{
1385 PyObject *result = istrue ? Py_True : Py_False;
1386 Py_INCREF(result);
1387 return result;
1388}
1389
1390static PyObject *
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001391xmlparse_getattr(xmlparseobject *self, char *name)
1392{
Fred Drake71b63ff2002-06-28 22:29:01 +00001393 int handlernum = handlername2int(name);
1394
1395 if (handlernum != -1) {
1396 PyObject *result = self->handlers[handlernum];
1397 if (result == NULL)
1398 result = Py_None;
1399 Py_INCREF(result);
1400 return result;
1401 }
1402 if (name[0] == 'E') {
1403 if (strcmp(name, "ErrorCode") == 0)
1404 return PyInt_FromLong((long)
1405 XML_GetErrorCode(self->itself));
1406 if (strcmp(name, "ErrorLineNumber") == 0)
1407 return PyInt_FromLong((long)
1408 XML_GetErrorLineNumber(self->itself));
1409 if (strcmp(name, "ErrorColumnNumber") == 0)
1410 return PyInt_FromLong((long)
1411 XML_GetErrorColumnNumber(self->itself));
1412 if (strcmp(name, "ErrorByteIndex") == 0)
1413 return PyInt_FromLong((long)
1414 XML_GetErrorByteIndex(self->itself));
1415 }
Dave Cole3203efb2004-08-26 00:37:31 +00001416 if (name[0] == 'C') {
1417 if (strcmp(name, "CurrentLineNumber") == 0)
1418 return PyInt_FromLong((long)
1419 XML_GetCurrentLineNumber(self->itself));
1420 if (strcmp(name, "CurrentColumnNumber") == 0)
1421 return PyInt_FromLong((long)
1422 XML_GetCurrentColumnNumber(self->itself));
1423 if (strcmp(name, "CurrentByteIndex") == 0)
1424 return PyInt_FromLong((long)
1425 XML_GetCurrentByteIndex(self->itself));
1426 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001427 if (name[0] == 'b') {
1428 if (strcmp(name, "buffer_size") == 0)
1429 return PyInt_FromLong((long) self->buffer_size);
1430 if (strcmp(name, "buffer_text") == 0)
1431 return get_pybool(self->buffer != NULL);
1432 if (strcmp(name, "buffer_used") == 0)
1433 return PyInt_FromLong((long) self->buffer_used);
1434 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001435 if (strcmp(name, "namespace_prefixes") == 0)
1436 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001437 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001438 return get_pybool(self->ordered_attributes);
Fred Drake0582df92000-07-12 04:49:00 +00001439 if (strcmp(name, "returns_unicode") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001440 return get_pybool((long) self->returns_unicode);
Fred Drake85d835f2001-02-08 15:39:08 +00001441 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001442 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001443 if (strcmp(name, "intern") == 0) {
1444 if (self->intern == NULL) {
1445 Py_INCREF(Py_None);
1446 return Py_None;
1447 }
1448 else {
1449 Py_INCREF(self->intern);
1450 return self->intern;
1451 }
1452 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001453
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001454#define APPEND(list, str) \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001455 do { \
1456 PyObject *o = PyString_FromString(str); \
1457 if (o != NULL) \
1458 PyList_Append(list, o); \
1459 Py_XDECREF(o); \
1460 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001461
Fred Drake0582df92000-07-12 04:49:00 +00001462 if (strcmp(name, "__members__") == 0) {
1463 int i;
1464 PyObject *rc = PyList_New(0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001465 if (!rc)
1466 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001467 for (i = 0; handler_info[i].name != NULL; i++) {
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001468 PyObject *o = get_handler_name(&handler_info[i]);
1469 if (o != NULL)
1470 PyList_Append(rc, o);
1471 Py_XDECREF(o);
Fred Drake0582df92000-07-12 04:49:00 +00001472 }
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001473 APPEND(rc, "ErrorCode");
1474 APPEND(rc, "ErrorLineNumber");
1475 APPEND(rc, "ErrorColumnNumber");
1476 APPEND(rc, "ErrorByteIndex");
Dave Cole3203efb2004-08-26 00:37:31 +00001477 APPEND(rc, "CurrentLineNumber");
1478 APPEND(rc, "CurrentColumnNumber");
1479 APPEND(rc, "CurrentByteIndex");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001480 APPEND(rc, "buffer_size");
1481 APPEND(rc, "buffer_text");
1482 APPEND(rc, "buffer_used");
Martin v. Löwis069dde22003-01-21 10:58:18 +00001483 APPEND(rc, "namespace_prefixes");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001484 APPEND(rc, "ordered_attributes");
1485 APPEND(rc, "returns_unicode");
1486 APPEND(rc, "specified_attributes");
1487 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001488
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001489#undef APPEND
Fred Drake0582df92000-07-12 04:49:00 +00001490 return rc;
1491 }
1492 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001493}
1494
Fred Drake6f987622000-08-25 18:03:30 +00001495static int
1496sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001497{
1498 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001499 if (handlernum >= 0) {
1500 xmlhandler c_handler = NULL;
1501 PyObject *temp = self->handlers[handlernum];
1502
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001503 if (v == Py_None) {
1504 /* If this is the character data handler, and a character
1505 data handler is already active, we need to be more
1506 careful. What we can safely do is replace the existing
1507 character data handler callback function with a no-op
1508 function that will refuse to call Python. The downside
1509 is that this doesn't completely remove the character
1510 data handler from the C layer if there's any callback
1511 active, so Expat does a little more work than it
1512 otherwise would, but that's really an odd case. A more
1513 elaborate system of handlers and state could remove the
1514 C handler more effectively. */
1515 if (handlernum == CharacterData && self->in_callback)
1516 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001517 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001518 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001519 else if (v != NULL) {
1520 Py_INCREF(v);
1521 c_handler = handler_info[handlernum].handler;
1522 }
Fred Drake0582df92000-07-12 04:49:00 +00001523 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001524 Py_XDECREF(temp);
1525 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001526 return 1;
1527 }
1528 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001529}
1530
1531static int
Fred Drake6f987622000-08-25 18:03:30 +00001532xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001533{
Fred Drake6f987622000-08-25 18:03:30 +00001534 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001535 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001536 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1537 return -1;
1538 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001539 if (strcmp(name, "buffer_text") == 0) {
1540 if (PyObject_IsTrue(v)) {
1541 if (self->buffer == NULL) {
1542 self->buffer = malloc(self->buffer_size);
1543 if (self->buffer == NULL) {
1544 PyErr_NoMemory();
1545 return -1;
1546 }
1547 self->buffer_used = 0;
1548 }
1549 }
1550 else if (self->buffer != NULL) {
1551 if (flush_character_buffer(self) < 0)
1552 return -1;
1553 free(self->buffer);
1554 self->buffer = NULL;
1555 }
1556 return 0;
1557 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001558 if (strcmp(name, "namespace_prefixes") == 0) {
1559 if (PyObject_IsTrue(v))
1560 self->ns_prefixes = 1;
1561 else
1562 self->ns_prefixes = 0;
1563 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1564 return 0;
1565 }
Fred Drake85d835f2001-02-08 15:39:08 +00001566 if (strcmp(name, "ordered_attributes") == 0) {
1567 if (PyObject_IsTrue(v))
1568 self->ordered_attributes = 1;
1569 else
1570 self->ordered_attributes = 0;
1571 return 0;
1572 }
Fred Drake6f987622000-08-25 18:03:30 +00001573 if (strcmp(name, "returns_unicode") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001574 if (PyObject_IsTrue(v)) {
Fred Drake6f987622000-08-25 18:03:30 +00001575 self->returns_unicode = 1;
Fred Drake6f987622000-08-25 18:03:30 +00001576 }
1577 else
1578 self->returns_unicode = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001579 return 0;
1580 }
1581 if (strcmp(name, "specified_attributes") == 0) {
1582 if (PyObject_IsTrue(v))
1583 self->specified_attributes = 1;
1584 else
1585 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001586 return 0;
1587 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001588 if (strcmp(name, "CharacterDataHandler") == 0) {
1589 /* If we're changing the character data handler, flush all
1590 * cached data with the old handler. Not sure there's a
1591 * "right" thing to do, though, but this probably won't
1592 * happen.
1593 */
1594 if (flush_character_buffer(self) < 0)
1595 return -1;
1596 }
Fred Drake6f987622000-08-25 18:03:30 +00001597 if (sethandler(self, name, v)) {
1598 return 0;
1599 }
1600 PyErr_SetString(PyExc_AttributeError, name);
1601 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001602}
1603
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001604static int
1605xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1606{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001607 int i;
1608 for (i = 0; handler_info[i].name != NULL; i++)
1609 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001610 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001611}
1612
1613static int
1614xmlparse_clear(xmlparseobject *op)
1615{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001616 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001617 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001618 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001619}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001621PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001622
1623static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001624 PyObject_HEAD_INIT(NULL)
1625 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001626 "pyexpat.xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001627 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001628 0, /*tp_itemsize*/
1629 /* methods */
1630 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1631 (printfunc)0, /*tp_print*/
1632 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1633 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1634 (cmpfunc)0, /*tp_compare*/
1635 (reprfunc)0, /*tp_repr*/
1636 0, /*tp_as_number*/
1637 0, /*tp_as_sequence*/
1638 0, /*tp_as_mapping*/
1639 (hashfunc)0, /*tp_hash*/
1640 (ternaryfunc)0, /*tp_call*/
1641 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001642 0, /* tp_getattro */
1643 0, /* tp_setattro */
1644 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001645#ifdef Py_TPFLAGS_HAVE_GC
Fred Drake71b63ff2002-06-28 22:29:01 +00001646 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001647#else
Fred Drake71b63ff2002-06-28 22:29:01 +00001648 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001649#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001650 Xmlparsetype__doc__, /* tp_doc - Documentation string */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001651 (traverseproc)xmlparse_traverse, /* tp_traverse */
1652 (inquiry)xmlparse_clear /* tp_clear */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001653};
1654
1655/* End of code for xmlparser objects */
1656/* -------------------------------------------------------- */
1657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001659"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001660Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001661
1662static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001663pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1664{
Fred Drakecde79132001-04-25 16:01:30 +00001665 char *encoding = NULL;
1666 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001667 PyObject *intern = NULL;
1668 PyObject *result;
1669 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001670 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001671 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001672
Fred Drakeb91a36b2002-06-27 19:40:48 +00001673 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1674 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001675 return NULL;
1676 if (namespace_separator != NULL
1677 && strlen(namespace_separator) > 1) {
1678 PyErr_SetString(PyExc_ValueError,
1679 "namespace_separator must be at most one"
1680 " character, omitted, or None");
1681 return NULL;
1682 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001683 /* Explicitly passing None means no interning is desired.
1684 Not passing anything means that a new dictionary is used. */
1685 if (intern == Py_None)
1686 intern = NULL;
1687 else if (intern == NULL) {
1688 intern = PyDict_New();
1689 if (!intern)
1690 return NULL;
1691 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001692 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001693 else if (!PyDict_Check(intern)) {
1694 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1695 return NULL;
1696 }
1697
1698 result = newxmlparseobject(encoding, namespace_separator, intern);
1699 if (intern_decref) {
1700 Py_DECREF(intern);
1701 }
1702 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001703}
1704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001705PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001706"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001707Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001708
1709static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001710pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001711{
Fred Drake0582df92000-07-12 04:49:00 +00001712 long code = 0;
1713
1714 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1715 return NULL;
1716 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001717}
1718
1719/* List of methods defined in the module */
1720
1721static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001722 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1723 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1724 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1725 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001726
Fred Drake0582df92000-07-12 04:49:00 +00001727 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001728};
1729
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001730/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001731
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001732PyDoc_STRVAR(pyexpat_module_documentation,
1733"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001734
Fred Drake4113b132001-03-24 19:58:26 +00001735/* Return a Python string that represents the version number without the
1736 * extra cruft added by revision control, even if the right options were
1737 * given to the "cvs export" command to make it not include the extra
1738 * cruft.
1739 */
1740static PyObject *
1741get_version_string(void)
1742{
1743 static char *rcsid = "$Revision$";
1744 char *rev = rcsid;
1745 int i = 0;
1746
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001747 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001748 ++rev;
1749 while (rev[i] != ' ' && rev[i] != '\0')
1750 ++i;
1751
1752 return PyString_FromStringAndSize(rev, i);
1753}
1754
Fred Drakecde79132001-04-25 16:01:30 +00001755/* Initialization function for the module */
1756
1757#ifndef MODULE_NAME
1758#define MODULE_NAME "pyexpat"
1759#endif
1760
1761#ifndef MODULE_INITFUNC
1762#define MODULE_INITFUNC initpyexpat
1763#endif
1764
Martin v. Löwis069dde22003-01-21 10:58:18 +00001765#ifndef PyMODINIT_FUNC
1766# ifdef MS_WINDOWS
1767# define PyMODINIT_FUNC __declspec(dllexport) void
1768# else
1769# define PyMODINIT_FUNC void
1770# endif
1771#endif
1772
Mark Hammond8235ea12002-07-19 06:55:41 +00001773PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001774
Martin v. Löwis069dde22003-01-21 10:58:18 +00001775PyMODINIT_FUNC
1776MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001777{
1778 PyObject *m, *d;
Fred Drakecde79132001-04-25 16:01:30 +00001779 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001780 PyObject *errors_module;
1781 PyObject *modelmod_name;
1782 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001783 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001784 static struct PyExpat_CAPI capi;
1785 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001786
Fred Drake6f987622000-08-25 18:03:30 +00001787 if (errmod_name == NULL)
1788 return;
Fred Drakecde79132001-04-25 16:01:30 +00001789 modelmod_name = PyString_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001790 if (modelmod_name == NULL)
1791 return;
Fred Drake6f987622000-08-25 18:03:30 +00001792
Fred Drake0582df92000-07-12 04:49:00 +00001793 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001794
Fred Drake0582df92000-07-12 04:49:00 +00001795 /* Create the module and add the functions */
Fred Drakecde79132001-04-25 16:01:30 +00001796 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
Fred Drake85d835f2001-02-08 15:39:08 +00001797 pyexpat_module_documentation);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001798 if (m == NULL)
1799 return;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001800
Fred Drake0582df92000-07-12 04:49:00 +00001801 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001802 if (ErrorObject == NULL) {
1803 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001804 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001805 if (ErrorObject == NULL)
1806 return;
1807 }
1808 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001809 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001810 Py_INCREF(ErrorObject);
1811 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001812 Py_INCREF(&Xmlparsetype);
1813 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001814
Fred Drake4113b132001-03-24 19:58:26 +00001815 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001816 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1817 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001818 {
1819 XML_Expat_Version info = XML_ExpatVersionInfo();
1820 PyModule_AddObject(m, "version_info",
1821 Py_BuildValue("(iii)", info.major,
1822 info.minor, info.micro));
1823 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001824 init_template_buffer();
Fred Drake0582df92000-07-12 04:49:00 +00001825 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001826 compiled, this should check and set native_encoding
1827 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001828 */
Fred Drake93adb692000-09-23 04:55:48 +00001829 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001830
Fred Drake85d835f2001-02-08 15:39:08 +00001831 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001832 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001833 errors_module = PyDict_GetItem(d, errmod_name);
1834 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001835 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001836 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001837 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001838 /* gives away the reference to errors_module */
1839 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001840 }
1841 }
Fred Drake6f987622000-08-25 18:03:30 +00001842 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001843 model_module = PyDict_GetItem(d, modelmod_name);
1844 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001845 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001846 if (model_module != NULL) {
1847 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1848 /* gives away the reference to model_module */
1849 PyModule_AddObject(m, "model", model_module);
1850 }
1851 }
1852 Py_DECREF(modelmod_name);
1853 if (errors_module == NULL || model_module == NULL)
1854 /* Don't core dump later! */
Fred Drake6f987622000-08-25 18:03:30 +00001855 return;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001856
Martin v. Löwisc847f402003-01-21 11:09:21 +00001857#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001858 {
1859 const XML_Feature *features = XML_GetFeatureList();
1860 PyObject *list = PyList_New(0);
1861 if (list == NULL)
1862 /* just ignore it */
1863 PyErr_Clear();
1864 else {
1865 int i = 0;
1866 for (; features[i].feature != XML_FEATURE_END; ++i) {
1867 int ok;
1868 PyObject *item = Py_BuildValue("si", features[i].name,
1869 features[i].value);
1870 if (item == NULL) {
1871 Py_DECREF(list);
1872 list = NULL;
1873 break;
1874 }
1875 ok = PyList_Append(list, item);
1876 Py_DECREF(item);
1877 if (ok < 0) {
1878 PyErr_Clear();
1879 break;
1880 }
1881 }
1882 if (list != NULL)
1883 PyModule_AddObject(m, "features", list);
1884 }
1885 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001886#endif
Fred Drake6f987622000-08-25 18:03:30 +00001887
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001888#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001889 PyModule_AddStringConstant(errors_module, #name, \
1890 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001891
Fred Drake0582df92000-07-12 04:49:00 +00001892 MYCONST(XML_ERROR_NO_MEMORY);
1893 MYCONST(XML_ERROR_SYNTAX);
1894 MYCONST(XML_ERROR_NO_ELEMENTS);
1895 MYCONST(XML_ERROR_INVALID_TOKEN);
1896 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1897 MYCONST(XML_ERROR_PARTIAL_CHAR);
1898 MYCONST(XML_ERROR_TAG_MISMATCH);
1899 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1900 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1901 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1902 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1903 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1904 MYCONST(XML_ERROR_ASYNC_ENTITY);
1905 MYCONST(XML_ERROR_BAD_CHAR_REF);
1906 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1907 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1908 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1909 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1910 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001911 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1912 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1913 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001914 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1915 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1916 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1917 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1918 /* Added in Expat 1.95.7. */
1919 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1920 /* Added in Expat 1.95.8. */
1921 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1922 MYCONST(XML_ERROR_INCOMPLETE_PE);
1923 MYCONST(XML_ERROR_XML_DECL);
1924 MYCONST(XML_ERROR_TEXT_DECL);
1925 MYCONST(XML_ERROR_PUBLICID);
1926 MYCONST(XML_ERROR_SUSPENDED);
1927 MYCONST(XML_ERROR_NOT_SUSPENDED);
1928 MYCONST(XML_ERROR_ABORTED);
1929 MYCONST(XML_ERROR_FINISHED);
1930 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001931
Fred Drake85d835f2001-02-08 15:39:08 +00001932 PyModule_AddStringConstant(errors_module, "__doc__",
1933 "Constants used to describe error conditions.");
1934
Fred Drake93adb692000-09-23 04:55:48 +00001935#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001936
Fred Drake85d835f2001-02-08 15:39:08 +00001937#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001938 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1939 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1940 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001941#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001942
Fred Drake85d835f2001-02-08 15:39:08 +00001943#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1944 PyModule_AddStringConstant(model_module, "__doc__",
1945 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001946
Fred Drake85d835f2001-02-08 15:39:08 +00001947 MYCONST(XML_CTYPE_EMPTY);
1948 MYCONST(XML_CTYPE_ANY);
1949 MYCONST(XML_CTYPE_MIXED);
1950 MYCONST(XML_CTYPE_NAME);
1951 MYCONST(XML_CTYPE_CHOICE);
1952 MYCONST(XML_CTYPE_SEQ);
1953
1954 MYCONST(XML_CQUANT_NONE);
1955 MYCONST(XML_CQUANT_OPT);
1956 MYCONST(XML_CQUANT_REP);
1957 MYCONST(XML_CQUANT_PLUS);
1958#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001959
1960 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001961 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001962 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001963 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1964 capi.MINOR_VERSION = XML_MINOR_VERSION;
1965 capi.MICRO_VERSION = XML_MICRO_VERSION;
1966 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001967 capi.GetErrorCode = XML_GetErrorCode;
1968 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1969 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001970 capi.Parse = XML_Parse;
1971 capi.ParserCreate_MM = XML_ParserCreate_MM;
1972 capi.ParserFree = XML_ParserFree;
1973 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1974 capi.SetCommentHandler = XML_SetCommentHandler;
1975 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1976 capi.SetElementHandler = XML_SetElementHandler;
1977 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1978 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1979 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1980 capi.SetUserData = XML_SetUserData;
Fredrik Lundhc3345042005-12-13 19:49:55 +00001981
1982 /* export as cobject */
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001983 capi_object = PyCObject_FromVoidPtr(&capi, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001984 if (capi_object)
1985 PyModule_AddObject(m, "expat_CAPI", capi_object);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001986}
1987
Fred Drake6f987622000-08-25 18:03:30 +00001988static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001989clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001990{
Fred Drakecde79132001-04-25 16:01:30 +00001991 int i = 0;
1992 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001993
Fred Drake71b63ff2002-06-28 22:29:01 +00001994 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001995 if (initial)
Fred Drake71b63ff2002-06-28 22:29:01 +00001996 self->handlers[i] = NULL;
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001997 else {
Fred Drakecde79132001-04-25 16:01:30 +00001998 temp = self->handlers[i];
1999 self->handlers[i] = NULL;
2000 Py_XDECREF(temp);
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002001 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002002 }
Fred Drakecde79132001-04-25 16:01:30 +00002003 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002004}
2005
Tim Peters0c322792002-07-17 16:49:03 +00002006static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002007 {"StartElementHandler",
2008 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002009 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002010 {"EndElementHandler",
2011 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002012 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002013 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002014 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2015 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002016 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002017 (xmlhandlersetter)XML_SetCharacterDataHandler,
2018 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002019 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002020 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002021 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002022 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002023 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002024 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002025 {"StartNamespaceDeclHandler",
2026 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002027 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002028 {"EndNamespaceDeclHandler",
2029 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002030 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002031 {"CommentHandler",
2032 (xmlhandlersetter)XML_SetCommentHandler,
2033 (xmlhandler)my_CommentHandler},
2034 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002035 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002036 (xmlhandler)my_StartCdataSectionHandler},
2037 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002038 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002039 (xmlhandler)my_EndCdataSectionHandler},
2040 {"DefaultHandler",
2041 (xmlhandlersetter)XML_SetDefaultHandler,
2042 (xmlhandler)my_DefaultHandler},
2043 {"DefaultHandlerExpand",
2044 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2045 (xmlhandler)my_DefaultHandlerExpandHandler},
2046 {"NotStandaloneHandler",
2047 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2048 (xmlhandler)my_NotStandaloneHandler},
2049 {"ExternalEntityRefHandler",
2050 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002051 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002052 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002053 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002054 (xmlhandler)my_StartDoctypeDeclHandler},
2055 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002056 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002057 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002058 {"EntityDeclHandler",
2059 (xmlhandlersetter)XML_SetEntityDeclHandler,
2060 (xmlhandler)my_EntityDeclHandler},
2061 {"XmlDeclHandler",
2062 (xmlhandlersetter)XML_SetXmlDeclHandler,
2063 (xmlhandler)my_XmlDeclHandler},
2064 {"ElementDeclHandler",
2065 (xmlhandlersetter)XML_SetElementDeclHandler,
2066 (xmlhandler)my_ElementDeclHandler},
2067 {"AttlistDeclHandler",
2068 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2069 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002070#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002071 {"SkippedEntityHandler",
2072 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2073 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002074#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002075
Fred Drake0582df92000-07-12 04:49:00 +00002076 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002077};