blob: aebae1c5fcd449385058b1eb1546f4627e119a44 [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
Fred Drake0582df92000-07-12 04:49:00 +0000959 if (PyFile_Check(f)) {
960 fp = PyFile_AsFile(f);
961 }
Neal Norwitz2f5e9902006-03-08 06:36:45 +0000962 else {
Fred Drake0582df92000-07-12 04:49:00 +0000963 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000964 readmethod = PyObject_GetAttrString(f, "read");
965 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000966 PyErr_Clear();
Fred Drake71b63ff2002-06-28 22:29:01 +0000967 PyErr_SetString(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000968 "argument must have 'read' attribute");
Fred Drake814f9fe2002-07-19 22:03:03 +0000969 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000970 }
971 }
972 for (;;) {
973 int bytes_read;
974 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000975 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000976 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000977 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +0000978 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000979
Fred Drake0582df92000-07-12 04:49:00 +0000980 if (fp) {
981 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
982 if (bytes_read < 0) {
983 PyErr_SetFromErrno(PyExc_IOError);
984 return NULL;
985 }
986 }
987 else {
988 bytes_read = readinst(buf, BUF_SIZE, readmethod);
Fred Drake7b6caff2003-07-21 17:05:56 +0000989 if (bytes_read < 0) {
990 Py_DECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000991 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000992 }
Fred Drake0582df92000-07-12 04:49:00 +0000993 }
994 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +0000995 if (PyErr_Occurred()) {
996 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000997 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +0000998 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000999
Fred Drake0582df92000-07-12 04:49:00 +00001000 if (!rv || bytes_read == 0)
1001 break;
1002 }
Fred Drake7b6caff2003-07-21 17:05:56 +00001003 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +00001004 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001005}
1006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001008"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001009Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001010
1011static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001012xmlparse_SetBase(xmlparseobject *self, PyObject *args)
1013{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001014 char *base;
1015
Fred Drake0582df92000-07-12 04:49:00 +00001016 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001017 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001018 if (!XML_SetBase(self->itself, base)) {
1019 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001020 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001021 Py_INCREF(Py_None);
1022 return Py_None;
1023}
1024
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001025PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001026"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001027Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001028
1029static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001030xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
Fred Drake0582df92000-07-12 04:49:00 +00001031{
Fred Drake0582df92000-07-12 04:49:00 +00001032 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001033}
1034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001035PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +00001036"GetInputContext() -> string\n\
1037Return the untranslated text of the input that caused the current event.\n\
1038If 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 +00001039for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +00001040
1041static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001042xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
Fred Drakebd6101c2001-02-14 18:29:45 +00001043{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001044 if (self->in_callback) {
1045 int offset, size;
1046 const char *buffer
1047 = XML_GetInputContext(self->itself, &offset, &size);
Fred Drakebd6101c2001-02-14 18:29:45 +00001048
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001049 if (buffer != NULL)
1050 return PyString_FromStringAndSize(buffer + offset,
1051 size - offset);
1052 else
1053 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001054 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001055 else
1056 Py_RETURN_NONE;
Fred Drakebd6101c2001-02-14 18:29:45 +00001057}
Fred Drakebd6101c2001-02-14 18:29:45 +00001058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001059PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +00001060"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +00001061Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001062information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001063
1064static PyObject *
1065xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
1066{
1067 char *context;
1068 char *encoding = NULL;
1069 xmlparseobject *new_parser;
1070 int i;
1071
Martin v. Löwisc57428d2001-09-19 09:55:09 +00001072 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +00001073 &context, &encoding)) {
1074 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001075 }
1076
Martin v. Löwis894258c2001-09-23 10:20:10 +00001077#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001078 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001079 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001080#else
1081 /* Python versions 2.2 and later */
1082 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1083#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001084
1085 if (new_parser == NULL)
1086 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001087 new_parser->buffer_size = self->buffer_size;
1088 new_parser->buffer_used = 0;
1089 if (self->buffer != NULL) {
1090 new_parser->buffer = malloc(new_parser->buffer_size);
1091 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +00001092#ifndef Py_TPFLAGS_HAVE_GC
1093 /* Code for versions 2.0 and 2.1 */
1094 PyObject_Del(new_parser);
1095#else
1096 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001097 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +00001098#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +00001099 return PyErr_NoMemory();
1100 }
1101 }
1102 else
1103 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001104 new_parser->returns_unicode = self->returns_unicode;
1105 new_parser->ordered_attributes = self->ordered_attributes;
1106 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001107 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001108 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001109 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001110 encoding);
1111 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001112 new_parser->intern = self->intern;
1113 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001114#ifdef Py_TPFLAGS_HAVE_GC
1115 PyObject_GC_Track(new_parser);
1116#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001117 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001118#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001119
1120 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001121 Py_DECREF(new_parser);
1122 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001123 }
1124
1125 XML_SetUserData(new_parser->itself, (void *)new_parser);
1126
1127 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001128 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001129 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001130
Fred Drake2a3d7db2002-06-28 22:56:48 +00001131 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001132 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001133 Py_DECREF(new_parser);
1134 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001135 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001136 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001137
1138 /* then copy handlers from self */
1139 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001140 PyObject *handler = self->handlers[i];
1141 if (handler != NULL) {
1142 Py_INCREF(handler);
1143 new_parser->handlers[i] = handler;
1144 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001145 handler_info[i].handler);
1146 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001147 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001148 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001149}
1150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001152"SetParamEntityParsing(flag) -> success\n\
1153Controls parsing of parameter entities (including the external DTD\n\
1154subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1155XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1156XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001157was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001158
1159static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001160xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001161{
Fred Drake85d835f2001-02-08 15:39:08 +00001162 int flag;
1163 if (!PyArg_ParseTuple(args, "i", &flag))
1164 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001165 flag = XML_SetParamEntityParsing(p->itself, flag);
Fred Drake85d835f2001-02-08 15:39:08 +00001166 return PyInt_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001167}
1168
Martin v. Löwisc847f402003-01-21 11:09:21 +00001169
1170#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001171PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1172"UseForeignDTD([flag])\n\
1173Allows the application to provide an artificial external subset if one is\n\
1174not specified as part of the document instance. This readily allows the\n\
1175use of a 'default' document type controlled by the application, while still\n\
1176getting the advantage of providing document type information to the parser.\n\
1177'flag' defaults to True if not provided.");
1178
1179static PyObject *
1180xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1181{
1182 PyObject *flagobj = NULL;
1183 XML_Bool flag = XML_TRUE;
1184 enum XML_Error rc;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001185 if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
Martin v. Löwis069dde22003-01-21 10:58:18 +00001186 return NULL;
1187 if (flagobj != NULL)
1188 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1189 rc = XML_UseForeignDTD(self->itself, flag);
1190 if (rc != XML_ERROR_NONE) {
1191 return set_error(self, rc);
1192 }
1193 Py_INCREF(Py_None);
1194 return Py_None;
1195}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001196#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001197
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001198static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001199 {"Parse", (PyCFunction)xmlparse_Parse,
Fred Drakebd6101c2001-02-14 18:29:45 +00001200 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001201 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001202 METH_O, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001203 {"SetBase", (PyCFunction)xmlparse_SetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001204 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001205 {"GetBase", (PyCFunction)xmlparse_GetBase,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001206 METH_NOARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001207 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001208 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001209 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
1210 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001211 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001212 METH_NOARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001213#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001214 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
1215 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001216#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001217 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001218};
1219
1220/* ---------- */
1221
1222
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001223
Fred Drake71b63ff2002-06-28 22:29:01 +00001224/* pyexpat international encoding support.
1225 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001226*/
1227
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001228static char template_buffer[257];
Fred Drakebb66a202001-03-01 20:48:17 +00001229PyObject *template_string = NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001230
Fred Drake71b63ff2002-06-28 22:29:01 +00001231static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001232init_template_buffer(void)
1233{
1234 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001235 for (i = 0; i < 256; i++) {
1236 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001237 }
Fred Drakebb66a202001-03-01 20:48:17 +00001238 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001239}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001240
Fred Drake71b63ff2002-06-28 22:29:01 +00001241static int
1242PyUnknownEncodingHandler(void *encodingHandlerData,
1243 const XML_Char *name,
1244 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001245{
Fred Drakebb66a202001-03-01 20:48:17 +00001246 PyUnicodeObject *_u_string = NULL;
1247 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001248 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001249
Fred Drakebb66a202001-03-01 20:48:17 +00001250 /* Yes, supports only 8bit encodings */
1251 _u_string = (PyUnicodeObject *)
1252 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001253
Fred Drakebb66a202001-03-01 20:48:17 +00001254 if (_u_string == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001255 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001256
Fred Drakebb66a202001-03-01 20:48:17 +00001257 for (i = 0; i < 256; i++) {
1258 /* Stupid to access directly, but fast */
1259 Py_UNICODE c = _u_string->str[i];
1260 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001261 info->map[i] = -1;
Fred Drakebb66a202001-03-01 20:48:17 +00001262 else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001263 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001264 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001265 info->data = NULL;
1266 info->convert = NULL;
1267 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001268 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001269 Py_DECREF(_u_string);
1270 return result;
1271}
1272
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001273
1274static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001275newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001276{
1277 int i;
1278 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001279
Martin v. Löwis894258c2001-09-23 10:20:10 +00001280#ifdef Py_TPFLAGS_HAVE_GC
1281 /* Code for versions 2.2 and later */
1282 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1283#else
Fred Drake0582df92000-07-12 04:49:00 +00001284 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001285#endif
Fred Drake0582df92000-07-12 04:49:00 +00001286 if (self == NULL)
1287 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001288
Fred Drake0582df92000-07-12 04:49:00 +00001289 self->returns_unicode = 1;
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001290
Fred Drake2a3d7db2002-06-28 22:56:48 +00001291 self->buffer = NULL;
1292 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1293 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001294 self->ordered_attributes = 0;
1295 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001296 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001297 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001298 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001299 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001300 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1301 }
Fred Drake85d835f2001-02-08 15:39:08 +00001302 else {
Fred Drake0582df92000-07-12 04:49:00 +00001303 self->itself = XML_ParserCreate(encoding);
1304 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001305 self->intern = intern;
1306 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001307#ifdef Py_TPFLAGS_HAVE_GC
1308 PyObject_GC_Track(self);
1309#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001310 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001311#endif
Fred Drake0582df92000-07-12 04:49:00 +00001312 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001313 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001314 "XML_ParserCreate failed");
1315 Py_DECREF(self);
1316 return NULL;
1317 }
1318 XML_SetUserData(self->itself, (void *)self);
Fred Drake7c75bf22002-07-01 14:02:31 +00001319 XML_SetUnknownEncodingHandler(self->itself,
1320 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001321
Fred Drake2a3d7db2002-06-28 22:56:48 +00001322 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001323 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001324
Fred Drake7c75bf22002-07-01 14:02:31 +00001325 self->handlers = malloc(sizeof(PyObject *) * i);
1326 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001327 Py_DECREF(self);
1328 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001329 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001330 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001331
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001332 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001333}
1334
1335
1336static void
Fred Drake0582df92000-07-12 04:49:00 +00001337xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001338{
Fred Drake0582df92000-07-12 04:49:00 +00001339 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001340#ifdef Py_TPFLAGS_HAVE_GC
1341 PyObject_GC_UnTrack(self);
1342#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001343 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001344#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001345 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001346 XML_ParserFree(self->itself);
1347 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001348
Fred Drake85d835f2001-02-08 15:39:08 +00001349 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001350 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001351 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001352 temp = self->handlers[i];
1353 self->handlers[i] = NULL;
1354 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001355 }
1356 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001357 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001358 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001359 if (self->buffer != NULL) {
1360 free(self->buffer);
1361 self->buffer = NULL;
1362 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001363 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001364#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001365 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001366 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001367#else
1368 /* Code for versions 2.2 and later. */
1369 PyObject_GC_Del(self);
1370#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001371}
1372
Fred Drake0582df92000-07-12 04:49:00 +00001373static int
1374handlername2int(const char *name)
1375{
1376 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001377 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001378 if (strcmp(name, handler_info[i].name) == 0) {
1379 return i;
1380 }
1381 }
1382 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001383}
1384
1385static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001386get_pybool(int istrue)
1387{
1388 PyObject *result = istrue ? Py_True : Py_False;
1389 Py_INCREF(result);
1390 return result;
1391}
1392
1393static PyObject *
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001394xmlparse_getattr(xmlparseobject *self, char *name)
1395{
Fred Drake71b63ff2002-06-28 22:29:01 +00001396 int handlernum = handlername2int(name);
1397
1398 if (handlernum != -1) {
1399 PyObject *result = self->handlers[handlernum];
1400 if (result == NULL)
1401 result = Py_None;
1402 Py_INCREF(result);
1403 return result;
1404 }
1405 if (name[0] == 'E') {
1406 if (strcmp(name, "ErrorCode") == 0)
1407 return PyInt_FromLong((long)
1408 XML_GetErrorCode(self->itself));
1409 if (strcmp(name, "ErrorLineNumber") == 0)
1410 return PyInt_FromLong((long)
1411 XML_GetErrorLineNumber(self->itself));
1412 if (strcmp(name, "ErrorColumnNumber") == 0)
1413 return PyInt_FromLong((long)
1414 XML_GetErrorColumnNumber(self->itself));
1415 if (strcmp(name, "ErrorByteIndex") == 0)
1416 return PyInt_FromLong((long)
1417 XML_GetErrorByteIndex(self->itself));
1418 }
Dave Cole3203efb2004-08-26 00:37:31 +00001419 if (name[0] == 'C') {
1420 if (strcmp(name, "CurrentLineNumber") == 0)
1421 return PyInt_FromLong((long)
1422 XML_GetCurrentLineNumber(self->itself));
1423 if (strcmp(name, "CurrentColumnNumber") == 0)
1424 return PyInt_FromLong((long)
1425 XML_GetCurrentColumnNumber(self->itself));
1426 if (strcmp(name, "CurrentByteIndex") == 0)
1427 return PyInt_FromLong((long)
1428 XML_GetCurrentByteIndex(self->itself));
1429 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001430 if (name[0] == 'b') {
1431 if (strcmp(name, "buffer_size") == 0)
1432 return PyInt_FromLong((long) self->buffer_size);
1433 if (strcmp(name, "buffer_text") == 0)
1434 return get_pybool(self->buffer != NULL);
1435 if (strcmp(name, "buffer_used") == 0)
1436 return PyInt_FromLong((long) self->buffer_used);
1437 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001438 if (strcmp(name, "namespace_prefixes") == 0)
1439 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001440 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001441 return get_pybool(self->ordered_attributes);
Fred Drake0582df92000-07-12 04:49:00 +00001442 if (strcmp(name, "returns_unicode") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001443 return get_pybool((long) self->returns_unicode);
Fred Drake85d835f2001-02-08 15:39:08 +00001444 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001445 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001446 if (strcmp(name, "intern") == 0) {
1447 if (self->intern == NULL) {
1448 Py_INCREF(Py_None);
1449 return Py_None;
1450 }
1451 else {
1452 Py_INCREF(self->intern);
1453 return self->intern;
1454 }
1455 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001456
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001457#define APPEND(list, str) \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001458 do { \
1459 PyObject *o = PyString_FromString(str); \
1460 if (o != NULL) \
1461 PyList_Append(list, o); \
1462 Py_XDECREF(o); \
1463 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001464
Fred Drake0582df92000-07-12 04:49:00 +00001465 if (strcmp(name, "__members__") == 0) {
1466 int i;
1467 PyObject *rc = PyList_New(0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001468 if (!rc)
1469 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001470 for (i = 0; handler_info[i].name != NULL; i++) {
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001471 PyObject *o = get_handler_name(&handler_info[i]);
1472 if (o != NULL)
1473 PyList_Append(rc, o);
1474 Py_XDECREF(o);
Fred Drake0582df92000-07-12 04:49:00 +00001475 }
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001476 APPEND(rc, "ErrorCode");
1477 APPEND(rc, "ErrorLineNumber");
1478 APPEND(rc, "ErrorColumnNumber");
1479 APPEND(rc, "ErrorByteIndex");
Dave Cole3203efb2004-08-26 00:37:31 +00001480 APPEND(rc, "CurrentLineNumber");
1481 APPEND(rc, "CurrentColumnNumber");
1482 APPEND(rc, "CurrentByteIndex");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001483 APPEND(rc, "buffer_size");
1484 APPEND(rc, "buffer_text");
1485 APPEND(rc, "buffer_used");
Martin v. Löwis069dde22003-01-21 10:58:18 +00001486 APPEND(rc, "namespace_prefixes");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001487 APPEND(rc, "ordered_attributes");
1488 APPEND(rc, "returns_unicode");
1489 APPEND(rc, "specified_attributes");
1490 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001491
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001492#undef APPEND
Fred Drake0582df92000-07-12 04:49:00 +00001493 return rc;
1494 }
1495 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001496}
1497
Fred Drake6f987622000-08-25 18:03:30 +00001498static int
1499sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001500{
1501 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001502 if (handlernum >= 0) {
1503 xmlhandler c_handler = NULL;
1504 PyObject *temp = self->handlers[handlernum];
1505
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001506 if (v == Py_None) {
1507 /* If this is the character data handler, and a character
1508 data handler is already active, we need to be more
1509 careful. What we can safely do is replace the existing
1510 character data handler callback function with a no-op
1511 function that will refuse to call Python. The downside
1512 is that this doesn't completely remove the character
1513 data handler from the C layer if there's any callback
1514 active, so Expat does a little more work than it
1515 otherwise would, but that's really an odd case. A more
1516 elaborate system of handlers and state could remove the
1517 C handler more effectively. */
1518 if (handlernum == CharacterData && self->in_callback)
1519 c_handler = noop_character_data_handler;
Fred Drake71b63ff2002-06-28 22:29:01 +00001520 v = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001521 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001522 else if (v != NULL) {
1523 Py_INCREF(v);
1524 c_handler = handler_info[handlernum].handler;
1525 }
Fred Drake0582df92000-07-12 04:49:00 +00001526 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001527 Py_XDECREF(temp);
1528 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001529 return 1;
1530 }
1531 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001532}
1533
1534static int
Fred Drake6f987622000-08-25 18:03:30 +00001535xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001536{
Fred Drake6f987622000-08-25 18:03:30 +00001537 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001538 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001539 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1540 return -1;
1541 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001542 if (strcmp(name, "buffer_text") == 0) {
1543 if (PyObject_IsTrue(v)) {
1544 if (self->buffer == NULL) {
1545 self->buffer = malloc(self->buffer_size);
1546 if (self->buffer == NULL) {
1547 PyErr_NoMemory();
1548 return -1;
1549 }
1550 self->buffer_used = 0;
1551 }
1552 }
1553 else if (self->buffer != NULL) {
1554 if (flush_character_buffer(self) < 0)
1555 return -1;
1556 free(self->buffer);
1557 self->buffer = NULL;
1558 }
1559 return 0;
1560 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001561 if (strcmp(name, "namespace_prefixes") == 0) {
1562 if (PyObject_IsTrue(v))
1563 self->ns_prefixes = 1;
1564 else
1565 self->ns_prefixes = 0;
1566 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1567 return 0;
1568 }
Fred Drake85d835f2001-02-08 15:39:08 +00001569 if (strcmp(name, "ordered_attributes") == 0) {
1570 if (PyObject_IsTrue(v))
1571 self->ordered_attributes = 1;
1572 else
1573 self->ordered_attributes = 0;
1574 return 0;
1575 }
Fred Drake6f987622000-08-25 18:03:30 +00001576 if (strcmp(name, "returns_unicode") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001577 if (PyObject_IsTrue(v)) {
Fred Drake6f987622000-08-25 18:03:30 +00001578 self->returns_unicode = 1;
Fred Drake6f987622000-08-25 18:03:30 +00001579 }
1580 else
1581 self->returns_unicode = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001582 return 0;
1583 }
1584 if (strcmp(name, "specified_attributes") == 0) {
1585 if (PyObject_IsTrue(v))
1586 self->specified_attributes = 1;
1587 else
1588 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001589 return 0;
1590 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001591 if (strcmp(name, "CharacterDataHandler") == 0) {
1592 /* If we're changing the character data handler, flush all
1593 * cached data with the old handler. Not sure there's a
1594 * "right" thing to do, though, but this probably won't
1595 * happen.
1596 */
1597 if (flush_character_buffer(self) < 0)
1598 return -1;
1599 }
Fred Drake6f987622000-08-25 18:03:30 +00001600 if (sethandler(self, name, v)) {
1601 return 0;
1602 }
1603 PyErr_SetString(PyExc_AttributeError, name);
1604 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001605}
1606
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001607static int
1608xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1609{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001610 int i;
1611 for (i = 0; handler_info[i].name != NULL; i++)
1612 Py_VISIT(op->handlers[i]);
Fred Drakecde79132001-04-25 16:01:30 +00001613 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001614}
1615
1616static int
1617xmlparse_clear(xmlparseobject *op)
1618{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001619 clear_handlers(op, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001620 Py_CLEAR(op->intern);
Fred Drakecde79132001-04-25 16:01:30 +00001621 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001622}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001625
1626static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001627 PyObject_HEAD_INIT(NULL)
1628 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001629 "pyexpat.xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001630 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001631 0, /*tp_itemsize*/
1632 /* methods */
1633 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1634 (printfunc)0, /*tp_print*/
1635 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1636 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1637 (cmpfunc)0, /*tp_compare*/
1638 (reprfunc)0, /*tp_repr*/
1639 0, /*tp_as_number*/
1640 0, /*tp_as_sequence*/
1641 0, /*tp_as_mapping*/
1642 (hashfunc)0, /*tp_hash*/
1643 (ternaryfunc)0, /*tp_call*/
1644 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001645 0, /* tp_getattro */
1646 0, /* tp_setattro */
1647 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001648#ifdef Py_TPFLAGS_HAVE_GC
Fred Drake71b63ff2002-06-28 22:29:01 +00001649 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001650#else
Fred Drake71b63ff2002-06-28 22:29:01 +00001651 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001652#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001653 Xmlparsetype__doc__, /* tp_doc - Documentation string */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001654 (traverseproc)xmlparse_traverse, /* tp_traverse */
1655 (inquiry)xmlparse_clear /* tp_clear */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001656};
1657
1658/* End of code for xmlparser objects */
1659/* -------------------------------------------------------- */
1660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001661PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001662"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001664
1665static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001666pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1667{
Fred Drakecde79132001-04-25 16:01:30 +00001668 char *encoding = NULL;
1669 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001670 PyObject *intern = NULL;
1671 PyObject *result;
1672 int intern_decref = 0;
Martin v. Löwis15e62742006-02-27 16:46:16 +00001673 static char *kwlist[] = {"encoding", "namespace_separator",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001674 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001675
Fred Drakeb91a36b2002-06-27 19:40:48 +00001676 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1677 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001678 return NULL;
1679 if (namespace_separator != NULL
1680 && strlen(namespace_separator) > 1) {
1681 PyErr_SetString(PyExc_ValueError,
1682 "namespace_separator must be at most one"
1683 " character, omitted, or None");
1684 return NULL;
1685 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001686 /* Explicitly passing None means no interning is desired.
1687 Not passing anything means that a new dictionary is used. */
1688 if (intern == Py_None)
1689 intern = NULL;
1690 else if (intern == NULL) {
1691 intern = PyDict_New();
1692 if (!intern)
1693 return NULL;
1694 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001695 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001696 else if (!PyDict_Check(intern)) {
1697 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1698 return NULL;
1699 }
1700
1701 result = newxmlparseobject(encoding, namespace_separator, intern);
1702 if (intern_decref) {
1703 Py_DECREF(intern);
1704 }
1705 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001706}
1707
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001708PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001709"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001710Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001711
1712static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001713pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001714{
Fred Drake0582df92000-07-12 04:49:00 +00001715 long code = 0;
1716
1717 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1718 return NULL;
1719 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001720}
1721
1722/* List of methods defined in the module */
1723
1724static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001725 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1726 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1727 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1728 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001729
Fred Drake0582df92000-07-12 04:49:00 +00001730 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001731};
1732
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001733/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735PyDoc_STRVAR(pyexpat_module_documentation,
1736"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001737
Fred Drake4113b132001-03-24 19:58:26 +00001738/* Return a Python string that represents the version number without the
1739 * extra cruft added by revision control, even if the right options were
1740 * given to the "cvs export" command to make it not include the extra
1741 * cruft.
1742 */
1743static PyObject *
1744get_version_string(void)
1745{
1746 static char *rcsid = "$Revision$";
1747 char *rev = rcsid;
1748 int i = 0;
1749
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001750 while (!isdigit(Py_CHARMASK(*rev)))
Fred Drake4113b132001-03-24 19:58:26 +00001751 ++rev;
1752 while (rev[i] != ' ' && rev[i] != '\0')
1753 ++i;
1754
1755 return PyString_FromStringAndSize(rev, i);
1756}
1757
Fred Drakecde79132001-04-25 16:01:30 +00001758/* Initialization function for the module */
1759
1760#ifndef MODULE_NAME
1761#define MODULE_NAME "pyexpat"
1762#endif
1763
1764#ifndef MODULE_INITFUNC
1765#define MODULE_INITFUNC initpyexpat
1766#endif
1767
Martin v. Löwis069dde22003-01-21 10:58:18 +00001768#ifndef PyMODINIT_FUNC
1769# ifdef MS_WINDOWS
1770# define PyMODINIT_FUNC __declspec(dllexport) void
1771# else
1772# define PyMODINIT_FUNC void
1773# endif
1774#endif
1775
Mark Hammond8235ea12002-07-19 06:55:41 +00001776PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001777
Martin v. Löwis069dde22003-01-21 10:58:18 +00001778PyMODINIT_FUNC
1779MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001780{
1781 PyObject *m, *d;
Fred Drakecde79132001-04-25 16:01:30 +00001782 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001783 PyObject *errors_module;
1784 PyObject *modelmod_name;
1785 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001786 PyObject *sys_modules;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001787 static struct PyExpat_CAPI capi;
1788 PyObject* capi_object;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001789
Fred Drake6f987622000-08-25 18:03:30 +00001790 if (errmod_name == NULL)
1791 return;
Fred Drakecde79132001-04-25 16:01:30 +00001792 modelmod_name = PyString_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001793 if (modelmod_name == NULL)
1794 return;
Fred Drake6f987622000-08-25 18:03:30 +00001795
Fred Drake0582df92000-07-12 04:49:00 +00001796 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001797
Fred Drake0582df92000-07-12 04:49:00 +00001798 /* Create the module and add the functions */
Fred Drakecde79132001-04-25 16:01:30 +00001799 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
Fred Drake85d835f2001-02-08 15:39:08 +00001800 pyexpat_module_documentation);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001801 if (m == NULL)
1802 return;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001803
Fred Drake0582df92000-07-12 04:49:00 +00001804 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001805 if (ErrorObject == NULL) {
1806 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001807 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001808 if (ErrorObject == NULL)
1809 return;
1810 }
1811 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001812 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001813 Py_INCREF(ErrorObject);
1814 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001815 Py_INCREF(&Xmlparsetype);
1816 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001817
Fred Drake4113b132001-03-24 19:58:26 +00001818 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001819 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1820 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001821 {
1822 XML_Expat_Version info = XML_ExpatVersionInfo();
1823 PyModule_AddObject(m, "version_info",
1824 Py_BuildValue("(iii)", info.major,
1825 info.minor, info.micro));
1826 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001827 init_template_buffer();
Fred Drake0582df92000-07-12 04:49:00 +00001828 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001829 compiled, this should check and set native_encoding
1830 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001831 */
Fred Drake93adb692000-09-23 04:55:48 +00001832 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001833
Fred Drake85d835f2001-02-08 15:39:08 +00001834 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001835 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001836 errors_module = PyDict_GetItem(d, errmod_name);
1837 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001838 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001839 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001840 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001841 /* gives away the reference to errors_module */
1842 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001843 }
1844 }
Fred Drake6f987622000-08-25 18:03:30 +00001845 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001846 model_module = PyDict_GetItem(d, modelmod_name);
1847 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001848 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001849 if (model_module != NULL) {
1850 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1851 /* gives away the reference to model_module */
1852 PyModule_AddObject(m, "model", model_module);
1853 }
1854 }
1855 Py_DECREF(modelmod_name);
1856 if (errors_module == NULL || model_module == NULL)
1857 /* Don't core dump later! */
Fred Drake6f987622000-08-25 18:03:30 +00001858 return;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001859
Martin v. Löwisc847f402003-01-21 11:09:21 +00001860#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001861 {
1862 const XML_Feature *features = XML_GetFeatureList();
1863 PyObject *list = PyList_New(0);
1864 if (list == NULL)
1865 /* just ignore it */
1866 PyErr_Clear();
1867 else {
1868 int i = 0;
1869 for (; features[i].feature != XML_FEATURE_END; ++i) {
1870 int ok;
1871 PyObject *item = Py_BuildValue("si", features[i].name,
1872 features[i].value);
1873 if (item == NULL) {
1874 Py_DECREF(list);
1875 list = NULL;
1876 break;
1877 }
1878 ok = PyList_Append(list, item);
1879 Py_DECREF(item);
1880 if (ok < 0) {
1881 PyErr_Clear();
1882 break;
1883 }
1884 }
1885 if (list != NULL)
1886 PyModule_AddObject(m, "features", list);
1887 }
1888 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001889#endif
Fred Drake6f987622000-08-25 18:03:30 +00001890
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001891#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001892 PyModule_AddStringConstant(errors_module, #name, \
1893 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001894
Fred Drake0582df92000-07-12 04:49:00 +00001895 MYCONST(XML_ERROR_NO_MEMORY);
1896 MYCONST(XML_ERROR_SYNTAX);
1897 MYCONST(XML_ERROR_NO_ELEMENTS);
1898 MYCONST(XML_ERROR_INVALID_TOKEN);
1899 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1900 MYCONST(XML_ERROR_PARTIAL_CHAR);
1901 MYCONST(XML_ERROR_TAG_MISMATCH);
1902 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1903 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1904 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1905 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1906 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1907 MYCONST(XML_ERROR_ASYNC_ENTITY);
1908 MYCONST(XML_ERROR_BAD_CHAR_REF);
1909 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1910 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1911 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1912 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1913 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001914 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1915 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1916 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001917 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1918 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1919 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1920 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1921 /* Added in Expat 1.95.7. */
1922 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1923 /* Added in Expat 1.95.8. */
1924 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1925 MYCONST(XML_ERROR_INCOMPLETE_PE);
1926 MYCONST(XML_ERROR_XML_DECL);
1927 MYCONST(XML_ERROR_TEXT_DECL);
1928 MYCONST(XML_ERROR_PUBLICID);
1929 MYCONST(XML_ERROR_SUSPENDED);
1930 MYCONST(XML_ERROR_NOT_SUSPENDED);
1931 MYCONST(XML_ERROR_ABORTED);
1932 MYCONST(XML_ERROR_FINISHED);
1933 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001934
Fred Drake85d835f2001-02-08 15:39:08 +00001935 PyModule_AddStringConstant(errors_module, "__doc__",
1936 "Constants used to describe error conditions.");
1937
Fred Drake93adb692000-09-23 04:55:48 +00001938#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001939
Fred Drake85d835f2001-02-08 15:39:08 +00001940#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001941 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1942 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1943 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001944#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001945
Fred Drake85d835f2001-02-08 15:39:08 +00001946#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1947 PyModule_AddStringConstant(model_module, "__doc__",
1948 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001949
Fred Drake85d835f2001-02-08 15:39:08 +00001950 MYCONST(XML_CTYPE_EMPTY);
1951 MYCONST(XML_CTYPE_ANY);
1952 MYCONST(XML_CTYPE_MIXED);
1953 MYCONST(XML_CTYPE_NAME);
1954 MYCONST(XML_CTYPE_CHOICE);
1955 MYCONST(XML_CTYPE_SEQ);
1956
1957 MYCONST(XML_CQUANT_NONE);
1958 MYCONST(XML_CQUANT_OPT);
1959 MYCONST(XML_CQUANT_REP);
1960 MYCONST(XML_CQUANT_PLUS);
1961#undef MYCONST
Fredrik Lundhc3345042005-12-13 19:49:55 +00001962
1963 /* initialize pyexpat dispatch table */
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001964 capi.size = sizeof(capi);
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001965 capi.magic = PyExpat_CAPI_MAGIC;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001966 capi.MAJOR_VERSION = XML_MAJOR_VERSION;
1967 capi.MINOR_VERSION = XML_MINOR_VERSION;
1968 capi.MICRO_VERSION = XML_MICRO_VERSION;
1969 capi.ErrorString = XML_ErrorString;
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001970 capi.GetErrorCode = XML_GetErrorCode;
1971 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
1972 capi.GetErrorLineNumber = XML_GetErrorLineNumber;
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001973 capi.Parse = XML_Parse;
1974 capi.ParserCreate_MM = XML_ParserCreate_MM;
1975 capi.ParserFree = XML_ParserFree;
1976 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
1977 capi.SetCommentHandler = XML_SetCommentHandler;
1978 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
1979 capi.SetElementHandler = XML_SetElementHandler;
1980 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
1981 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
1982 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
1983 capi.SetUserData = XML_SetUserData;
Fredrik Lundhc3345042005-12-13 19:49:55 +00001984
1985 /* export as cobject */
Fredrik Lundhcc117db2005-12-13 21:55:36 +00001986 capi_object = PyCObject_FromVoidPtr(&capi, NULL);
Fredrik Lundhd7a42882005-12-13 20:43:04 +00001987 if (capi_object)
1988 PyModule_AddObject(m, "expat_CAPI", capi_object);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001989}
1990
Fred Drake6f987622000-08-25 18:03:30 +00001991static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001992clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001993{
Fred Drakecde79132001-04-25 16:01:30 +00001994 int i = 0;
1995 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001996
Fred Drake71b63ff2002-06-28 22:29:01 +00001997 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001998 if (initial)
Fred Drake71b63ff2002-06-28 22:29:01 +00001999 self->handlers[i] = NULL;
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002000 else {
Fred Drakecde79132001-04-25 16:01:30 +00002001 temp = self->handlers[i];
2002 self->handlers[i] = NULL;
2003 Py_XDECREF(temp);
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002004 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002005 }
Fred Drakecde79132001-04-25 16:01:30 +00002006 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002007}
2008
Tim Peters0c322792002-07-17 16:49:03 +00002009static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002010 {"StartElementHandler",
2011 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002012 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002013 {"EndElementHandler",
2014 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002015 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002016 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002017 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2018 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002019 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002020 (xmlhandlersetter)XML_SetCharacterDataHandler,
2021 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002022 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002023 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002024 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002025 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002026 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002027 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002028 {"StartNamespaceDeclHandler",
2029 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002030 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002031 {"EndNamespaceDeclHandler",
2032 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002033 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002034 {"CommentHandler",
2035 (xmlhandlersetter)XML_SetCommentHandler,
2036 (xmlhandler)my_CommentHandler},
2037 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002038 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002039 (xmlhandler)my_StartCdataSectionHandler},
2040 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002041 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002042 (xmlhandler)my_EndCdataSectionHandler},
2043 {"DefaultHandler",
2044 (xmlhandlersetter)XML_SetDefaultHandler,
2045 (xmlhandler)my_DefaultHandler},
2046 {"DefaultHandlerExpand",
2047 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2048 (xmlhandler)my_DefaultHandlerExpandHandler},
2049 {"NotStandaloneHandler",
2050 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2051 (xmlhandler)my_NotStandaloneHandler},
2052 {"ExternalEntityRefHandler",
2053 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002054 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002055 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002056 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002057 (xmlhandler)my_StartDoctypeDeclHandler},
2058 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002059 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002060 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002061 {"EntityDeclHandler",
2062 (xmlhandlersetter)XML_SetEntityDeclHandler,
2063 (xmlhandler)my_EntityDeclHandler},
2064 {"XmlDeclHandler",
2065 (xmlhandlersetter)XML_SetXmlDeclHandler,
2066 (xmlhandler)my_XmlDeclHandler},
2067 {"ElementDeclHandler",
2068 (xmlhandlersetter)XML_SetElementDeclHandler,
2069 (xmlhandler)my_ElementDeclHandler},
2070 {"AttlistDeclHandler",
2071 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2072 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002073#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002074 {"SkippedEntityHandler",
2075 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2076 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002077#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002078
Fred Drake0582df92000-07-12 04:49:00 +00002079 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002080};