blob: 23d0e2d5ea566e12834d4c531fb9170c48e05eac [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 "compile.h"
5#include "frameobject.h"
Fred Drakea77254a2000-09-29 19:23:29 +00006#include "expat.h"
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00007
Martin v. Löwisc847f402003-01-21 11:09:21 +00008#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
9
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000010#ifndef PyDoc_STRVAR
Martin v. Löwis069dde22003-01-21 10:58:18 +000011
12/*
13 * fdrake says:
14 * Don't change the PyDoc_STR macro definition to (str), because
15 * '''the parentheses cause compile failures
16 * ("non-constant static initializer" or something like that)
17 * on some platforms (Irix?)'''
18 */
Fred Drakef57b22a2002-09-02 15:54:06 +000019#define PyDoc_STR(str) str
Fred Drake7c75bf22002-07-01 14:02:31 +000020#define PyDoc_VAR(name) static char name[]
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000021#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000022#endif
23
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +000024#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
25/* In Python 2.0 and 2.1, disabling Unicode was not possible. */
Martin v. Löwis339d0f72001-08-17 18:39:25 +000026#define Py_USING_UNICODE
Jeremy Hylton9263f572003-06-27 16:13:17 +000027#else
28#define FIX_TRACE
Martin v. Löwis339d0f72001-08-17 18:39:25 +000029#endif
30
Fred Drake0582df92000-07-12 04:49:00 +000031enum HandlerTypes {
32 StartElement,
33 EndElement,
34 ProcessingInstruction,
35 CharacterData,
36 UnparsedEntityDecl,
37 NotationDecl,
38 StartNamespaceDecl,
39 EndNamespaceDecl,
40 Comment,
41 StartCdataSection,
42 EndCdataSection,
43 Default,
44 DefaultHandlerExpand,
45 NotStandalone,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000046 ExternalEntityRef,
47 StartDoctypeDecl,
48 EndDoctypeDecl,
Fred Drake85d835f2001-02-08 15:39:08 +000049 EntityDecl,
50 XmlDecl,
51 ElementDecl,
52 AttlistDecl,
Martin v. Löwisc847f402003-01-21 11:09:21 +000053#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +000054 SkippedEntity,
Martin v. Löwisc847f402003-01-21 11:09:21 +000055#endif
Fred Drake85d835f2001-02-08 15:39:08 +000056 _DummyDecl
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000057};
58
59static PyObject *ErrorObject;
60
61/* ----------------------------------------------------- */
62
63/* Declarations for objects of type xmlparser */
64
65typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000066 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000067
Fred Drake0582df92000-07-12 04:49:00 +000068 XML_Parser itself;
Fred Drake85d835f2001-02-08 15:39:08 +000069 int returns_unicode; /* True if Unicode strings are returned;
70 if false, UTF-8 strings are returned */
71 int ordered_attributes; /* Return attributes as a list. */
72 int specified_attributes; /* Report only specified attributes. */
Fred Drakebd6101c2001-02-14 18:29:45 +000073 int in_callback; /* Is a callback active? */
Martin v. Löwis069dde22003-01-21 10:58:18 +000074 int ns_prefixes; /* Namespace-triplets mode? */
Fred Drake2a3d7db2002-06-28 22:56:48 +000075 XML_Char *buffer; /* Buffer used when accumulating characters */
76 /* NULL if not enabled */
77 int buffer_size; /* Size of buffer, in XML_Char units */
78 int buffer_used; /* Buffer units in use */
Fred Drakeb91a36b2002-06-27 19:40:48 +000079 PyObject *intern; /* Dictionary to intern strings */
Fred Drake0582df92000-07-12 04:49:00 +000080 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000081} xmlparseobject;
82
Fred Drake2a3d7db2002-06-28 22:56:48 +000083#define CHARACTER_DATA_BUFFER_SIZE 8192
84
Jeremy Hylton938ace62002-07-17 16:30:39 +000085static PyTypeObject Xmlparsetype;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000086
Fred Drake117ac852002-09-24 16:24:54 +000087typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000088typedef void* xmlhandler;
89
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000090struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000091 const char *name;
92 xmlhandlersetter setter;
93 xmlhandler handler;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +000094 PyCodeObject *tb_code;
Fred Drake71b63ff2002-06-28 22:29:01 +000095 PyObject *nameobj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000096};
97
Jeremy Hylton938ace62002-07-17 16:30:39 +000098static struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000099
Fred Drakebd6101c2001-02-14 18:29:45 +0000100/* Set an integer attribute on the error object; return true on success,
101 * false on an exception.
102 */
103static int
104set_error_attr(PyObject *err, char *name, int value)
105{
106 PyObject *v = PyInt_FromLong(value);
Fred Drake85d835f2001-02-08 15:39:08 +0000107
Fred Drakebd6101c2001-02-14 18:29:45 +0000108 if (v != NULL && PyObject_SetAttrString(err, name, v) == -1) {
109 Py_DECREF(v);
110 return 0;
111 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000112 Py_DECREF(v);
Fred Drakebd6101c2001-02-14 18:29:45 +0000113 return 1;
114}
115
116/* Build and set an Expat exception, including positioning
117 * information. Always returns NULL.
118 */
Fred Drake85d835f2001-02-08 15:39:08 +0000119static PyObject *
Martin v. Löwis069dde22003-01-21 10:58:18 +0000120set_error(xmlparseobject *self, enum XML_Error code)
Fred Drake85d835f2001-02-08 15:39:08 +0000121{
122 PyObject *err;
123 char buffer[256];
124 XML_Parser parser = self->itself;
Fred Drakebd6101c2001-02-14 18:29:45 +0000125 int lineno = XML_GetErrorLineNumber(parser);
126 int column = XML_GetErrorColumnNumber(parser);
Fred Drake85d835f2001-02-08 15:39:08 +0000127
Martin v. Löwis6b2cf0e2002-06-30 06:03:35 +0000128 /* There is no risk of overflowing this buffer, since
129 even for 64-bit integers, there is sufficient space. */
130 sprintf(buffer, "%.200s: line %i, column %i",
Fred Drakebd6101c2001-02-14 18:29:45 +0000131 XML_ErrorString(code), lineno, column);
Fred Drake85d835f2001-02-08 15:39:08 +0000132 err = PyObject_CallFunction(ErrorObject, "s", buffer);
Fred Drakebd6101c2001-02-14 18:29:45 +0000133 if ( err != NULL
134 && set_error_attr(err, "code", code)
135 && set_error_attr(err, "offset", column)
136 && set_error_attr(err, "lineno", lineno)) {
137 PyErr_SetObject(ErrorObject, err);
Fred Drake85d835f2001-02-08 15:39:08 +0000138 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000139 Py_DECREF(err);
Fred Drake85d835f2001-02-08 15:39:08 +0000140 return NULL;
141}
142
Fred Drake71b63ff2002-06-28 22:29:01 +0000143static int
144have_handler(xmlparseobject *self, int type)
145{
146 PyObject *handler = self->handlers[type];
147 return handler != NULL;
148}
149
150static PyObject *
151get_handler_name(struct HandlerInfo *hinfo)
152{
153 PyObject *name = hinfo->nameobj;
154 if (name == NULL) {
155 name = PyString_FromString(hinfo->name);
156 hinfo->nameobj = name;
157 }
158 Py_XINCREF(name);
159 return name;
160}
161
Fred Drake85d835f2001-02-08 15:39:08 +0000162
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000163#ifdef Py_USING_UNICODE
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000164/* Convert a string of XML_Chars into a Unicode string.
165 Returns None if str is a null pointer. */
166
Fred Drake0582df92000-07-12 04:49:00 +0000167static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000168conv_string_to_unicode(const XML_Char *str)
Fred Drake0582df92000-07-12 04:49:00 +0000169{
Fred Drake71b63ff2002-06-28 22:29:01 +0000170 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000171 and hence in UTF-8. */
172 /* UTF-8 from Expat, Unicode desired */
173 if (str == NULL) {
174 Py_INCREF(Py_None);
175 return Py_None;
176 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000177 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000178}
179
Fred Drake0582df92000-07-12 04:49:00 +0000180static PyObject *
181conv_string_len_to_unicode(const XML_Char *str, int len)
182{
Fred Drake71b63ff2002-06-28 22:29:01 +0000183 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake0582df92000-07-12 04:49:00 +0000184 and hence in UTF-8. */
185 /* UTF-8 from Expat, Unicode desired */
186 if (str == NULL) {
187 Py_INCREF(Py_None);
188 return Py_None;
189 }
Fred Drake6f987622000-08-25 18:03:30 +0000190 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000191}
192#endif
193
194/* Convert a string of XML_Chars into an 8-bit Python string.
195 Returns None if str is a null pointer. */
196
Fred Drake6f987622000-08-25 18:03:30 +0000197static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +0000198conv_string_to_utf8(const XML_Char *str)
Fred Drake6f987622000-08-25 18:03:30 +0000199{
Fred Drake71b63ff2002-06-28 22:29:01 +0000200 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000201 and hence in UTF-8. */
202 /* UTF-8 from Expat, UTF-8 desired */
203 if (str == NULL) {
204 Py_INCREF(Py_None);
205 return Py_None;
206 }
Fred Drakeb91a36b2002-06-27 19:40:48 +0000207 return PyString_FromString(str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000208}
209
Fred Drake6f987622000-08-25 18:03:30 +0000210static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +0000211conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000212{
Fred Drake71b63ff2002-06-28 22:29:01 +0000213 /* XXX currently this code assumes that XML_Char is 8-bit,
Fred Drake6f987622000-08-25 18:03:30 +0000214 and hence in UTF-8. */
215 /* UTF-8 from Expat, UTF-8 desired */
216 if (str == NULL) {
217 Py_INCREF(Py_None);
218 return Py_None;
219 }
220 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000221}
222
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000223/* Callback routines */
224
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000225static void clear_handlers(xmlparseobject *self, int initial);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000226
Martin v. Löwis069dde22003-01-21 10:58:18 +0000227/* This handler is used when an error has been detected, in the hope
228 that actual parsing can be terminated early. This will only help
229 if an external entity reference is encountered. */
230static int
231error_external_entity_ref_handler(XML_Parser parser,
232 const XML_Char *context,
233 const XML_Char *base,
234 const XML_Char *systemId,
235 const XML_Char *publicId)
236{
237 return 0;
238}
239
Fred Drake6f987622000-08-25 18:03:30 +0000240static void
241flag_error(xmlparseobject *self)
242{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +0000243 clear_handlers(self, 0);
Martin v. Löwis069dde22003-01-21 10:58:18 +0000244 XML_SetExternalEntityRefHandler(self->itself,
245 error_external_entity_ref_handler);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000246}
247
248static PyCodeObject*
249getcode(enum HandlerTypes slot, char* func_name, int lineno)
250{
Fred Drakebd6101c2001-02-14 18:29:45 +0000251 PyObject *code = NULL;
252 PyObject *name = NULL;
253 PyObject *nulltuple = NULL;
254 PyObject *filename = NULL;
255
256 if (handler_info[slot].tb_code == NULL) {
257 code = PyString_FromString("");
258 if (code == NULL)
259 goto failed;
260 name = PyString_FromString(func_name);
261 if (name == NULL)
262 goto failed;
263 nulltuple = PyTuple_New(0);
264 if (nulltuple == NULL)
265 goto failed;
266 filename = PyString_FromString(__FILE__);
267 handler_info[slot].tb_code =
268 PyCode_New(0, /* argcount */
269 0, /* nlocals */
270 0, /* stacksize */
271 0, /* flags */
272 code, /* code */
273 nulltuple, /* consts */
274 nulltuple, /* names */
275 nulltuple, /* varnames */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000276#if PYTHON_API_VERSION >= 1010
Fred Drakebd6101c2001-02-14 18:29:45 +0000277 nulltuple, /* freevars */
278 nulltuple, /* cellvars */
Martin v. Löwis76192ee2001-02-06 09:34:40 +0000279#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000280 filename, /* filename */
281 name, /* name */
282 lineno, /* firstlineno */
283 code /* lnotab */
284 );
285 if (handler_info[slot].tb_code == NULL)
286 goto failed;
287 Py_DECREF(code);
288 Py_DECREF(nulltuple);
289 Py_DECREF(filename);
290 Py_DECREF(name);
291 }
292 return handler_info[slot].tb_code;
293 failed:
294 Py_XDECREF(code);
295 Py_XDECREF(name);
296 return NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000297}
298
Jeremy Hylton9263f572003-06-27 16:13:17 +0000299#ifdef FIX_TRACE
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000300static int
301trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
302{
303 int result = 0;
304 if (!tstate->use_tracing || tstate->tracing)
305 return 0;
306 if (tstate->c_profilefunc != NULL) {
307 tstate->tracing++;
308 result = tstate->c_profilefunc(tstate->c_profileobj,
309 f, code , val);
310 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
311 || (tstate->c_profilefunc != NULL));
312 tstate->tracing--;
313 if (result)
314 return result;
315 }
316 if (tstate->c_tracefunc != NULL) {
317 tstate->tracing++;
318 result = tstate->c_tracefunc(tstate->c_traceobj,
319 f, code , val);
320 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
321 || (tstate->c_profilefunc != NULL));
322 tstate->tracing--;
323 }
324 return result;
325}
Jeremy Hylton9263f572003-06-27 16:13:17 +0000326
327static int
328trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
329{
330 PyObject *type, *value, *traceback, *arg;
331 int err;
332
333 if (tstate->c_tracefunc == NULL)
334 return 0;
335
336 PyErr_Fetch(&type, &value, &traceback);
337 if (value == NULL) {
338 value = Py_None;
339 Py_INCREF(value);
340 }
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000341 arg = PyTuple_Pack(3, type, value, traceback);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000342 if (arg == NULL) {
343 PyErr_Restore(type, value, traceback);
344 return 0;
345 }
346 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
347 Py_DECREF(arg);
348 if (err == 0)
349 PyErr_Restore(type, value, traceback);
350 else {
351 Py_XDECREF(type);
352 Py_XDECREF(value);
353 Py_XDECREF(traceback);
354 }
355 return err;
356}
Martin v. Löwis069dde22003-01-21 10:58:18 +0000357#endif
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000358
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000359static PyObject*
360call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
361{
Fred Drakebd6101c2001-02-14 18:29:45 +0000362 PyThreadState *tstate = PyThreadState_GET();
363 PyFrameObject *f;
364 PyObject *res;
365
366 if (c == NULL)
367 return NULL;
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000368
Jeremy Hylton9263f572003-06-27 16:13:17 +0000369 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +0000370 if (f == NULL)
371 return NULL;
372 tstate->frame = f;
Jeremy Hylton9263f572003-06-27 16:13:17 +0000373#ifdef FIX_TRACE
374 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000375 return NULL;
376 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000377#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000378 res = PyEval_CallObject(func, args);
Jeremy Hylton9263f572003-06-27 16:13:17 +0000379 if (res == NULL) {
380 if (tstate->curexc_traceback == NULL)
381 PyTraceBack_Here(f);
382#ifdef FIX_TRACE
383 if (trace_frame_exc(tstate, f) < 0) {
384 return NULL;
385 }
386 }
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000387 else {
Jeremy Hylton9263f572003-06-27 16:13:17 +0000388 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
Martin v. Löwis7d6e19d2002-08-04 08:24:49 +0000389 Py_XDECREF(res);
390 res = NULL;
391 }
392 }
Jeremy Hylton9263f572003-06-27 16:13:17 +0000393#else
394 }
Martin v. Löwis069dde22003-01-21 10:58:18 +0000395#endif
Fred Drakebd6101c2001-02-14 18:29:45 +0000396 tstate->frame = f->f_back;
397 Py_DECREF(f);
398 return res;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000399}
400
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000401#ifndef Py_USING_UNICODE
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000402#define STRING_CONV_FUNC conv_string_to_utf8
403#else
Martin v. Löwis069dde22003-01-21 10:58:18 +0000404/* Python 2.0 and later versions, when built with Unicode support */
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000405#define STRING_CONV_FUNC (self->returns_unicode \
406 ? conv_string_to_unicode : conv_string_to_utf8)
407#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000408
Fred Drakeb91a36b2002-06-27 19:40:48 +0000409static PyObject*
410string_intern(xmlparseobject *self, const char* str)
411{
412 PyObject *result = STRING_CONV_FUNC(str);
413 PyObject *value;
414 if (!self->intern)
415 return result;
416 value = PyDict_GetItem(self->intern, result);
417 if (!value) {
418 if (PyDict_SetItem(self->intern, result, result) == 0)
419 return result;
420 else
421 return NULL;
422 }
423 Py_INCREF(value);
424 Py_DECREF(result);
425 return value;
426}
427
Fred Drake2a3d7db2002-06-28 22:56:48 +0000428/* Return 0 on success, -1 on exception.
429 * flag_error() will be called before return if needed.
430 */
431static int
432call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
433{
434 PyObject *args;
435 PyObject *temp;
436
437 args = PyTuple_New(1);
438 if (args == NULL)
439 return -1;
440#ifdef Py_USING_UNICODE
441 temp = (self->returns_unicode
442 ? conv_string_len_to_unicode(buffer, len)
443 : conv_string_len_to_utf8(buffer, len));
444#else
445 temp = conv_string_len_to_utf8(buffer, len);
446#endif
447 if (temp == NULL) {
448 Py_DECREF(args);
449 flag_error(self);
450 return -1;
451 }
452 PyTuple_SET_ITEM(args, 0, temp);
453 /* temp is now a borrowed reference; consider it unused. */
454 self->in_callback = 1;
455 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
456 self->handlers[CharacterData], args);
457 /* temp is an owned reference again, or NULL */
458 self->in_callback = 0;
459 Py_DECREF(args);
460 if (temp == NULL) {
461 flag_error(self);
462 return -1;
463 }
464 Py_DECREF(temp);
465 return 0;
466}
467
468static int
469flush_character_buffer(xmlparseobject *self)
470{
471 int rc;
472 if (self->buffer == NULL || self->buffer_used == 0)
473 return 0;
474 rc = call_character_handler(self, self->buffer, self->buffer_used);
475 self->buffer_used = 0;
476 return rc;
477}
478
479static void
480my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
481{
482 xmlparseobject *self = (xmlparseobject *) userData;
483 if (self->buffer == NULL)
484 call_character_handler(self, data, len);
485 else {
486 if ((self->buffer_used + len) > self->buffer_size) {
487 if (flush_character_buffer(self) < 0)
488 return;
489 /* handler might have changed; drop the rest on the floor
490 * if there isn't a handler anymore
491 */
492 if (!have_handler(self, CharacterData))
493 return;
494 }
495 if (len > self->buffer_size) {
496 call_character_handler(self, data, len);
497 self->buffer_used = 0;
498 }
499 else {
500 memcpy(self->buffer + self->buffer_used,
501 data, len * sizeof(XML_Char));
502 self->buffer_used += len;
503 }
504 }
505}
506
Fred Drake85d835f2001-02-08 15:39:08 +0000507static void
508my_StartElementHandler(void *userData,
Fred Drake71b63ff2002-06-28 22:29:01 +0000509 const XML_Char *name, const XML_Char *atts[])
Fred Drake85d835f2001-02-08 15:39:08 +0000510{
511 xmlparseobject *self = (xmlparseobject *)userData;
512
Fred Drake71b63ff2002-06-28 22:29:01 +0000513 if (have_handler(self, StartElement)) {
Fred Drake85d835f2001-02-08 15:39:08 +0000514 PyObject *container, *rv, *args;
515 int i, max;
516
Fred Drake2a3d7db2002-06-28 22:56:48 +0000517 if (flush_character_buffer(self) < 0)
518 return;
Fred Drake85d835f2001-02-08 15:39:08 +0000519 /* Set max to the number of slots filled in atts[]; max/2 is
520 * the number of attributes we need to process.
521 */
522 if (self->specified_attributes) {
523 max = XML_GetSpecifiedAttributeCount(self->itself);
524 }
525 else {
526 max = 0;
527 while (atts[max] != NULL)
528 max += 2;
529 }
530 /* Build the container. */
531 if (self->ordered_attributes)
532 container = PyList_New(max);
533 else
534 container = PyDict_New();
535 if (container == NULL) {
536 flag_error(self);
537 return;
538 }
539 for (i = 0; i < max; i += 2) {
Fred Drakeb91a36b2002-06-27 19:40:48 +0000540 PyObject *n = string_intern(self, (XML_Char *) atts[i]);
Fred Drake85d835f2001-02-08 15:39:08 +0000541 PyObject *v;
542 if (n == NULL) {
543 flag_error(self);
544 Py_DECREF(container);
545 return;
546 }
547 v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
548 if (v == NULL) {
549 flag_error(self);
550 Py_DECREF(container);
551 Py_DECREF(n);
552 return;
553 }
554 if (self->ordered_attributes) {
555 PyList_SET_ITEM(container, i, n);
556 PyList_SET_ITEM(container, i+1, v);
557 }
558 else if (PyDict_SetItem(container, n, v)) {
559 flag_error(self);
560 Py_DECREF(n);
561 Py_DECREF(v);
562 return;
563 }
564 else {
565 Py_DECREF(n);
566 Py_DECREF(v);
567 }
568 }
Fred Drakeb91a36b2002-06-27 19:40:48 +0000569 args = Py_BuildValue("(NN)", string_intern(self, name), container);
Fred Drake85d835f2001-02-08 15:39:08 +0000570 if (args == NULL) {
571 Py_DECREF(container);
572 return;
573 }
574 /* Container is now a borrowed reference; ignore it. */
Fred Drakebd6101c2001-02-14 18:29:45 +0000575 self->in_callback = 1;
576 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
Fred Drake85d835f2001-02-08 15:39:08 +0000577 self->handlers[StartElement], args);
Fred Drakebd6101c2001-02-14 18:29:45 +0000578 self->in_callback = 0;
579 Py_DECREF(args);
Fred Drake85d835f2001-02-08 15:39:08 +0000580 if (rv == NULL) {
581 flag_error(self);
582 return;
Fred Drakebd6101c2001-02-14 18:29:45 +0000583 }
Fred Drake85d835f2001-02-08 15:39:08 +0000584 Py_DECREF(rv);
585 }
586}
587
588#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
589 RETURN, GETUSERDATA) \
590static RC \
591my_##NAME##Handler PARAMS {\
592 xmlparseobject *self = GETUSERDATA ; \
593 PyObject *args = NULL; \
594 PyObject *rv = NULL; \
595 INIT \
596\
Fred Drake71b63ff2002-06-28 22:29:01 +0000597 if (have_handler(self, NAME)) { \
Fred Drake2a3d7db2002-06-28 22:56:48 +0000598 if (flush_character_buffer(self) < 0) \
599 return RETURN; \
Fred Drake85d835f2001-02-08 15:39:08 +0000600 args = Py_BuildValue PARAM_FORMAT ;\
Martin v. Löwis1d7c55f2001-11-10 13:57:55 +0000601 if (!args) { flag_error(self); return RETURN;} \
Fred Drakebd6101c2001-02-14 18:29:45 +0000602 self->in_callback = 1; \
Fred Drake85d835f2001-02-08 15:39:08 +0000603 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
604 self->handlers[NAME], args); \
Fred Drakebd6101c2001-02-14 18:29:45 +0000605 self->in_callback = 0; \
Fred Drake85d835f2001-02-08 15:39:08 +0000606 Py_DECREF(args); \
607 if (rv == NULL) { \
608 flag_error(self); \
609 return RETURN; \
610 } \
611 CONVERSION \
612 Py_DECREF(rv); \
613 } \
614 return RETURN; \
615}
616
Fred Drake6f987622000-08-25 18:03:30 +0000617#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
618 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
619 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000620
Fred Drake6f987622000-08-25 18:03:30 +0000621#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
622 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
623 rc = PyInt_AsLong(rv);, rc, \
624 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000625
Fred Drake71b63ff2002-06-28 22:29:01 +0000626VOID_HANDLER(EndElement,
627 (void *userData, const XML_Char *name),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000628 ("(N)", string_intern(self, name)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000629
Fred Drake6f987622000-08-25 18:03:30 +0000630VOID_HANDLER(ProcessingInstruction,
Fred Drake71b63ff2002-06-28 22:29:01 +0000631 (void *userData,
632 const XML_Char *target,
Fred Drake85d835f2001-02-08 15:39:08 +0000633 const XML_Char *data),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000634 ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000635
Fred Drake6f987622000-08-25 18:03:30 +0000636VOID_HANDLER(UnparsedEntityDecl,
Fred Drake71b63ff2002-06-28 22:29:01 +0000637 (void *userData,
Fred Drake85d835f2001-02-08 15:39:08 +0000638 const XML_Char *entityName,
639 const XML_Char *base,
640 const XML_Char *systemId,
641 const XML_Char *publicId,
642 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000643 ("(NNNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000644 string_intern(self, entityName), string_intern(self, base),
645 string_intern(self, systemId), string_intern(self, publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000646 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000647
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000648#ifndef Py_USING_UNICODE
Fred Drake85d835f2001-02-08 15:39:08 +0000649VOID_HANDLER(EntityDecl,
650 (void *userData,
651 const XML_Char *entityName,
652 int is_parameter_entity,
653 const XML_Char *value,
654 int value_length,
655 const XML_Char *base,
656 const XML_Char *systemId,
657 const XML_Char *publicId,
658 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000659 ("NiNNNNN",
660 string_intern(self, entityName), is_parameter_entity,
Fred Drake85d835f2001-02-08 15:39:08 +0000661 conv_string_len_to_utf8(value, value_length),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000662 string_intern(self, base), string_intern(self, systemId),
663 string_intern(self, publicId),
664 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000665#else
666VOID_HANDLER(EntityDecl,
667 (void *userData,
668 const XML_Char *entityName,
669 int is_parameter_entity,
670 const XML_Char *value,
671 int value_length,
672 const XML_Char *base,
673 const XML_Char *systemId,
674 const XML_Char *publicId,
675 const XML_Char *notationName),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000676 ("NiNNNNN",
677 string_intern(self, entityName), is_parameter_entity,
Fred Drake71b63ff2002-06-28 22:29:01 +0000678 (self->returns_unicode
679 ? conv_string_len_to_unicode(value, value_length)
Fred Drake85d835f2001-02-08 15:39:08 +0000680 : conv_string_len_to_utf8(value, value_length)),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000681 string_intern(self, base), string_intern(self, systemId),
682 string_intern(self, publicId),
683 string_intern(self, notationName)))
Fred Drake85d835f2001-02-08 15:39:08 +0000684#endif
685
686VOID_HANDLER(XmlDecl,
687 (void *userData,
688 const XML_Char *version,
689 const XML_Char *encoding,
690 int standalone),
691 ("(O&O&i)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000692 STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
Fred Drake85d835f2001-02-08 15:39:08 +0000693 standalone))
694
695static PyObject *
696conv_content_model(XML_Content * const model,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000697 PyObject *(*conv_string)(const XML_Char *))
Fred Drake85d835f2001-02-08 15:39:08 +0000698{
699 PyObject *result = NULL;
700 PyObject *children = PyTuple_New(model->numchildren);
701 int i;
702
703 if (children != NULL) {
Tim Peters9544fc52001-07-28 09:36:36 +0000704 assert(model->numchildren < INT_MAX);
705 for (i = 0; i < (int)model->numchildren; ++i) {
Fred Drake85d835f2001-02-08 15:39:08 +0000706 PyObject *child = conv_content_model(&model->children[i],
707 conv_string);
708 if (child == NULL) {
709 Py_XDECREF(children);
710 return NULL;
711 }
712 PyTuple_SET_ITEM(children, i, child);
713 }
714 result = Py_BuildValue("(iiO&N)",
715 model->type, model->quant,
716 conv_string,model->name, children);
717 }
718 return result;
719}
720
Fred Drake06dd8cf2003-02-02 03:54:17 +0000721static void
722my_ElementDeclHandler(void *userData,
723 const XML_Char *name,
724 XML_Content *model)
Fred Drake85d835f2001-02-08 15:39:08 +0000725{
Fred Drake06dd8cf2003-02-02 03:54:17 +0000726 xmlparseobject *self = (xmlparseobject *)userData;
727 PyObject *args = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +0000728
Fred Drake06dd8cf2003-02-02 03:54:17 +0000729 if (have_handler(self, ElementDecl)) {
730 PyObject *rv = NULL;
731 PyObject *modelobj, *nameobj;
732
733 if (flush_character_buffer(self) < 0)
734 goto finally;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000735#ifdef Py_USING_UNICODE
Fred Drake06dd8cf2003-02-02 03:54:17 +0000736 modelobj = conv_content_model(model,
737 (self->returns_unicode
738 ? conv_string_to_unicode
739 : conv_string_to_utf8));
Fred Drake85d835f2001-02-08 15:39:08 +0000740#else
Fred Drake06dd8cf2003-02-02 03:54:17 +0000741 modelobj = conv_content_model(model, conv_string_to_utf8);
Fred Drake85d835f2001-02-08 15:39:08 +0000742#endif
Fred Drake06dd8cf2003-02-02 03:54:17 +0000743 if (modelobj == NULL) {
744 flag_error(self);
745 goto finally;
746 }
747 nameobj = string_intern(self, name);
748 if (nameobj == NULL) {
749 Py_DECREF(modelobj);
750 flag_error(self);
751 goto finally;
752 }
Michael W. Hudson0bb84542004-08-03 11:31:31 +0000753 args = Py_BuildValue("NN", nameobj, modelobj);
Fred Drake06dd8cf2003-02-02 03:54:17 +0000754 if (args == NULL) {
755 Py_DECREF(modelobj);
756 flag_error(self);
757 goto finally;
758 }
759 self->in_callback = 1;
760 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
761 self->handlers[ElementDecl], args);
762 self->in_callback = 0;
763 if (rv == NULL) {
764 flag_error(self);
765 goto finally;
766 }
767 Py_DECREF(rv);
768 }
769 finally:
770 Py_XDECREF(args);
771 XML_FreeContentModel(self->itself, model);
772 return;
773}
Fred Drake85d835f2001-02-08 15:39:08 +0000774
775VOID_HANDLER(AttlistDecl,
776 (void *userData,
777 const XML_Char *elname,
778 const XML_Char *attname,
779 const XML_Char *att_type,
780 const XML_Char *dflt,
781 int isrequired),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000782 ("(NNO&O&i)",
783 string_intern(self, elname), string_intern(self, attname),
Fred Drake85d835f2001-02-08 15:39:08 +0000784 STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
785 isrequired))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000786
Martin v. Löwisc847f402003-01-21 11:09:21 +0000787#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +0000788VOID_HANDLER(SkippedEntity,
789 (void *userData,
790 const XML_Char *entityName,
791 int is_parameter_entity),
792 ("Ni",
793 string_intern(self, entityName), is_parameter_entity))
Martin v. Löwisc847f402003-01-21 11:09:21 +0000794#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +0000795
Fred Drake71b63ff2002-06-28 22:29:01 +0000796VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000797 (void *userData,
798 const XML_Char *notationName,
799 const XML_Char *base,
800 const XML_Char *systemId,
801 const XML_Char *publicId),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000802 ("(NNNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000803 string_intern(self, notationName), string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000804 string_intern(self, systemId), string_intern(self, publicId)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000805
Fred Drake6f987622000-08-25 18:03:30 +0000806VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000807 (void *userData,
808 const XML_Char *prefix,
809 const XML_Char *uri),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000810 ("(NN)",
811 string_intern(self, prefix), string_intern(self, uri)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000812
Fred Drake6f987622000-08-25 18:03:30 +0000813VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000814 (void *userData,
815 const XML_Char *prefix),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000816 ("(N)", string_intern(self, prefix)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000817
Fred Drake6f987622000-08-25 18:03:30 +0000818VOID_HANDLER(Comment,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000819 (void *userData, const XML_Char *data),
820 ("(O&)", STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000821
Fred Drake6f987622000-08-25 18:03:30 +0000822VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000823 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000824 ("()"))
Fred Drake71b63ff2002-06-28 22:29:01 +0000825
Fred Drake6f987622000-08-25 18:03:30 +0000826VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000827 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000828 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000829
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000830#ifndef Py_USING_UNICODE
Fred Drake6f987622000-08-25 18:03:30 +0000831VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000832 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000833 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000834
Fred Drake6f987622000-08-25 18:03:30 +0000835VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000836 (void *userData, const XML_Char *s, int len),
Fred Drakeca1f4262000-09-21 20:10:23 +0000837 ("(N)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000838#else
Fred Drake6f987622000-08-25 18:03:30 +0000839VOID_HANDLER(Default,
Fred Drake71b63ff2002-06-28 22:29:01 +0000840 (void *userData, const XML_Char *s, int len),
841 ("(N)", (self->returns_unicode
842 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000843 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000844
Fred Drake6f987622000-08-25 18:03:30 +0000845VOID_HANDLER(DefaultHandlerExpand,
Fred Drake71b63ff2002-06-28 22:29:01 +0000846 (void *userData, const XML_Char *s, int len),
847 ("(N)", (self->returns_unicode
848 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000849 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000850#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000851
Fred Drake71b63ff2002-06-28 22:29:01 +0000852INT_HANDLER(NotStandalone,
853 (void *userData),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000854 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000855
Fred Drake6f987622000-08-25 18:03:30 +0000856RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000857 (XML_Parser parser,
858 const XML_Char *context,
859 const XML_Char *base,
860 const XML_Char *systemId,
861 const XML_Char *publicId),
862 int rc=0;,
Fred Drakeb91a36b2002-06-27 19:40:48 +0000863 ("(O&NNN)",
Fred Drake71b63ff2002-06-28 22:29:01 +0000864 STRING_CONV_FUNC,context, string_intern(self, base),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000865 string_intern(self, systemId), string_intern(self, publicId)),
Fred Drake6f987622000-08-25 18:03:30 +0000866 rc = PyInt_AsLong(rv);, rc,
867 XML_GetUserData(parser))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000868
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000869/* XXX UnknownEncodingHandler */
870
Fred Drake85d835f2001-02-08 15:39:08 +0000871VOID_HANDLER(StartDoctypeDecl,
872 (void *userData, const XML_Char *doctypeName,
873 const XML_Char *sysid, const XML_Char *pubid,
874 int has_internal_subset),
Fred Drakeb91a36b2002-06-27 19:40:48 +0000875 ("(NNNi)", string_intern(self, doctypeName),
876 string_intern(self, sysid), string_intern(self, pubid),
Fred Drake85d835f2001-02-08 15:39:08 +0000877 has_internal_subset))
Martin v. Löwis0078f6c2001-01-21 10:18:10 +0000878
879VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000880
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000881/* ---------------------------------------------------------------- */
882
Fred Drake71b63ff2002-06-28 22:29:01 +0000883static PyObject *
884get_parse_result(xmlparseobject *self, int rv)
885{
886 if (PyErr_Occurred()) {
887 return NULL;
888 }
889 if (rv == 0) {
Martin v. Löwis069dde22003-01-21 10:58:18 +0000890 return set_error(self, XML_GetErrorCode(self->itself));
Fred Drake71b63ff2002-06-28 22:29:01 +0000891 }
Fred Drake2a3d7db2002-06-28 22:56:48 +0000892 if (flush_character_buffer(self) < 0) {
893 return NULL;
894 }
Fred Drake71b63ff2002-06-28 22:29:01 +0000895 return PyInt_FromLong(rv);
896}
897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000898PyDoc_STRVAR(xmlparse_Parse__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000899"Parse(data[, isfinal])\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000900Parse XML data. `isfinal' should be true at end of input.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000901
902static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000903xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000904{
Fred Drake0582df92000-07-12 04:49:00 +0000905 char *s;
906 int slen;
907 int isFinal = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000908
Fred Drake0582df92000-07-12 04:49:00 +0000909 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
910 return NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +0000911
912 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000913}
914
Fred Drakeca1f4262000-09-21 20:10:23 +0000915/* File reading copied from cPickle */
916
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000917#define BUF_SIZE 2048
918
Fred Drake0582df92000-07-12 04:49:00 +0000919static int
920readinst(char *buf, int buf_size, PyObject *meth)
921{
922 PyObject *arg = NULL;
923 PyObject *bytes = NULL;
924 PyObject *str = NULL;
925 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000926
Fred Drake676940b2000-09-22 15:21:31 +0000927 if ((bytes = PyInt_FromLong(buf_size)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000928 goto finally;
Fred Drake676940b2000-09-22 15:21:31 +0000929
Fred Drake7b6caff2003-07-21 17:05:56 +0000930 if ((arg = PyTuple_New(1)) == NULL) {
931 Py_DECREF(bytes);
Fred Drake0582df92000-07-12 04:49:00 +0000932 goto finally;
Fred Drake7b6caff2003-07-21 17:05:56 +0000933 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000934
Tim Peters954eef72000-09-22 06:01:11 +0000935 PyTuple_SET_ITEM(arg, 0, bytes);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000936
Guido van Rossum84b2bed2002-08-16 17:01:09 +0000937 if ((str = PyObject_Call(meth, arg, NULL)) == NULL)
Fred Drake0582df92000-07-12 04:49:00 +0000938 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000939
Fred Drake0582df92000-07-12 04:49:00 +0000940 /* XXX what to do if it returns a Unicode string? */
Fred Drakeca1f4262000-09-21 20:10:23 +0000941 if (!PyString_Check(str)) {
Fred Drake71b63ff2002-06-28 22:29:01 +0000942 PyErr_Format(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000943 "read() did not return a string object (type=%.400s)",
944 str->ob_type->tp_name);
945 goto finally;
946 }
947 len = PyString_GET_SIZE(str);
948 if (len > buf_size) {
949 PyErr_Format(PyExc_ValueError,
950 "read() returned too much data: "
951 "%i bytes requested, %i returned",
952 buf_size, len);
Fred Drake0582df92000-07-12 04:49:00 +0000953 goto finally;
954 }
955 memcpy(buf, PyString_AsString(str), len);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000956finally:
Fred Drake0582df92000-07-12 04:49:00 +0000957 Py_XDECREF(arg);
Fred Drakeca1f4262000-09-21 20:10:23 +0000958 Py_XDECREF(str);
Fred Drake0582df92000-07-12 04:49:00 +0000959 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000960}
961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000962PyDoc_STRVAR(xmlparse_ParseFile__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +0000963"ParseFile(file)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000964Parse XML data from file-like object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000965
966static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000967xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000968{
Fred Drake0582df92000-07-12 04:49:00 +0000969 int rv = 1;
970 PyObject *f;
971 FILE *fp;
972 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000973
Fred Drake0582df92000-07-12 04:49:00 +0000974 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
975 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000976
Fred Drake0582df92000-07-12 04:49:00 +0000977 if (PyFile_Check(f)) {
978 fp = PyFile_AsFile(f);
979 }
980 else{
981 fp = NULL;
Fred Drakeca1f4262000-09-21 20:10:23 +0000982 readmethod = PyObject_GetAttrString(f, "read");
983 if (readmethod == NULL) {
Fred Drake0582df92000-07-12 04:49:00 +0000984 PyErr_Clear();
Fred Drake71b63ff2002-06-28 22:29:01 +0000985 PyErr_SetString(PyExc_TypeError,
Fred Drake0582df92000-07-12 04:49:00 +0000986 "argument must have 'read' attribute");
Fred Drake814f9fe2002-07-19 22:03:03 +0000987 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000988 }
989 }
990 for (;;) {
991 int bytes_read;
992 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
Fred Drake7b6caff2003-07-21 17:05:56 +0000993 if (buf == NULL) {
Fred Drakef239c6d2003-07-21 17:22:43 +0000994 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +0000995 return PyErr_NoMemory();
Fred Drake7b6caff2003-07-21 17:05:56 +0000996 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000997
Fred Drake0582df92000-07-12 04:49:00 +0000998 if (fp) {
999 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
1000 if (bytes_read < 0) {
1001 PyErr_SetFromErrno(PyExc_IOError);
1002 return NULL;
1003 }
1004 }
1005 else {
1006 bytes_read = readinst(buf, BUF_SIZE, readmethod);
Fred Drake7b6caff2003-07-21 17:05:56 +00001007 if (bytes_read < 0) {
1008 Py_DECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001009 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001010 }
Fred Drake0582df92000-07-12 04:49:00 +00001011 }
1012 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
Fred Drake7b6caff2003-07-21 17:05:56 +00001013 if (PyErr_Occurred()) {
1014 Py_XDECREF(readmethod);
Fred Drake0582df92000-07-12 04:49:00 +00001015 return NULL;
Fred Drake7b6caff2003-07-21 17:05:56 +00001016 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001017
Fred Drake0582df92000-07-12 04:49:00 +00001018 if (!rv || bytes_read == 0)
1019 break;
1020 }
Fred Drake7b6caff2003-07-21 17:05:56 +00001021 Py_XDECREF(readmethod);
Fred Drake71b63ff2002-06-28 22:29:01 +00001022 return get_parse_result(self, rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001023}
1024
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001025PyDoc_STRVAR(xmlparse_SetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001026"SetBase(base_url)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001027Set the base URL for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001028
1029static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001030xmlparse_SetBase(xmlparseobject *self, PyObject *args)
1031{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001032 char *base;
1033
Fred Drake0582df92000-07-12 04:49:00 +00001034 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001035 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001036 if (!XML_SetBase(self->itself, base)) {
1037 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001038 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001039 Py_INCREF(Py_None);
1040 return Py_None;
1041}
1042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001043PyDoc_STRVAR(xmlparse_GetBase__doc__,
Thomas Wouters35317302000-07-22 16:34:15 +00001044"GetBase() -> url\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001045Return base URL string for the parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001046
1047static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001048xmlparse_GetBase(xmlparseobject *self, PyObject *args)
1049{
1050 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001051 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001052
Fred Drake0582df92000-07-12 04:49:00 +00001053 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001054}
1055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001056PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
Fred Drakebd6101c2001-02-14 18:29:45 +00001057"GetInputContext() -> string\n\
1058Return the untranslated text of the input that caused the current event.\n\
1059If 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 +00001060for an element with many attributes), not all of the text may be available.");
Fred Drakebd6101c2001-02-14 18:29:45 +00001061
1062static PyObject *
1063xmlparse_GetInputContext(xmlparseobject *self, PyObject *args)
1064{
1065 PyObject *result = NULL;
1066
1067 if (PyArg_ParseTuple(args, ":GetInputContext")) {
1068 if (self->in_callback) {
1069 int offset, size;
1070 const char *buffer
1071 = XML_GetInputContext(self->itself, &offset, &size);
1072
1073 if (buffer != NULL)
1074 result = PyString_FromStringAndSize(buffer + offset, size);
1075 else {
1076 result = Py_None;
1077 Py_INCREF(result);
1078 }
1079 }
1080 else {
1081 result = Py_None;
1082 Py_INCREF(result);
1083 }
1084 }
1085 return result;
1086}
Fred Drakebd6101c2001-02-14 18:29:45 +00001087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001088PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
Fred Drake2d4ac202001-01-03 15:36:25 +00001089"ExternalEntityParserCreate(context[, encoding])\n\
Tim Peters51dc9682000-09-24 22:12:45 +00001090Create a parser for parsing an external entity based on the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001091information passed to the ExternalEntityRefHandler.");
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001092
1093static PyObject *
1094xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
1095{
1096 char *context;
1097 char *encoding = NULL;
1098 xmlparseobject *new_parser;
1099 int i;
1100
Martin v. Löwisc57428d2001-09-19 09:55:09 +00001101 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
Fred Drakecde79132001-04-25 16:01:30 +00001102 &context, &encoding)) {
1103 return NULL;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001104 }
1105
Martin v. Löwis894258c2001-09-23 10:20:10 +00001106#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001107 /* Python versions 2.0 and 2.1 */
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001108 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001109#else
1110 /* Python versions 2.2 and later */
1111 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1112#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001113
1114 if (new_parser == NULL)
1115 return NULL;
Fred Drake2a3d7db2002-06-28 22:56:48 +00001116 new_parser->buffer_size = self->buffer_size;
1117 new_parser->buffer_used = 0;
1118 if (self->buffer != NULL) {
1119 new_parser->buffer = malloc(new_parser->buffer_size);
1120 if (new_parser->buffer == NULL) {
Fred Drakeb28467b2002-07-02 15:44:36 +00001121#ifndef Py_TPFLAGS_HAVE_GC
1122 /* Code for versions 2.0 and 2.1 */
1123 PyObject_Del(new_parser);
1124#else
1125 /* Code for versions 2.2 and later. */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001126 PyObject_GC_Del(new_parser);
Fred Drakeb28467b2002-07-02 15:44:36 +00001127#endif
Fred Drake2a3d7db2002-06-28 22:56:48 +00001128 return PyErr_NoMemory();
1129 }
1130 }
1131 else
1132 new_parser->buffer = NULL;
Fred Drake85d835f2001-02-08 15:39:08 +00001133 new_parser->returns_unicode = self->returns_unicode;
1134 new_parser->ordered_attributes = self->ordered_attributes;
1135 new_parser->specified_attributes = self->specified_attributes;
Fred Drakebd6101c2001-02-14 18:29:45 +00001136 new_parser->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001137 new_parser->ns_prefixes = self->ns_prefixes;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001138 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001139 encoding);
1140 new_parser->handlers = 0;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001141 new_parser->intern = self->intern;
1142 Py_XINCREF(new_parser->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001143#ifdef Py_TPFLAGS_HAVE_GC
1144 PyObject_GC_Track(new_parser);
1145#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001146 PyObject_GC_Init(new_parser);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001147#endif
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001148
1149 if (!new_parser->itself) {
Fred Drake85d835f2001-02-08 15:39:08 +00001150 Py_DECREF(new_parser);
1151 return PyErr_NoMemory();
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001152 }
1153
1154 XML_SetUserData(new_parser->itself, (void *)new_parser);
1155
1156 /* allocate and clear handlers first */
Fred Drake2a3d7db2002-06-28 22:56:48 +00001157 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake85d835f2001-02-08 15:39:08 +00001158 /* do nothing */;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001159
Fred Drake2a3d7db2002-06-28 22:56:48 +00001160 new_parser->handlers = malloc(sizeof(PyObject *) * i);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001161 if (!new_parser->handlers) {
Fred Drake85d835f2001-02-08 15:39:08 +00001162 Py_DECREF(new_parser);
1163 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001164 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001165 clear_handlers(new_parser, 1);
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001166
1167 /* then copy handlers from self */
1168 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001169 PyObject *handler = self->handlers[i];
1170 if (handler != NULL) {
1171 Py_INCREF(handler);
1172 new_parser->handlers[i] = handler;
1173 handler_info[i].setter(new_parser->itself,
Fred Drake85d835f2001-02-08 15:39:08 +00001174 handler_info[i].handler);
1175 }
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001176 }
Fred Drake71b63ff2002-06-28 22:29:01 +00001177 return (PyObject *)new_parser;
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001178}
1179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001180PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001181"SetParamEntityParsing(flag) -> success\n\
1182Controls parsing of parameter entities (including the external DTD\n\
1183subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
1184XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
1185XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001186was successful.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001187
1188static PyObject*
Fred Drakebd6101c2001-02-14 18:29:45 +00001189xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001190{
Fred Drake85d835f2001-02-08 15:39:08 +00001191 int flag;
1192 if (!PyArg_ParseTuple(args, "i", &flag))
1193 return NULL;
Fred Drakebd6101c2001-02-14 18:29:45 +00001194 flag = XML_SetParamEntityParsing(p->itself, flag);
Fred Drake85d835f2001-02-08 15:39:08 +00001195 return PyInt_FromLong(flag);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001196}
1197
Martin v. Löwisc847f402003-01-21 11:09:21 +00001198
1199#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001200PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
1201"UseForeignDTD([flag])\n\
1202Allows the application to provide an artificial external subset if one is\n\
1203not specified as part of the document instance. This readily allows the\n\
1204use of a 'default' document type controlled by the application, while still\n\
1205getting the advantage of providing document type information to the parser.\n\
1206'flag' defaults to True if not provided.");
1207
1208static PyObject *
1209xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
1210{
1211 PyObject *flagobj = NULL;
1212 XML_Bool flag = XML_TRUE;
1213 enum XML_Error rc;
1214 if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))
1215 return NULL;
1216 if (flagobj != NULL)
1217 flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
1218 rc = XML_UseForeignDTD(self->itself, flag);
1219 if (rc != XML_ERROR_NONE) {
1220 return set_error(self, rc);
1221 }
1222 Py_INCREF(Py_None);
1223 return Py_None;
1224}
Martin v. Löwisc847f402003-01-21 11:09:21 +00001225#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001226
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001227static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001228 {"Parse", (PyCFunction)xmlparse_Parse,
Fred Drakebd6101c2001-02-14 18:29:45 +00001229 METH_VARARGS, xmlparse_Parse__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001230 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
Fred Drakebd6101c2001-02-14 18:29:45 +00001231 METH_VARARGS, xmlparse_ParseFile__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001232 {"SetBase", (PyCFunction)xmlparse_SetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001233 METH_VARARGS, xmlparse_SetBase__doc__},
Fred Drake0582df92000-07-12 04:49:00 +00001234 {"GetBase", (PyCFunction)xmlparse_GetBase,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001235 METH_VARARGS, xmlparse_GetBase__doc__},
Lars Gustäbel4a30a072000-09-24 20:50:52 +00001236 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
Martin v. Löwis069dde22003-01-21 10:58:18 +00001237 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001238 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
1239 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
Fred Drakebd6101c2001-02-14 18:29:45 +00001240 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
1241 METH_VARARGS, xmlparse_GetInputContext__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001242#if XML_COMBINED_VERSION >= 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001243 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
1244 METH_VARARGS, xmlparse_UseForeignDTD__doc__},
Martin v. Löwisc847f402003-01-21 11:09:21 +00001245#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001246 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001247};
1248
1249/* ---------- */
1250
1251
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001252#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001253
Fred Drake71b63ff2002-06-28 22:29:01 +00001254/* pyexpat international encoding support.
1255 Make it as simple as possible.
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001256*/
1257
Martin v. Löwis3af7cc02001-01-22 08:19:10 +00001258static char template_buffer[257];
Fred Drakebb66a202001-03-01 20:48:17 +00001259PyObject *template_string = NULL;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001260
Fred Drake71b63ff2002-06-28 22:29:01 +00001261static void
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001262init_template_buffer(void)
1263{
1264 int i;
Fred Drakebb66a202001-03-01 20:48:17 +00001265 for (i = 0; i < 256; i++) {
1266 template_buffer[i] = i;
Tim Peters63cb99e2001-02-17 18:12:50 +00001267 }
Fred Drakebb66a202001-03-01 20:48:17 +00001268 template_buffer[256] = 0;
Tim Peters63cb99e2001-02-17 18:12:50 +00001269}
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001270
Fred Drake71b63ff2002-06-28 22:29:01 +00001271static int
1272PyUnknownEncodingHandler(void *encodingHandlerData,
1273 const XML_Char *name,
1274 XML_Encoding *info)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001275{
Fred Drakebb66a202001-03-01 20:48:17 +00001276 PyUnicodeObject *_u_string = NULL;
1277 int result = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001278 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001279
Fred Drakebb66a202001-03-01 20:48:17 +00001280 /* Yes, supports only 8bit encodings */
1281 _u_string = (PyUnicodeObject *)
1282 PyUnicode_Decode(template_buffer, 256, name, "replace");
Fred Drake71b63ff2002-06-28 22:29:01 +00001283
Fred Drakebb66a202001-03-01 20:48:17 +00001284 if (_u_string == NULL)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001285 return result;
Fred Drake71b63ff2002-06-28 22:29:01 +00001286
Fred Drakebb66a202001-03-01 20:48:17 +00001287 for (i = 0; i < 256; i++) {
1288 /* Stupid to access directly, but fast */
1289 Py_UNICODE c = _u_string->str[i];
1290 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001291 info->map[i] = -1;
Fred Drakebb66a202001-03-01 20:48:17 +00001292 else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001293 info->map[i] = c;
Tim Peters63cb99e2001-02-17 18:12:50 +00001294 }
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001295 info->data = NULL;
1296 info->convert = NULL;
1297 info->release = NULL;
Fred Drake71b63ff2002-06-28 22:29:01 +00001298 result = 1;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001299 Py_DECREF(_u_string);
1300 return result;
1301}
1302
1303#endif
1304
1305static PyObject *
Fred Drakeb91a36b2002-06-27 19:40:48 +00001306newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
Fred Drake0582df92000-07-12 04:49:00 +00001307{
1308 int i;
1309 xmlparseobject *self;
Fred Drake71b63ff2002-06-28 22:29:01 +00001310
Martin v. Löwis894258c2001-09-23 10:20:10 +00001311#ifdef Py_TPFLAGS_HAVE_GC
1312 /* Code for versions 2.2 and later */
1313 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
1314#else
Fred Drake0582df92000-07-12 04:49:00 +00001315 self = PyObject_New(xmlparseobject, &Xmlparsetype);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001316#endif
Fred Drake0582df92000-07-12 04:49:00 +00001317 if (self == NULL)
1318 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001319
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001320#ifdef Py_USING_UNICODE
Fred Drake0582df92000-07-12 04:49:00 +00001321 self->returns_unicode = 1;
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001322#else
1323 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001324#endif
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001325
Fred Drake2a3d7db2002-06-28 22:56:48 +00001326 self->buffer = NULL;
1327 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
1328 self->buffer_used = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001329 self->ordered_attributes = 0;
1330 self->specified_attributes = 0;
Fred Drakebd6101c2001-02-14 18:29:45 +00001331 self->in_callback = 0;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001332 self->ns_prefixes = 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001333 self->handlers = NULL;
Fred Drakecde79132001-04-25 16:01:30 +00001334 if (namespace_separator != NULL) {
Fred Drake0582df92000-07-12 04:49:00 +00001335 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
1336 }
Fred Drake85d835f2001-02-08 15:39:08 +00001337 else {
Fred Drake0582df92000-07-12 04:49:00 +00001338 self->itself = XML_ParserCreate(encoding);
1339 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001340 self->intern = intern;
1341 Py_XINCREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001342#ifdef Py_TPFLAGS_HAVE_GC
1343 PyObject_GC_Track(self);
1344#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001345 PyObject_GC_Init(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001346#endif
Fred Drake0582df92000-07-12 04:49:00 +00001347 if (self->itself == NULL) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001348 PyErr_SetString(PyExc_RuntimeError,
Fred Drake0582df92000-07-12 04:49:00 +00001349 "XML_ParserCreate failed");
1350 Py_DECREF(self);
1351 return NULL;
1352 }
1353 XML_SetUserData(self->itself, (void *)self);
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001354#ifdef Py_USING_UNICODE
Fred Drake7c75bf22002-07-01 14:02:31 +00001355 XML_SetUnknownEncodingHandler(self->itself,
1356 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001357#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001358
Fred Drake2a3d7db2002-06-28 22:56:48 +00001359 for (i = 0; handler_info[i].name != NULL; i++)
Fred Drake0582df92000-07-12 04:49:00 +00001360 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001361
Fred Drake7c75bf22002-07-01 14:02:31 +00001362 self->handlers = malloc(sizeof(PyObject *) * i);
1363 if (!self->handlers) {
Fred Drake71b63ff2002-06-28 22:29:01 +00001364 Py_DECREF(self);
1365 return PyErr_NoMemory();
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001366 }
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001367 clear_handlers(self, 1);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001368
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001369 return (PyObject*)self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001370}
1371
1372
1373static void
Fred Drake0582df92000-07-12 04:49:00 +00001374xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001375{
Fred Drake0582df92000-07-12 04:49:00 +00001376 int i;
Martin v. Löwis894258c2001-09-23 10:20:10 +00001377#ifdef Py_TPFLAGS_HAVE_GC
1378 PyObject_GC_UnTrack(self);
1379#else
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001380 PyObject_GC_Fini(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001381#endif
Fred Drake85d835f2001-02-08 15:39:08 +00001382 if (self->itself != NULL)
Fred Drake0582df92000-07-12 04:49:00 +00001383 XML_ParserFree(self->itself);
1384 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001385
Fred Drake85d835f2001-02-08 15:39:08 +00001386 if (self->handlers != NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001387 PyObject *temp;
Fred Drake85d835f2001-02-08 15:39:08 +00001388 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drakecde79132001-04-25 16:01:30 +00001389 temp = self->handlers[i];
1390 self->handlers[i] = NULL;
1391 Py_XDECREF(temp);
Fred Drake85d835f2001-02-08 15:39:08 +00001392 }
1393 free(self->handlers);
Fred Drake71b63ff2002-06-28 22:29:01 +00001394 self->handlers = NULL;
Fred Drake0582df92000-07-12 04:49:00 +00001395 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001396 if (self->buffer != NULL) {
1397 free(self->buffer);
1398 self->buffer = NULL;
1399 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001400 Py_XDECREF(self->intern);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001401#ifndef Py_TPFLAGS_HAVE_GC
Martin v. Löwisb4fcf4d2002-06-30 06:40:55 +00001402 /* Code for versions 2.0 and 2.1 */
Fred Drake0582df92000-07-12 04:49:00 +00001403 PyObject_Del(self);
Martin v. Löwis894258c2001-09-23 10:20:10 +00001404#else
1405 /* Code for versions 2.2 and later. */
1406 PyObject_GC_Del(self);
1407#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001408}
1409
Fred Drake0582df92000-07-12 04:49:00 +00001410static int
1411handlername2int(const char *name)
1412{
1413 int i;
Fred Drake71b63ff2002-06-28 22:29:01 +00001414 for (i = 0; handler_info[i].name != NULL; i++) {
Fred Drake0582df92000-07-12 04:49:00 +00001415 if (strcmp(name, handler_info[i].name) == 0) {
1416 return i;
1417 }
1418 }
1419 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001420}
1421
1422static PyObject *
Fred Drake71b63ff2002-06-28 22:29:01 +00001423get_pybool(int istrue)
1424{
1425 PyObject *result = istrue ? Py_True : Py_False;
1426 Py_INCREF(result);
1427 return result;
1428}
1429
1430static PyObject *
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001431xmlparse_getattr(xmlparseobject *self, char *name)
1432{
Fred Drake71b63ff2002-06-28 22:29:01 +00001433 int handlernum = handlername2int(name);
1434
1435 if (handlernum != -1) {
1436 PyObject *result = self->handlers[handlernum];
1437 if (result == NULL)
1438 result = Py_None;
1439 Py_INCREF(result);
1440 return result;
1441 }
1442 if (name[0] == 'E') {
1443 if (strcmp(name, "ErrorCode") == 0)
1444 return PyInt_FromLong((long)
1445 XML_GetErrorCode(self->itself));
1446 if (strcmp(name, "ErrorLineNumber") == 0)
1447 return PyInt_FromLong((long)
1448 XML_GetErrorLineNumber(self->itself));
1449 if (strcmp(name, "ErrorColumnNumber") == 0)
1450 return PyInt_FromLong((long)
1451 XML_GetErrorColumnNumber(self->itself));
1452 if (strcmp(name, "ErrorByteIndex") == 0)
1453 return PyInt_FromLong((long)
1454 XML_GetErrorByteIndex(self->itself));
1455 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001456 if (name[0] == 'b') {
1457 if (strcmp(name, "buffer_size") == 0)
1458 return PyInt_FromLong((long) self->buffer_size);
1459 if (strcmp(name, "buffer_text") == 0)
1460 return get_pybool(self->buffer != NULL);
1461 if (strcmp(name, "buffer_used") == 0)
1462 return PyInt_FromLong((long) self->buffer_used);
1463 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001464 if (strcmp(name, "namespace_prefixes") == 0)
1465 return get_pybool(self->ns_prefixes);
Fred Drake85d835f2001-02-08 15:39:08 +00001466 if (strcmp(name, "ordered_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001467 return get_pybool(self->ordered_attributes);
Fred Drake0582df92000-07-12 04:49:00 +00001468 if (strcmp(name, "returns_unicode") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001469 return get_pybool((long) self->returns_unicode);
Fred Drake85d835f2001-02-08 15:39:08 +00001470 if (strcmp(name, "specified_attributes") == 0)
Fred Drake71b63ff2002-06-28 22:29:01 +00001471 return get_pybool((long) self->specified_attributes);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001472 if (strcmp(name, "intern") == 0) {
1473 if (self->intern == NULL) {
1474 Py_INCREF(Py_None);
1475 return Py_None;
1476 }
1477 else {
1478 Py_INCREF(self->intern);
1479 return self->intern;
1480 }
1481 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001482
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001483#define APPEND(list, str) \
Martin v. Löwis069dde22003-01-21 10:58:18 +00001484 do { \
1485 PyObject *o = PyString_FromString(str); \
1486 if (o != NULL) \
1487 PyList_Append(list, o); \
1488 Py_XDECREF(o); \
1489 } while (0)
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001490
Fred Drake0582df92000-07-12 04:49:00 +00001491 if (strcmp(name, "__members__") == 0) {
1492 int i;
1493 PyObject *rc = PyList_New(0);
Fred Drake71b63ff2002-06-28 22:29:01 +00001494 for (i = 0; handler_info[i].name != NULL; i++) {
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001495 PyObject *o = get_handler_name(&handler_info[i]);
1496 if (o != NULL)
1497 PyList_Append(rc, o);
1498 Py_XDECREF(o);
Fred Drake0582df92000-07-12 04:49:00 +00001499 }
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001500 APPEND(rc, "ErrorCode");
1501 APPEND(rc, "ErrorLineNumber");
1502 APPEND(rc, "ErrorColumnNumber");
1503 APPEND(rc, "ErrorByteIndex");
1504 APPEND(rc, "buffer_size");
1505 APPEND(rc, "buffer_text");
1506 APPEND(rc, "buffer_used");
Martin v. Löwis069dde22003-01-21 10:58:18 +00001507 APPEND(rc, "namespace_prefixes");
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001508 APPEND(rc, "ordered_attributes");
1509 APPEND(rc, "returns_unicode");
1510 APPEND(rc, "specified_attributes");
1511 APPEND(rc, "intern");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001512
Neal Norwitzfa56e2d2003-01-19 15:40:09 +00001513#undef APPEND
Fred Drake0582df92000-07-12 04:49:00 +00001514 return rc;
1515 }
1516 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001517}
1518
Fred Drake6f987622000-08-25 18:03:30 +00001519static int
1520sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +00001521{
1522 int handlernum = handlername2int(name);
Fred Drake71b63ff2002-06-28 22:29:01 +00001523 if (handlernum >= 0) {
1524 xmlhandler c_handler = NULL;
1525 PyObject *temp = self->handlers[handlernum];
1526
1527 if (v == Py_None)
1528 v = NULL;
1529 else if (v != NULL) {
1530 Py_INCREF(v);
1531 c_handler = handler_info[handlernum].handler;
1532 }
Fred Drake0582df92000-07-12 04:49:00 +00001533 self->handlers[handlernum] = v;
Fred Drake71b63ff2002-06-28 22:29:01 +00001534 Py_XDECREF(temp);
1535 handler_info[handlernum].setter(self->itself, c_handler);
Fred Drake0582df92000-07-12 04:49:00 +00001536 return 1;
1537 }
1538 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001539}
1540
1541static int
Fred Drake6f987622000-08-25 18:03:30 +00001542xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001543{
Fred Drake6f987622000-08-25 18:03:30 +00001544 /* Set attribute 'name' to value 'v'. v==NULL means delete */
Fred Drake85d835f2001-02-08 15:39:08 +00001545 if (v == NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001546 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
1547 return -1;
1548 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001549 if (strcmp(name, "buffer_text") == 0) {
1550 if (PyObject_IsTrue(v)) {
1551 if (self->buffer == NULL) {
1552 self->buffer = malloc(self->buffer_size);
1553 if (self->buffer == NULL) {
1554 PyErr_NoMemory();
1555 return -1;
1556 }
1557 self->buffer_used = 0;
1558 }
1559 }
1560 else if (self->buffer != NULL) {
1561 if (flush_character_buffer(self) < 0)
1562 return -1;
1563 free(self->buffer);
1564 self->buffer = NULL;
1565 }
1566 return 0;
1567 }
Martin v. Löwis069dde22003-01-21 10:58:18 +00001568 if (strcmp(name, "namespace_prefixes") == 0) {
1569 if (PyObject_IsTrue(v))
1570 self->ns_prefixes = 1;
1571 else
1572 self->ns_prefixes = 0;
1573 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
1574 return 0;
1575 }
Fred Drake85d835f2001-02-08 15:39:08 +00001576 if (strcmp(name, "ordered_attributes") == 0) {
1577 if (PyObject_IsTrue(v))
1578 self->ordered_attributes = 1;
1579 else
1580 self->ordered_attributes = 0;
1581 return 0;
1582 }
Fred Drake6f987622000-08-25 18:03:30 +00001583 if (strcmp(name, "returns_unicode") == 0) {
Fred Drake85d835f2001-02-08 15:39:08 +00001584 if (PyObject_IsTrue(v)) {
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001585#ifndef Py_USING_UNICODE
Fred Drake71b63ff2002-06-28 22:29:01 +00001586 PyErr_SetString(PyExc_ValueError,
1587 "Unicode support not available");
Fred Drake6f987622000-08-25 18:03:30 +00001588 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001589#else
Fred Drake6f987622000-08-25 18:03:30 +00001590 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001591#endif
Fred Drake6f987622000-08-25 18:03:30 +00001592 }
1593 else
1594 self->returns_unicode = 0;
Fred Drake85d835f2001-02-08 15:39:08 +00001595 return 0;
1596 }
1597 if (strcmp(name, "specified_attributes") == 0) {
1598 if (PyObject_IsTrue(v))
1599 self->specified_attributes = 1;
1600 else
1601 self->specified_attributes = 0;
Fred Drake6f987622000-08-25 18:03:30 +00001602 return 0;
1603 }
Fred Drake2a3d7db2002-06-28 22:56:48 +00001604 if (strcmp(name, "CharacterDataHandler") == 0) {
1605 /* If we're changing the character data handler, flush all
1606 * cached data with the old handler. Not sure there's a
1607 * "right" thing to do, though, but this probably won't
1608 * happen.
1609 */
1610 if (flush_character_buffer(self) < 0)
1611 return -1;
1612 }
Fred Drake6f987622000-08-25 18:03:30 +00001613 if (sethandler(self, name, v)) {
1614 return 0;
1615 }
1616 PyErr_SetString(PyExc_AttributeError, name);
1617 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001618}
1619
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001620#ifdef WITH_CYCLE_GC
1621static int
1622xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
1623{
Fred Drakecde79132001-04-25 16:01:30 +00001624 int i, err;
1625 for (i = 0; handler_info[i].name != NULL; i++) {
1626 if (!op->handlers[i])
1627 continue;
1628 err = visit(op->handlers[i], arg);
1629 if (err)
1630 return err;
1631 }
1632 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001633}
1634
1635static int
1636xmlparse_clear(xmlparseobject *op)
1637{
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001638 clear_handlers(op, 0);
Fred Drakeb91a36b2002-06-27 19:40:48 +00001639 Py_XDECREF(op->intern);
1640 op->intern = 0;
Fred Drakecde79132001-04-25 16:01:30 +00001641 return 0;
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001642}
1643#endif
1644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001646
1647static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001648 PyObject_HEAD_INIT(NULL)
1649 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +00001650 "pyexpat.xmlparser", /*tp_name*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001651 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001652 0, /*tp_itemsize*/
1653 /* methods */
1654 (destructor)xmlparse_dealloc, /*tp_dealloc*/
1655 (printfunc)0, /*tp_print*/
1656 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
1657 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
1658 (cmpfunc)0, /*tp_compare*/
1659 (reprfunc)0, /*tp_repr*/
1660 0, /*tp_as_number*/
1661 0, /*tp_as_sequence*/
1662 0, /*tp_as_mapping*/
1663 (hashfunc)0, /*tp_hash*/
1664 (ternaryfunc)0, /*tp_call*/
1665 (reprfunc)0, /*tp_str*/
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001666 0, /* tp_getattro */
1667 0, /* tp_setattro */
1668 0, /* tp_as_buffer */
Martin v. Löwis894258c2001-09-23 10:20:10 +00001669#ifdef Py_TPFLAGS_HAVE_GC
Fred Drake71b63ff2002-06-28 22:29:01 +00001670 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001671#else
Fred Drake71b63ff2002-06-28 22:29:01 +00001672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
Martin v. Löwis894258c2001-09-23 10:20:10 +00001673#endif
Martin v. Löwis069dde22003-01-21 10:58:18 +00001674 Xmlparsetype__doc__, /* tp_doc - Documentation string */
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001675#ifdef WITH_CYCLE_GC
1676 (traverseproc)xmlparse_traverse, /* tp_traverse */
1677 (inquiry)xmlparse_clear /* tp_clear */
1678#else
1679 0, 0
1680#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001681};
1682
1683/* End of code for xmlparser objects */
1684/* -------------------------------------------------------- */
1685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001686PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001687"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001688Return a new XML parser object.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001689
1690static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001691pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
1692{
Fred Drakecde79132001-04-25 16:01:30 +00001693 char *encoding = NULL;
1694 char *namespace_separator = NULL;
Fred Drakeb91a36b2002-06-27 19:40:48 +00001695 PyObject *intern = NULL;
1696 PyObject *result;
1697 int intern_decref = 0;
Fred Drake71b63ff2002-06-28 22:29:01 +00001698 static char *kwlist[] = {"encoding", "namespace_separator",
Fred Drakeb91a36b2002-06-27 19:40:48 +00001699 "intern", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001700
Fred Drakeb91a36b2002-06-27 19:40:48 +00001701 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
1702 &encoding, &namespace_separator, &intern))
Fred Drakecde79132001-04-25 16:01:30 +00001703 return NULL;
1704 if (namespace_separator != NULL
1705 && strlen(namespace_separator) > 1) {
1706 PyErr_SetString(PyExc_ValueError,
1707 "namespace_separator must be at most one"
1708 " character, omitted, or None");
1709 return NULL;
1710 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001711 /* Explicitly passing None means no interning is desired.
1712 Not passing anything means that a new dictionary is used. */
1713 if (intern == Py_None)
1714 intern = NULL;
1715 else if (intern == NULL) {
1716 intern = PyDict_New();
1717 if (!intern)
1718 return NULL;
1719 intern_decref = 1;
Fred Drake71b63ff2002-06-28 22:29:01 +00001720 }
Fred Drakeb91a36b2002-06-27 19:40:48 +00001721 else if (!PyDict_Check(intern)) {
1722 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
1723 return NULL;
1724 }
1725
1726 result = newxmlparseobject(encoding, namespace_separator, intern);
1727 if (intern_decref) {
1728 Py_DECREF(intern);
1729 }
1730 return result;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001731}
1732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001733PyDoc_STRVAR(pyexpat_ErrorString__doc__,
Fred Drake0582df92000-07-12 04:49:00 +00001734"ErrorString(errno) -> string\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735Returns string error for given number.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001736
1737static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +00001738pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001739{
Fred Drake0582df92000-07-12 04:49:00 +00001740 long code = 0;
1741
1742 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
1743 return NULL;
1744 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001745}
1746
1747/* List of methods defined in the module */
1748
1749static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +00001750 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
1751 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
1752 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
1753 METH_VARARGS, pyexpat_ErrorString__doc__},
Fred Drake71b63ff2002-06-28 22:29:01 +00001754
Fred Drake0582df92000-07-12 04:49:00 +00001755 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001756};
1757
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +00001758/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760PyDoc_STRVAR(pyexpat_module_documentation,
1761"Python wrapper for Expat parser.");
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001762
Fred Drake4113b132001-03-24 19:58:26 +00001763/* Return a Python string that represents the version number without the
1764 * extra cruft added by revision control, even if the right options were
1765 * given to the "cvs export" command to make it not include the extra
1766 * cruft.
1767 */
1768static PyObject *
1769get_version_string(void)
1770{
1771 static char *rcsid = "$Revision$";
1772 char *rev = rcsid;
1773 int i = 0;
1774
Neal Norwitz3afb2d22002-03-20 21:32:07 +00001775 while (!isdigit((int)*rev))
Fred Drake4113b132001-03-24 19:58:26 +00001776 ++rev;
1777 while (rev[i] != ' ' && rev[i] != '\0')
1778 ++i;
1779
1780 return PyString_FromStringAndSize(rev, i);
1781}
1782
Fred Drakecde79132001-04-25 16:01:30 +00001783/* Initialization function for the module */
1784
1785#ifndef MODULE_NAME
1786#define MODULE_NAME "pyexpat"
1787#endif
1788
1789#ifndef MODULE_INITFUNC
1790#define MODULE_INITFUNC initpyexpat
1791#endif
1792
Martin v. Löwis069dde22003-01-21 10:58:18 +00001793#ifndef PyMODINIT_FUNC
1794# ifdef MS_WINDOWS
1795# define PyMODINIT_FUNC __declspec(dllexport) void
1796# else
1797# define PyMODINIT_FUNC void
1798# endif
1799#endif
1800
Mark Hammond8235ea12002-07-19 06:55:41 +00001801PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
Fred Drakecde79132001-04-25 16:01:30 +00001802
Martin v. Löwis069dde22003-01-21 10:58:18 +00001803PyMODINIT_FUNC
1804MODULE_INITFUNC(void)
Fred Drake0582df92000-07-12 04:49:00 +00001805{
1806 PyObject *m, *d;
Fred Drakecde79132001-04-25 16:01:30 +00001807 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
Fred Drake85d835f2001-02-08 15:39:08 +00001808 PyObject *errors_module;
1809 PyObject *modelmod_name;
1810 PyObject *model_module;
Fred Drake0582df92000-07-12 04:49:00 +00001811 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001812
Fred Drake6f987622000-08-25 18:03:30 +00001813 if (errmod_name == NULL)
1814 return;
Fred Drakecde79132001-04-25 16:01:30 +00001815 modelmod_name = PyString_FromString(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001816 if (modelmod_name == NULL)
1817 return;
Fred Drake6f987622000-08-25 18:03:30 +00001818
Fred Drake0582df92000-07-12 04:49:00 +00001819 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001820
Fred Drake0582df92000-07-12 04:49:00 +00001821 /* Create the module and add the functions */
Fred Drakecde79132001-04-25 16:01:30 +00001822 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
Fred Drake85d835f2001-02-08 15:39:08 +00001823 pyexpat_module_documentation);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001824
Fred Drake0582df92000-07-12 04:49:00 +00001825 /* Add some symbolic constants to the module */
Fred Drakebd6101c2001-02-14 18:29:45 +00001826 if (ErrorObject == NULL) {
1827 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
Fred Drake93adb692000-09-23 04:55:48 +00001828 NULL, NULL);
Fred Drakebd6101c2001-02-14 18:29:45 +00001829 if (ErrorObject == NULL)
1830 return;
1831 }
1832 Py_INCREF(ErrorObject);
Fred Drake93adb692000-09-23 04:55:48 +00001833 PyModule_AddObject(m, "error", ErrorObject);
Fred Drakebd6101c2001-02-14 18:29:45 +00001834 Py_INCREF(ErrorObject);
1835 PyModule_AddObject(m, "ExpatError", ErrorObject);
Fred Drake4ba298c2000-10-29 04:57:53 +00001836 Py_INCREF(&Xmlparsetype);
1837 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001838
Fred Drake4113b132001-03-24 19:58:26 +00001839 PyModule_AddObject(m, "__version__", get_version_string());
Fred Drake738293d2000-12-21 17:25:07 +00001840 PyModule_AddStringConstant(m, "EXPAT_VERSION",
1841 (char *) XML_ExpatVersion());
Fred Drake85d835f2001-02-08 15:39:08 +00001842 {
1843 XML_Expat_Version info = XML_ExpatVersionInfo();
1844 PyModule_AddObject(m, "version_info",
1845 Py_BuildValue("(iii)", info.major,
1846 info.minor, info.micro));
1847 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001848#ifdef Py_USING_UNICODE
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001849 init_template_buffer();
1850#endif
Fred Drake0582df92000-07-12 04:49:00 +00001851 /* XXX When Expat supports some way of figuring out how it was
Fred Drake71b63ff2002-06-28 22:29:01 +00001852 compiled, this should check and set native_encoding
1853 appropriately.
Fred Drake0582df92000-07-12 04:49:00 +00001854 */
Fred Drake93adb692000-09-23 04:55:48 +00001855 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
Fred Drakec23b5232000-08-24 21:57:43 +00001856
Fred Drake85d835f2001-02-08 15:39:08 +00001857 sys_modules = PySys_GetObject("modules");
Fred Drake93adb692000-09-23 04:55:48 +00001858 d = PyModule_GetDict(m);
Fred Drake6f987622000-08-25 18:03:30 +00001859 errors_module = PyDict_GetItem(d, errmod_name);
1860 if (errors_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001861 errors_module = PyModule_New(MODULE_NAME ".errors");
Fred Drake6f987622000-08-25 18:03:30 +00001862 if (errors_module != NULL) {
Fred Drake6f987622000-08-25 18:03:30 +00001863 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drake93adb692000-09-23 04:55:48 +00001864 /* gives away the reference to errors_module */
1865 PyModule_AddObject(m, "errors", errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +00001866 }
1867 }
Fred Drake6f987622000-08-25 18:03:30 +00001868 Py_DECREF(errmod_name);
Fred Drake85d835f2001-02-08 15:39:08 +00001869 model_module = PyDict_GetItem(d, modelmod_name);
1870 if (model_module == NULL) {
Fred Drakecde79132001-04-25 16:01:30 +00001871 model_module = PyModule_New(MODULE_NAME ".model");
Fred Drake85d835f2001-02-08 15:39:08 +00001872 if (model_module != NULL) {
1873 PyDict_SetItem(sys_modules, modelmod_name, model_module);
1874 /* gives away the reference to model_module */
1875 PyModule_AddObject(m, "model", model_module);
1876 }
1877 }
1878 Py_DECREF(modelmod_name);
1879 if (errors_module == NULL || model_module == NULL)
1880 /* Don't core dump later! */
Fred Drake6f987622000-08-25 18:03:30 +00001881 return;
Martin v. Löwis069dde22003-01-21 10:58:18 +00001882
Martin v. Löwisc847f402003-01-21 11:09:21 +00001883#if XML_COMBINED_VERSION > 19505
Martin v. Löwis069dde22003-01-21 10:58:18 +00001884 {
1885 const XML_Feature *features = XML_GetFeatureList();
1886 PyObject *list = PyList_New(0);
1887 if (list == NULL)
1888 /* just ignore it */
1889 PyErr_Clear();
1890 else {
1891 int i = 0;
1892 for (; features[i].feature != XML_FEATURE_END; ++i) {
1893 int ok;
1894 PyObject *item = Py_BuildValue("si", features[i].name,
1895 features[i].value);
1896 if (item == NULL) {
1897 Py_DECREF(list);
1898 list = NULL;
1899 break;
1900 }
1901 ok = PyList_Append(list, item);
1902 Py_DECREF(item);
1903 if (ok < 0) {
1904 PyErr_Clear();
1905 break;
1906 }
1907 }
1908 if (list != NULL)
1909 PyModule_AddObject(m, "features", list);
1910 }
1911 }
Martin v. Löwisc847f402003-01-21 11:09:21 +00001912#endif
Fred Drake6f987622000-08-25 18:03:30 +00001913
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001914#define MYCONST(name) \
Fred Drake93adb692000-09-23 04:55:48 +00001915 PyModule_AddStringConstant(errors_module, #name, \
1916 (char*)XML_ErrorString(name))
Fred Drake7bd9f412000-07-04 23:51:31 +00001917
Fred Drake0582df92000-07-12 04:49:00 +00001918 MYCONST(XML_ERROR_NO_MEMORY);
1919 MYCONST(XML_ERROR_SYNTAX);
1920 MYCONST(XML_ERROR_NO_ELEMENTS);
1921 MYCONST(XML_ERROR_INVALID_TOKEN);
1922 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
1923 MYCONST(XML_ERROR_PARTIAL_CHAR);
1924 MYCONST(XML_ERROR_TAG_MISMATCH);
1925 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
1926 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
1927 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
1928 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
1929 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
1930 MYCONST(XML_ERROR_ASYNC_ENTITY);
1931 MYCONST(XML_ERROR_BAD_CHAR_REF);
1932 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
1933 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
1934 MYCONST(XML_ERROR_MISPLACED_XML_PI);
1935 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
1936 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001937 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
1938 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
1939 MYCONST(XML_ERROR_NOT_STANDALONE);
Fred Drake283b6702004-08-04 22:28:16 +00001940 MYCONST(XML_ERROR_UNEXPECTED_STATE);
1941 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
1942 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
1943 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
1944 /* Added in Expat 1.95.7. */
1945 MYCONST(XML_ERROR_UNBOUND_PREFIX);
1946 /* Added in Expat 1.95.8. */
1947 MYCONST(XML_ERROR_UNDECLARING_PREFIX);
1948 MYCONST(XML_ERROR_INCOMPLETE_PE);
1949 MYCONST(XML_ERROR_XML_DECL);
1950 MYCONST(XML_ERROR_TEXT_DECL);
1951 MYCONST(XML_ERROR_PUBLICID);
1952 MYCONST(XML_ERROR_SUSPENDED);
1953 MYCONST(XML_ERROR_NOT_SUSPENDED);
1954 MYCONST(XML_ERROR_ABORTED);
1955 MYCONST(XML_ERROR_FINISHED);
1956 MYCONST(XML_ERROR_SUSPEND_PE);
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001957
Fred Drake85d835f2001-02-08 15:39:08 +00001958 PyModule_AddStringConstant(errors_module, "__doc__",
1959 "Constants used to describe error conditions.");
1960
Fred Drake93adb692000-09-23 04:55:48 +00001961#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001962
Fred Drake85d835f2001-02-08 15:39:08 +00001963#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001964 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
1965 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1966 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
Fred Drake85d835f2001-02-08 15:39:08 +00001967#undef MYCONST
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001968
Fred Drake85d835f2001-02-08 15:39:08 +00001969#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
1970 PyModule_AddStringConstant(model_module, "__doc__",
1971 "Constants used to interpret content model information.");
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00001972
Fred Drake85d835f2001-02-08 15:39:08 +00001973 MYCONST(XML_CTYPE_EMPTY);
1974 MYCONST(XML_CTYPE_ANY);
1975 MYCONST(XML_CTYPE_MIXED);
1976 MYCONST(XML_CTYPE_NAME);
1977 MYCONST(XML_CTYPE_CHOICE);
1978 MYCONST(XML_CTYPE_SEQ);
1979
1980 MYCONST(XML_CQUANT_NONE);
1981 MYCONST(XML_CQUANT_OPT);
1982 MYCONST(XML_CQUANT_REP);
1983 MYCONST(XML_CQUANT_PLUS);
1984#undef MYCONST
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001985}
1986
Fred Drake6f987622000-08-25 18:03:30 +00001987static void
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001988clear_handlers(xmlparseobject *self, int initial)
Fred Drake0582df92000-07-12 04:49:00 +00001989{
Fred Drakecde79132001-04-25 16:01:30 +00001990 int i = 0;
1991 PyObject *temp;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001992
Fred Drake71b63ff2002-06-28 22:29:01 +00001993 for (; handler_info[i].name != NULL; i++) {
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001994 if (initial)
Fred Drake71b63ff2002-06-28 22:29:01 +00001995 self->handlers[i] = NULL;
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00001996 else {
Fred Drakecde79132001-04-25 16:01:30 +00001997 temp = self->handlers[i];
1998 self->handlers[i] = NULL;
1999 Py_XDECREF(temp);
Martin v. Löwis5b68ce32001-10-21 08:53:52 +00002000 handler_info[i].setter(self->itself, NULL);
Fred Drakecde79132001-04-25 16:01:30 +00002001 }
Fred Drakecde79132001-04-25 16:01:30 +00002002 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002003}
2004
Tim Peters0c322792002-07-17 16:49:03 +00002005static struct HandlerInfo handler_info[] = {
Fred Drake71b63ff2002-06-28 22:29:01 +00002006 {"StartElementHandler",
2007 (xmlhandlersetter)XML_SetStartElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002008 (xmlhandler)my_StartElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002009 {"EndElementHandler",
2010 (xmlhandlersetter)XML_SetEndElementHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002011 (xmlhandler)my_EndElementHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002012 {"ProcessingInstructionHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002013 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
2014 (xmlhandler)my_ProcessingInstructionHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002015 {"CharacterDataHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002016 (xmlhandlersetter)XML_SetCharacterDataHandler,
2017 (xmlhandler)my_CharacterDataHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002018 {"UnparsedEntityDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002019 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002020 (xmlhandler)my_UnparsedEntityDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002021 {"NotationDeclHandler",
Fred Drake0582df92000-07-12 04:49:00 +00002022 (xmlhandlersetter)XML_SetNotationDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002023 (xmlhandler)my_NotationDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002024 {"StartNamespaceDeclHandler",
2025 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002026 (xmlhandler)my_StartNamespaceDeclHandler},
Fred Drake71b63ff2002-06-28 22:29:01 +00002027 {"EndNamespaceDeclHandler",
2028 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002029 (xmlhandler)my_EndNamespaceDeclHandler},
Fred Drake0582df92000-07-12 04:49:00 +00002030 {"CommentHandler",
2031 (xmlhandlersetter)XML_SetCommentHandler,
2032 (xmlhandler)my_CommentHandler},
2033 {"StartCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002034 (xmlhandlersetter)XML_SetStartCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002035 (xmlhandler)my_StartCdataSectionHandler},
2036 {"EndCdataSectionHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002037 (xmlhandlersetter)XML_SetEndCdataSectionHandler,
Fred Drake0582df92000-07-12 04:49:00 +00002038 (xmlhandler)my_EndCdataSectionHandler},
2039 {"DefaultHandler",
2040 (xmlhandlersetter)XML_SetDefaultHandler,
2041 (xmlhandler)my_DefaultHandler},
2042 {"DefaultHandlerExpand",
2043 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
2044 (xmlhandler)my_DefaultHandlerExpandHandler},
2045 {"NotStandaloneHandler",
2046 (xmlhandlersetter)XML_SetNotStandaloneHandler,
2047 (xmlhandler)my_NotStandaloneHandler},
2048 {"ExternalEntityRefHandler",
2049 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
Fred Drake2a3d7db2002-06-28 22:56:48 +00002050 (xmlhandler)my_ExternalEntityRefHandler},
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002051 {"StartDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002052 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002053 (xmlhandler)my_StartDoctypeDeclHandler},
2054 {"EndDoctypeDeclHandler",
Fred Drake71b63ff2002-06-28 22:29:01 +00002055 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
Martin v. Löwis0078f6c2001-01-21 10:18:10 +00002056 (xmlhandler)my_EndDoctypeDeclHandler},
Fred Drake85d835f2001-02-08 15:39:08 +00002057 {"EntityDeclHandler",
2058 (xmlhandlersetter)XML_SetEntityDeclHandler,
2059 (xmlhandler)my_EntityDeclHandler},
2060 {"XmlDeclHandler",
2061 (xmlhandlersetter)XML_SetXmlDeclHandler,
2062 (xmlhandler)my_XmlDeclHandler},
2063 {"ElementDeclHandler",
2064 (xmlhandlersetter)XML_SetElementDeclHandler,
2065 (xmlhandler)my_ElementDeclHandler},
2066 {"AttlistDeclHandler",
2067 (xmlhandlersetter)XML_SetAttlistDeclHandler,
2068 (xmlhandler)my_AttlistDeclHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002069#if XML_COMBINED_VERSION >= 19504
Martin v. Löwis069dde22003-01-21 10:58:18 +00002070 {"SkippedEntityHandler",
2071 (xmlhandlersetter)XML_SetSkippedEntityHandler,
2072 (xmlhandler)my_SkippedEntityHandler},
Martin v. Löwisc847f402003-01-21 11:09:21 +00002073#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002074
Fred Drake0582df92000-07-12 04:49:00 +00002075 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00002076};