blob: 8b29d4b5ade8f1a8dde8d07d5c093a64f2cd19c9 [file] [log] [blame]
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001/***********************************************************
2Copyright 2000 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000014
15******************************************************************/
16
17#include "Python.h"
18#include "xmlparse.h"
19
20/*
21** The version number should match the one in _checkversion
22*/
23#define VERSION "1.9"
24
Fred Drake0582df92000-07-12 04:49:00 +000025enum HandlerTypes {
26 StartElement,
27 EndElement,
28 ProcessingInstruction,
29 CharacterData,
30 UnparsedEntityDecl,
31 NotationDecl,
32 StartNamespaceDecl,
33 EndNamespaceDecl,
34 Comment,
35 StartCdataSection,
36 EndCdataSection,
37 Default,
38 DefaultHandlerExpand,
39 NotStandalone,
40 ExternalEntityRef
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000041};
42
43static PyObject *ErrorObject;
44
45/* ----------------------------------------------------- */
46
47/* Declarations for objects of type xmlparser */
48
49typedef struct {
Fred Drake0582df92000-07-12 04:49:00 +000050 PyObject_HEAD
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000051
Fred Drake0582df92000-07-12 04:49:00 +000052 XML_Parser itself;
53 int returns_unicode; /* True if Unicode strings are returned;
54 if false, UTF-8 strings are returned */
55 PyObject **handlers;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000056} xmlparseobject;
57
58staticforward PyTypeObject Xmlparsetype;
59
Fred Drake6f987622000-08-25 18:03:30 +000060typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000061typedef void* xmlhandler;
62
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000063struct HandlerInfo {
Fred Drake0582df92000-07-12 04:49:00 +000064 const char *name;
65 xmlhandlersetter setter;
66 xmlhandler handler;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000067};
68
Andrew M. Kuchling637f6642000-07-04 14:53:43 +000069staticforward struct HandlerInfo handler_info[64];
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +000070
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000071/* Convert an array of attributes and their values into a Python dict */
72
Fred Drake0582df92000-07-12 04:49:00 +000073static PyObject *
74conv_atts_using_string(XML_Char **atts)
Andrew M. Kuchlinga4e75d72000-07-12 00:53:41 +000075{
Fred Drake0582df92000-07-12 04:49:00 +000076 PyObject *attrs_obj = NULL;
77 XML_Char **attrs_p, **attrs_k = NULL;
78 int attrs_len;
79 PyObject *rv;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +000080
Fred Drake0582df92000-07-12 04:49:00 +000081 if ((attrs_obj = PyDict_New()) == NULL)
82 goto finally;
83 for (attrs_len = 0, attrs_p = atts;
84 *attrs_p;
85 attrs_p++, attrs_len++) {
86 if (attrs_len % 2) {
87 rv = PyString_FromString(*attrs_p);
88 if (!rv) {
89 Py_DECREF(attrs_obj);
90 attrs_obj = NULL;
91 goto finally;
92 }
93 if (PyDict_SetItemString(attrs_obj,
94 (char*)*attrs_k, rv) < 0) {
95 Py_DECREF(attrs_obj);
96 attrs_obj = NULL;
97 goto finally;
98 }
99 Py_DECREF(rv);
100 }
101 else
102 attrs_k = attrs_p;
103 }
104 finally:
105 return attrs_obj;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000106}
107
108#if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
Fred Drake0582df92000-07-12 04:49:00 +0000109static PyObject *
110conv_atts_using_unicode(XML_Char **atts)
111{
112 PyObject *attrs_obj = NULL;
113 XML_Char **attrs_p, **attrs_k = NULL;
114 int attrs_len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000115
Fred Drake0582df92000-07-12 04:49:00 +0000116 if ((attrs_obj = PyDict_New()) == NULL)
117 goto finally;
118 for (attrs_len = 0, attrs_p = atts;
119 *attrs_p;
120 attrs_p++, attrs_len++) {
121 if (attrs_len % 2) {
122 PyObject *attr_str, *value_str;
123 const char *p = (const char *) (*attrs_k);
124 attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
125 if (!attr_str) {
126 Py_DECREF(attrs_obj);
127 attrs_obj = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000128 goto finally;
Fred Drake0582df92000-07-12 04:49:00 +0000129 }
130 p = (const char *) *attrs_p;
131 value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
132 if (!value_str) {
133 Py_DECREF(attrs_obj);
134 Py_DECREF(attr_str);
135 attrs_obj = NULL;
136 goto finally;
137 }
138 if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
139 Py_DECREF(attrs_obj);
140 attrs_obj = NULL;
141 goto finally;
142 }
143 Py_DECREF(attr_str);
144 Py_DECREF(value_str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000145 }
Fred Drake0582df92000-07-12 04:49:00 +0000146 else
147 attrs_k = attrs_p;
148 }
149 finally:
150 return attrs_obj;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000151}
152
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000153/* Convert a string of XML_Chars into a Unicode string.
154 Returns None if str is a null pointer. */
155
Fred Drake0582df92000-07-12 04:49:00 +0000156static PyObject *
157conv_string_to_unicode(XML_Char *str)
158{
159 /* XXX currently this code assumes that XML_Char is 8-bit,
160 and hence in UTF-8. */
161 /* UTF-8 from Expat, Unicode desired */
162 if (str == NULL) {
163 Py_INCREF(Py_None);
164 return Py_None;
165 }
166 return PyUnicode_DecodeUTF8((const char *)str,
167 strlen((const char *)str),
168 "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000169}
170
Fred Drake0582df92000-07-12 04:49:00 +0000171static PyObject *
172conv_string_len_to_unicode(const XML_Char *str, int len)
173{
174 /* XXX currently this code assumes that XML_Char is 8-bit,
175 and hence in UTF-8. */
176 /* UTF-8 from Expat, Unicode desired */
177 if (str == NULL) {
178 Py_INCREF(Py_None);
179 return Py_None;
180 }
Fred Drake6f987622000-08-25 18:03:30 +0000181 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000182}
183#endif
184
185/* Convert a string of XML_Chars into an 8-bit Python string.
186 Returns None if str is a null pointer. */
187
Fred Drake6f987622000-08-25 18:03:30 +0000188static PyObject *
189conv_string_to_utf8(XML_Char *str)
190{
191 /* XXX currently this code assumes that XML_Char is 8-bit,
192 and hence in UTF-8. */
193 /* UTF-8 from Expat, UTF-8 desired */
194 if (str == NULL) {
195 Py_INCREF(Py_None);
196 return Py_None;
197 }
198 return PyString_FromString((const char *)str);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000199}
200
Fred Drake6f987622000-08-25 18:03:30 +0000201static PyObject *
202conv_string_len_to_utf8(const XML_Char *str, int len)
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000203{
Fred Drake6f987622000-08-25 18:03:30 +0000204 /* XXX currently this code assumes that XML_Char is 8-bit,
205 and hence in UTF-8. */
206 /* UTF-8 from Expat, UTF-8 desired */
207 if (str == NULL) {
208 Py_INCREF(Py_None);
209 return Py_None;
210 }
211 return PyString_FromStringAndSize((const char *)str, len);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000212}
213
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000214/* Callback routines */
215
Fred Drake6f987622000-08-25 18:03:30 +0000216static void clear_handlers(xmlparseobject *self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000217
Fred Drake6f987622000-08-25 18:03:30 +0000218static void
219flag_error(xmlparseobject *self)
220{
221 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000222}
223
Fred Drake6f987622000-08-25 18:03:30 +0000224#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000225 RETURN, GETUSERDATA) \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000226\
227static RC my_##NAME##Handler PARAMS {\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000228 xmlparseobject *self = GETUSERDATA ; \
229 PyObject *args=NULL; \
230 PyObject *rv=NULL; \
231 INIT \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000232\
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000233 if (self->handlers[NAME] \
234 && self->handlers[NAME] != Py_None) { \
235 args = Py_BuildValue PARAM_FORMAT ;\
236 if (!args) return RETURN; \
237 rv = PyEval_CallObject(self->handlers[NAME], args); \
238 Py_DECREF(args); \
239 if (rv == NULL) { \
Fred Drake6f987622000-08-25 18:03:30 +0000240 flag_error(self); \
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000241 return RETURN; \
242 } \
243 CONVERSION \
244 Py_DECREF(rv); \
245 } \
246 return RETURN; \
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000247}
248
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000249#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
250#define STRING_CONV_FUNC conv_string_to_utf8
251#else
252/* Python 1.6 and later versions */
253#define STRING_CONV_FUNC (self->returns_unicode \
254 ? conv_string_to_unicode : conv_string_to_utf8)
255#endif
Guido van Rossum5961f5a2000-03-31 16:18:11 +0000256
Fred Drake6f987622000-08-25 18:03:30 +0000257#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
258 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
259 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000260
Fred Drake6f987622000-08-25 18:03:30 +0000261#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
262 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
263 rc = PyInt_AsLong(rv);, rc, \
264 (xmlparseobject *)userData)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000265
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000266#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000267VOID_HANDLER(StartElement,
268 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000269 ("(O&O&)", STRING_CONV_FUNC, name,
270 conv_atts_using_string, atts ) )
271#else
272/* Python 1.6 and later */
Fred Drake6f987622000-08-25 18:03:30 +0000273VOID_HANDLER(StartElement,
274 (void *userData, const XML_Char *name, const XML_Char **atts),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000275 ("(O&O&)", STRING_CONV_FUNC, name,
276 (self->returns_unicode
277 ? conv_atts_using_unicode
Fred Drake6f987622000-08-25 18:03:30 +0000278 : conv_atts_using_string), atts))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000279#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000280
Fred Drake6f987622000-08-25 18:03:30 +0000281VOID_HANDLER(EndElement,
282 (void *userData, const XML_Char *name),
283 ("(O&)", STRING_CONV_FUNC, name))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000284
Fred Drake6f987622000-08-25 18:03:30 +0000285VOID_HANDLER(ProcessingInstruction,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000286 (void *userData,
287 const XML_Char *target,
288 const XML_Char *data),
Fred Drake6f987622000-08-25 18:03:30 +0000289 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000290
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000291#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000292VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000293 (void *userData, const XML_Char *data, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000294 ("(O)", conv_string_len_to_utf8(data,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000295#else
Fred Drake6f987622000-08-25 18:03:30 +0000296VOID_HANDLER(CharacterData,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000297 (void *userData, const XML_Char *data, int len),
298 ("(O)", (self->returns_unicode
299 ? conv_string_len_to_unicode(data,len)
Fred Drake6f987622000-08-25 18:03:30 +0000300 : conv_string_len_to_utf8(data,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000301#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000302
Fred Drake6f987622000-08-25 18:03:30 +0000303VOID_HANDLER(UnparsedEntityDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000304 (void *userData,
305 const XML_Char *entityName,
306 const XML_Char *base,
307 const XML_Char *systemId,
308 const XML_Char *publicId,
309 const XML_Char *notationName),
310 ("(O&O&O&O&O&)",
311 STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base,
312 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId,
313 STRING_CONV_FUNC,notationName))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000314
Fred Drake6f987622000-08-25 18:03:30 +0000315VOID_HANDLER(NotationDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000316 (void *userData,
317 const XML_Char *notationName,
318 const XML_Char *base,
319 const XML_Char *systemId,
320 const XML_Char *publicId),
321 ("(O&O&O&O&)",
322 STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base,
323 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000324
Fred Drake6f987622000-08-25 18:03:30 +0000325VOID_HANDLER(StartNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000326 (void *userData,
327 const XML_Char *prefix,
328 const XML_Char *uri),
Fred Drake6f987622000-08-25 18:03:30 +0000329 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000330
Fred Drake6f987622000-08-25 18:03:30 +0000331VOID_HANDLER(EndNamespaceDecl,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000332 (void *userData,
333 const XML_Char *prefix),
Fred Drake6f987622000-08-25 18:03:30 +0000334 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000335
Fred Drake6f987622000-08-25 18:03:30 +0000336VOID_HANDLER(Comment,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000337 (void *userData, const XML_Char *prefix),
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000338 ("(O&)", STRING_CONV_FUNC,prefix))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000339
Fred Drake6f987622000-08-25 18:03:30 +0000340VOID_HANDLER(StartCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000341 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000342 ("()"))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000343
Fred Drake6f987622000-08-25 18:03:30 +0000344VOID_HANDLER(EndCdataSection,
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000345 (void *userData),
Fred Drake6f987622000-08-25 18:03:30 +0000346 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000347
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000348#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000349VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000350 (void *userData, const XML_Char *s, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000351 ("(O)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000352
Fred Drake6f987622000-08-25 18:03:30 +0000353VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000354 (void *userData, const XML_Char *s, int len),
Fred Drake6f987622000-08-25 18:03:30 +0000355 ("(O)", conv_string_len_to_utf8(s,len)))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000356#else
Fred Drake6f987622000-08-25 18:03:30 +0000357VOID_HANDLER(Default,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000358 (void *userData, const XML_Char *s, int len),
359 ("(O)", (self->returns_unicode
360 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000361 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000362
Fred Drake6f987622000-08-25 18:03:30 +0000363VOID_HANDLER(DefaultHandlerExpand,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000364 (void *userData, const XML_Char *s, int len),
365 ("(O)", (self->returns_unicode
366 ? conv_string_len_to_unicode(s,len)
Fred Drake6f987622000-08-25 18:03:30 +0000367 : conv_string_len_to_utf8(s,len))))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000368#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000369
Fred Drake6f987622000-08-25 18:03:30 +0000370INT_HANDLER(NotStandalone,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000371 (void *userData),
372 ("()"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000373
Fred Drake6f987622000-08-25 18:03:30 +0000374RC_HANDLER(int, ExternalEntityRef,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000375 (XML_Parser parser,
376 const XML_Char *context,
377 const XML_Char *base,
378 const XML_Char *systemId,
379 const XML_Char *publicId),
380 int rc=0;,
381 ("(O&O&O&O&)",
382 STRING_CONV_FUNC,context, STRING_CONV_FUNC,base,
Fred Drake6f987622000-08-25 18:03:30 +0000383 STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
384 rc = PyInt_AsLong(rv);, rc,
385 XML_GetUserData(parser))
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000386
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000387
388
389/* File reading copied from cPickle */
390
391#define UNLESS(E) if (!(E))
392
393/*
394static int
395read_other(xmlparseobject *self, char **s, int n) {
396 PyObject *bytes=NULL, *str=NULL, *arg=NULL;
397 int res = -1;
398
399 UNLESS(bytes = PyInt_FromLong(n)) {
400 if (!PyErr_Occurred())
401 PyErr_SetNone(PyExc_EOFError);
402
403 goto finally;
404 }
405
406 UNLESS(arg)
407 UNLESS(arg = PyTuple_New(1))
408 goto finally;
409
410 Py_INCREF(bytes);
411 if (PyTuple_SetItem(arg, 0, bytes) < 0)
412 goto finally;
413
414 UNLESS(str = PyObject_CallObject(self->read, arg))
415 goto finally;
416
417 *s = PyString_AsString(str);
418
419 res = n;
420
421finally:
422 Py_XDECREF(arg);
423 Py_XDECREF(bytes);
424
425 return res;
426}
427
428*/
429
430
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000431
432/* ---------------------------------------------------------------- */
433
434static char xmlparse_Parse__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000435"Parse(data[, isfinal])\n\
Fred Drake0582df92000-07-12 04:49:00 +0000436Parse XML data. `isfinal' should be true at end of input.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000437
438static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000439xmlparse_Parse(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000440{
Fred Drake0582df92000-07-12 04:49:00 +0000441 char *s;
442 int slen;
443 int isFinal = 0;
444 int rv;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000445
Fred Drake0582df92000-07-12 04:49:00 +0000446 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
447 return NULL;
448 rv = XML_Parse(self->itself, s, slen, isFinal);
449 if (PyErr_Occurred()) {
450 return NULL;
451 }
452 else if (rv == 0) {
453 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
454 XML_ErrorString(XML_GetErrorCode(self->itself)),
455 XML_GetErrorLineNumber(self->itself),
456 XML_GetErrorColumnNumber(self->itself));
457 return NULL;
458 }
459 return PyInt_FromLong(rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000460}
461
462#define BUF_SIZE 2048
463
Fred Drake0582df92000-07-12 04:49:00 +0000464static int
465readinst(char *buf, int buf_size, PyObject *meth)
466{
467 PyObject *arg = NULL;
468 PyObject *bytes = NULL;
469 PyObject *str = NULL;
470 int len = -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000471
Fred Drake0582df92000-07-12 04:49:00 +0000472 UNLESS(bytes = PyInt_FromLong(buf_size)) {
473 if (!PyErr_Occurred())
474 PyErr_SetNone(PyExc_EOFError);
475 goto finally;
476 }
477 UNLESS(arg)
478 UNLESS(arg = PyTuple_New(1))
479 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000480
Fred Drake0582df92000-07-12 04:49:00 +0000481 if (PyTuple_SetItem(arg, 0, bytes) < 0)
482 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000483
Fred Drake0582df92000-07-12 04:49:00 +0000484 UNLESS(str = PyObject_CallObject(meth, arg))
485 goto finally;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000486
Fred Drake0582df92000-07-12 04:49:00 +0000487 /* XXX what to do if it returns a Unicode string? */
Fred Drake6f987622000-08-25 18:03:30 +0000488 UNLESS(PyString_Check(str)) {
Fred Drake0582df92000-07-12 04:49:00 +0000489 PyErr_Format(PyExc_TypeError,
490 "read() did not return a string object (type=%.400s)",
491 str->ob_type->tp_name);
492 goto finally;
493 }
494 len = PyString_GET_SIZE(str);
495 if (len > buf_size) {
496 PyErr_Format(PyExc_ValueError,
497 "read() returned too much data: "
498 "%i bytes requested, %i returned",
499 buf_size, len);
500 Py_DECREF(str);
501 goto finally;
502 }
503 memcpy(buf, PyString_AsString(str), len);
504 Py_XDECREF(str);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000505finally:
Fred Drake0582df92000-07-12 04:49:00 +0000506 Py_XDECREF(arg);
507 return len;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000508}
509
510static char xmlparse_ParseFile__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000511"ParseFile(file)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000512Parse XML data from file-like object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000513
514static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000515xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000516{
Fred Drake0582df92000-07-12 04:49:00 +0000517 int rv = 1;
518 PyObject *f;
519 FILE *fp;
520 PyObject *readmethod = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000521
Fred Drake0582df92000-07-12 04:49:00 +0000522 if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
523 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000524
Fred Drake0582df92000-07-12 04:49:00 +0000525 if (PyFile_Check(f)) {
526 fp = PyFile_AsFile(f);
527 }
528 else{
529 fp = NULL;
530 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
531 PyErr_Clear();
532 PyErr_SetString(PyExc_TypeError,
533 "argument must have 'read' attribute");
534 return 0;
535 }
536 }
537 for (;;) {
538 int bytes_read;
539 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
540 if (buf == NULL)
541 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000542
Fred Drake0582df92000-07-12 04:49:00 +0000543 if (fp) {
544 bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
545 if (bytes_read < 0) {
546 PyErr_SetFromErrno(PyExc_IOError);
547 return NULL;
548 }
549 }
550 else {
551 bytes_read = readinst(buf, BUF_SIZE, readmethod);
552 if (bytes_read < 0)
553 return NULL;
554 }
555 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
556 if (PyErr_Occurred())
557 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000558
Fred Drake0582df92000-07-12 04:49:00 +0000559 if (!rv || bytes_read == 0)
560 break;
561 }
562 return Py_BuildValue("i", rv);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000563}
564
565static char xmlparse_SetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000566"SetBase(base_url)\n\
Fred Drake0582df92000-07-12 04:49:00 +0000567Set the base URL for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000568
569static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000570xmlparse_SetBase(xmlparseobject *self, PyObject *args)
571{
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000572 char *base;
573
Fred Drake0582df92000-07-12 04:49:00 +0000574 if (!PyArg_ParseTuple(args, "s:SetBase", &base))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000575 return NULL;
Fred Drake0582df92000-07-12 04:49:00 +0000576 if (!XML_SetBase(self->itself, base)) {
577 return PyErr_NoMemory();
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000578 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000579 Py_INCREF(Py_None);
580 return Py_None;
581}
582
583static char xmlparse_GetBase__doc__[] =
Thomas Wouters35317302000-07-22 16:34:15 +0000584"GetBase() -> url\n\
Fred Drake0582df92000-07-12 04:49:00 +0000585Return base URL string for the parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000586
587static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000588xmlparse_GetBase(xmlparseobject *self, PyObject *args)
589{
590 if (!PyArg_ParseTuple(args, ":GetBase"))
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000591 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000592
Fred Drake0582df92000-07-12 04:49:00 +0000593 return Py_BuildValue("z", XML_GetBase(self->itself));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000594}
595
596static struct PyMethodDef xmlparse_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000597 {"Parse", (PyCFunction)xmlparse_Parse,
598 METH_VARARGS, xmlparse_Parse__doc__},
599 {"ParseFile", (PyCFunction)xmlparse_ParseFile,
600 METH_VARARGS, xmlparse_ParseFile__doc__},
601 {"SetBase", (PyCFunction)xmlparse_SetBase,
602 METH_VARARGS, xmlparse_SetBase__doc__},
603 {"GetBase", (PyCFunction)xmlparse_GetBase,
604 METH_VARARGS, xmlparse_GetBase__doc__},
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000605 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000606};
607
608/* ---------- */
609
610
611static xmlparseobject *
Fred Drake0582df92000-07-12 04:49:00 +0000612newxmlparseobject(char *encoding, char *namespace_separator)
613{
614 int i;
615 xmlparseobject *self;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000616
617#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000618 self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
619 if (self == NULL)
620 return NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000621
Fred Drake0582df92000-07-12 04:49:00 +0000622 self->returns_unicode = 0;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000623#else
Fred Drake0582df92000-07-12 04:49:00 +0000624 /* Code for versions 1.6 and later */
625 self = PyObject_New(xmlparseobject, &Xmlparsetype);
626 if (self == NULL)
627 return NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000628
Fred Drake0582df92000-07-12 04:49:00 +0000629 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000630#endif
Fred Drake0582df92000-07-12 04:49:00 +0000631 if (namespace_separator) {
632 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
633 }
634 else{
635 self->itself = XML_ParserCreate(encoding);
636 }
637 if (self->itself == NULL) {
638 PyErr_SetString(PyExc_RuntimeError,
639 "XML_ParserCreate failed");
640 Py_DECREF(self);
641 return NULL;
642 }
643 XML_SetUserData(self->itself, (void *)self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000644
Fred Drake0582df92000-07-12 04:49:00 +0000645 for(i = 0; handler_info[i].name != NULL; i++)
646 /* do nothing */;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000647
Fred Drake0582df92000-07-12 04:49:00 +0000648 self->handlers = malloc(sizeof(PyObject *)*i);
649 clear_handlers(self);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000650
Fred Drake0582df92000-07-12 04:49:00 +0000651 return self;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000652}
653
654
655static void
Fred Drake0582df92000-07-12 04:49:00 +0000656xmlparse_dealloc(xmlparseobject *self)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000657{
Fred Drake0582df92000-07-12 04:49:00 +0000658 int i;
659 if (self->itself)
660 XML_ParserFree(self->itself);
661 self->itself = NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000662
Fred Drake0582df92000-07-12 04:49:00 +0000663 for (i=0; handler_info[i].name != NULL; i++) {
664 Py_XDECREF(self->handlers[i]);
665 }
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000666#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake0582df92000-07-12 04:49:00 +0000667 /* Code for versions before 1.6 */
668 free(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000669#else
Fred Drake0582df92000-07-12 04:49:00 +0000670 /* Code for versions 1.6 and later */
671 PyObject_Del(self);
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000672#endif
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000673}
674
Fred Drake0582df92000-07-12 04:49:00 +0000675static int
676handlername2int(const char *name)
677{
678 int i;
679 for (i=0; handler_info[i].name != NULL; i++) {
680 if (strcmp(name, handler_info[i].name) == 0) {
681 return i;
682 }
683 }
684 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000685}
686
687static PyObject *
688xmlparse_getattr(xmlparseobject *self, char *name)
689{
Fred Drake0582df92000-07-12 04:49:00 +0000690 int handlernum;
691 if (strcmp(name, "ErrorCode") == 0)
692 return Py_BuildValue("l",
693 (long)XML_GetErrorCode(self->itself));
694 if (strcmp(name, "ErrorLineNumber") == 0)
695 return Py_BuildValue("l",
696 (long)XML_GetErrorLineNumber(self->itself));
697 if (strcmp(name, "ErrorColumnNumber") == 0)
698 return Py_BuildValue("l",
699 (long)XML_GetErrorColumnNumber(self->itself));
700 if (strcmp(name, "ErrorByteIndex") == 0)
701 return Py_BuildValue("l",
702 XML_GetErrorByteIndex(self->itself));
703 if (strcmp(name, "returns_unicode") == 0)
704 return Py_BuildValue("i", self->returns_unicode);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000705
Fred Drake0582df92000-07-12 04:49:00 +0000706 handlernum = handlername2int(name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000707
Fred Drake0582df92000-07-12 04:49:00 +0000708 if (handlernum != -1 && self->handlers[handlernum] != NULL) {
709 Py_INCREF(self->handlers[handlernum]);
710 return self->handlers[handlernum];
711 }
712 if (strcmp(name, "__members__") == 0) {
713 int i;
714 PyObject *rc = PyList_New(0);
715 for(i = 0; handler_info[i].name!=NULL; i++) {
716 PyList_Append(rc,
717 PyString_FromString(handler_info[i].name));
718 }
719 PyList_Append(rc, PyString_FromString("ErrorCode"));
720 PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
721 PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
722 PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000723
Fred Drake0582df92000-07-12 04:49:00 +0000724 return rc;
725 }
726 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000727}
728
Fred Drake6f987622000-08-25 18:03:30 +0000729static int
730sethandler(xmlparseobject *self, const char *name, PyObject* v)
Fred Drake0582df92000-07-12 04:49:00 +0000731{
732 int handlernum = handlername2int(name);
733 if (handlernum != -1) {
734 Py_INCREF(v);
735 Py_XDECREF(self->handlers[handlernum]);
736 self->handlers[handlernum] = v;
737 handler_info[handlernum].setter(self->itself,
738 handler_info[handlernum].handler);
739 return 1;
740 }
741 return 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000742}
743
744static int
Fred Drake6f987622000-08-25 18:03:30 +0000745xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000746{
Fred Drake6f987622000-08-25 18:03:30 +0000747 /* Set attribute 'name' to value 'v'. v==NULL means delete */
748 if (v==NULL) {
749 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
750 return -1;
751 }
752 if (strcmp(name, "returns_unicode") == 0) {
753 PyObject *intobj = PyNumber_Int(v);
754 if (intobj == NULL) return -1;
755 if (PyInt_AsLong(intobj)) {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000756#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
Fred Drake6f987622000-08-25 18:03:30 +0000757 PyErr_SetString(PyExc_ValueError,
758 "Cannot return Unicode strings in Python 1.5");
759 return -1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000760#else
Fred Drake6f987622000-08-25 18:03:30 +0000761 self->returns_unicode = 1;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000762#endif
Fred Drake6f987622000-08-25 18:03:30 +0000763 }
764 else
765 self->returns_unicode = 0;
766 Py_DECREF(intobj);
767 return 0;
768 }
769 if (sethandler(self, name, v)) {
770 return 0;
771 }
772 PyErr_SetString(PyExc_AttributeError, name);
773 return -1;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000774}
775
776static char Xmlparsetype__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000777"XML parser";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000778
779static PyTypeObject Xmlparsetype = {
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000780 PyObject_HEAD_INIT(NULL)
781 0, /*ob_size*/
782 "xmlparser", /*tp_name*/
783 sizeof(xmlparseobject), /*tp_basicsize*/
784 0, /*tp_itemsize*/
785 /* methods */
786 (destructor)xmlparse_dealloc, /*tp_dealloc*/
787 (printfunc)0, /*tp_print*/
788 (getattrfunc)xmlparse_getattr, /*tp_getattr*/
789 (setattrfunc)xmlparse_setattr, /*tp_setattr*/
790 (cmpfunc)0, /*tp_compare*/
791 (reprfunc)0, /*tp_repr*/
792 0, /*tp_as_number*/
793 0, /*tp_as_sequence*/
794 0, /*tp_as_mapping*/
795 (hashfunc)0, /*tp_hash*/
796 (ternaryfunc)0, /*tp_call*/
797 (reprfunc)0, /*tp_str*/
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000798
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000799 /* Space for future expansion */
800 0L,0L,0L,0L,
801 Xmlparsetype__doc__ /* Documentation string */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000802};
803
804/* End of code for xmlparser objects */
805/* -------------------------------------------------------- */
806
807
808static char pyexpat_ParserCreate__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000809"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
810Return a new XML parser object.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000811
812static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000813pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
814{
815 char *encoding = NULL;
816 char *namespace_separator = NULL;
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000817 static char *kwlist[] = {"encoding", "namespace_separator", NULL};
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000818
Fred Drake0582df92000-07-12 04:49:00 +0000819 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000820 &encoding, &namespace_separator))
821 return NULL;
822 return (PyObject *)newxmlparseobject(encoding, namespace_separator);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000823}
824
825static char pyexpat_ErrorString__doc__[] =
Fred Drake0582df92000-07-12 04:49:00 +0000826"ErrorString(errno) -> string\n\
827Returns string error for given number.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000828
829static PyObject *
Fred Drake0582df92000-07-12 04:49:00 +0000830pyexpat_ErrorString(PyObject *self, PyObject *args)
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000831{
Fred Drake0582df92000-07-12 04:49:00 +0000832 long code = 0;
833
834 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
835 return NULL;
836 return Py_BuildValue("z", XML_ErrorString((int)code));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000837}
838
839/* List of methods defined in the module */
840
841static struct PyMethodDef pyexpat_methods[] = {
Fred Drake0582df92000-07-12 04:49:00 +0000842 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
843 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
844 {"ErrorString", (PyCFunction)pyexpat_ErrorString,
845 METH_VARARGS, pyexpat_ErrorString__doc__},
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000846
Fred Drake0582df92000-07-12 04:49:00 +0000847 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000848};
849
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000850/* Module docstring */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000851
852static char pyexpat_module_documentation[] =
Fred Drake0582df92000-07-12 04:49:00 +0000853"Python wrapper for Expat parser.";
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000854
Andrew M. Kuchlingbeba0562000-06-27 00:33:30 +0000855/* Initialization function for the module */
856
Fred Drake6f987622000-08-25 18:03:30 +0000857DL_IMPORT(void) initpyexpat(void);
858
859DL_EXPORT(void)
Fred Drake0582df92000-07-12 04:49:00 +0000860initpyexpat(void)
861{
862 PyObject *m, *d;
863 char *rev = "$Revision$";
Fred Drake6f987622000-08-25 18:03:30 +0000864 PyObject *errmod_name = PyString_FromString("pyexpat.errors");
Fred Drake0582df92000-07-12 04:49:00 +0000865 PyObject *errors_module, *errors_dict;
866 PyObject *sys_modules;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000867
Fred Drake6f987622000-08-25 18:03:30 +0000868 if (errmod_name == NULL)
869 return;
870
Fred Drake0582df92000-07-12 04:49:00 +0000871 Xmlparsetype.ob_type = &PyType_Type;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000872
Fred Drake0582df92000-07-12 04:49:00 +0000873 /* Create the module and add the functions */
874 m = Py_InitModule4("pyexpat", pyexpat_methods,
875 pyexpat_module_documentation,
876 (PyObject*)NULL, PYTHON_API_VERSION);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000877
Fred Drake0582df92000-07-12 04:49:00 +0000878 /* Add some symbolic constants to the module */
879 d = PyModule_GetDict(m);
Fred Drakec23b5232000-08-24 21:57:43 +0000880 if (ErrorObject == NULL)
881 ErrorObject = PyErr_NewException("pyexpat.error", NULL, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000882 PyDict_SetItemString(d, "error", ErrorObject);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000883
Fred Drake0582df92000-07-12 04:49:00 +0000884 PyDict_SetItemString(d, "__version__",
885 PyString_FromStringAndSize(rev+11,
886 strlen(rev+11)-2));
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000887
Fred Drake0582df92000-07-12 04:49:00 +0000888 /* XXX When Expat supports some way of figuring out how it was
889 compiled, this should check and set native_encoding
890 appropriately.
891 */
892 PyDict_SetItemString(d, "native_encoding",
893 PyString_FromString("UTF-8"));
Fred Drakec23b5232000-08-24 21:57:43 +0000894
Fred Drake6f987622000-08-25 18:03:30 +0000895 errors_module = PyDict_GetItem(d, errmod_name);
896 if (errors_module == NULL) {
897 errors_module = PyModule_New("pyexpat.errors");
898 if (errors_module != NULL) {
899 sys_modules = PySys_GetObject("modules");
900 PyDict_SetItemString(d, "errors", errors_module);
901 PyDict_SetItem(sys_modules, errmod_name, errors_module);
Fred Drakec23b5232000-08-24 21:57:43 +0000902 }
903 }
Fred Drake6f987622000-08-25 18:03:30 +0000904 Py_DECREF(errmod_name);
905 if (errors_module == NULL)
906 /* Don't code dump later! */
907 return;
908
Fred Drake0582df92000-07-12 04:49:00 +0000909 errors_dict = PyModule_GetDict(errors_module);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000910
911#define MYCONST(name) \
Fred Drake0582df92000-07-12 04:49:00 +0000912 PyDict_SetItemString(errors_dict, #name, \
913 PyString_FromString(XML_ErrorString(name)))
Fred Drake7bd9f412000-07-04 23:51:31 +0000914
Fred Drake0582df92000-07-12 04:49:00 +0000915 MYCONST(XML_ERROR_NO_MEMORY);
916 MYCONST(XML_ERROR_SYNTAX);
917 MYCONST(XML_ERROR_NO_ELEMENTS);
918 MYCONST(XML_ERROR_INVALID_TOKEN);
919 MYCONST(XML_ERROR_UNCLOSED_TOKEN);
920 MYCONST(XML_ERROR_PARTIAL_CHAR);
921 MYCONST(XML_ERROR_TAG_MISMATCH);
922 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
923 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
924 MYCONST(XML_ERROR_PARAM_ENTITY_REF);
925 MYCONST(XML_ERROR_UNDEFINED_ENTITY);
926 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
927 MYCONST(XML_ERROR_ASYNC_ENTITY);
928 MYCONST(XML_ERROR_BAD_CHAR_REF);
929 MYCONST(XML_ERROR_BINARY_ENTITY_REF);
930 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
931 MYCONST(XML_ERROR_MISPLACED_XML_PI);
932 MYCONST(XML_ERROR_UNKNOWN_ENCODING);
933 MYCONST(XML_ERROR_INCORRECT_ENCODING);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000934}
935
Fred Drake6f987622000-08-25 18:03:30 +0000936static void
937clear_handlers(xmlparseobject *self)
Fred Drake0582df92000-07-12 04:49:00 +0000938{
939 int i = 0;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000940
Fred Drake0582df92000-07-12 04:49:00 +0000941 for (; handler_info[i].name!=NULL; i++) {
942 self->handlers[i]=NULL;
Fred Drake6f987622000-08-25 18:03:30 +0000943 handler_info[i].setter(self->itself, NULL);
Fred Drake0582df92000-07-12 04:49:00 +0000944 }
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000945}
946
Fred Drake6f987622000-08-25 18:03:30 +0000947typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000948
Fred Drake6f987622000-08-25 18:03:30 +0000949static void
950pyxml_UpdatePairedHandlers(xmlparseobject *self,
951 int startHandler,
952 int endHandler,
953 pairsetter setter)
Fred Drake0582df92000-07-12 04:49:00 +0000954{
955 void *start_handler=NULL;
956 void *end_handler=NULL;
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000957
Fred Drake0582df92000-07-12 04:49:00 +0000958 if (self->handlers[startHandler]
959 && self->handlers[endHandler]!=Py_None) {
960 start_handler=handler_info[startHandler].handler;
961 }
962 if (self->handlers[EndElement]
963 && self->handlers[EndElement] !=Py_None) {
964 end_handler=handler_info[endHandler].handler;
965 }
966 setter(self->itself, start_handler, end_handler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000967}
968
Fred Drake6f987622000-08-25 18:03:30 +0000969static void
970pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000971{
972 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
973 StartElement, EndElement,
974 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000975}
976
Fred Drake6f987622000-08-25 18:03:30 +0000977static void
978pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000979{
980 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
981 StartElement, EndElement,
982 (pairsetter)XML_SetElementHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000983}
984
Fred Drake6f987622000-08-25 18:03:30 +0000985static void
986pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000987{
988 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
989 StartNamespaceDecl, EndNamespaceDecl,
990 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000991}
992
Fred Drake6f987622000-08-25 18:03:30 +0000993static void
994pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +0000995{
996 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
997 StartNamespaceDecl, EndNamespaceDecl,
998 (pairsetter)XML_SetNamespaceDeclHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +0000999}
1000
Fred Drake6f987622000-08-25 18:03:30 +00001001static void
1002pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001003{
1004 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1005 StartCdataSection, EndCdataSection,
1006 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001007}
1008
Fred Drake6f987622000-08-25 18:03:30 +00001009static void
1010pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
Fred Drake0582df92000-07-12 04:49:00 +00001011{
1012 pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
1013 StartCdataSection, EndCdataSection,
1014 (pairsetter)XML_SetCdataSectionHandler);
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001015}
1016
Fred Drake0582df92000-07-12 04:49:00 +00001017statichere struct HandlerInfo handler_info[] = {
1018 {"StartElementHandler",
1019 pyxml_SetStartElementHandler,
1020 (xmlhandler)my_StartElementHandler},
1021 {"EndElementHandler",
1022 pyxml_SetEndElementHandler,
1023 (xmlhandler)my_EndElementHandler},
1024 {"ProcessingInstructionHandler",
1025 (xmlhandlersetter)XML_SetProcessingInstructionHandler,
1026 (xmlhandler)my_ProcessingInstructionHandler},
1027 {"CharacterDataHandler",
1028 (xmlhandlersetter)XML_SetCharacterDataHandler,
1029 (xmlhandler)my_CharacterDataHandler},
1030 {"UnparsedEntityDeclHandler",
1031 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
1032 (xmlhandler)my_UnparsedEntityDeclHandler },
1033 {"NotationDeclHandler",
1034 (xmlhandlersetter)XML_SetNotationDeclHandler,
1035 (xmlhandler)my_NotationDeclHandler },
1036 {"StartNamespaceDeclHandler",
1037 pyxml_SetStartNamespaceDeclHandler,
1038 (xmlhandler)my_StartNamespaceDeclHandler },
1039 {"EndNamespaceDeclHandler",
1040 pyxml_SetEndNamespaceDeclHandler,
1041 (xmlhandler)my_EndNamespaceDeclHandler },
1042 {"CommentHandler",
1043 (xmlhandlersetter)XML_SetCommentHandler,
1044 (xmlhandler)my_CommentHandler},
1045 {"StartCdataSectionHandler",
1046 pyxml_SetStartCdataSection,
1047 (xmlhandler)my_StartCdataSectionHandler},
1048 {"EndCdataSectionHandler",
1049 pyxml_SetEndCdataSection,
1050 (xmlhandler)my_EndCdataSectionHandler},
1051 {"DefaultHandler",
1052 (xmlhandlersetter)XML_SetDefaultHandler,
1053 (xmlhandler)my_DefaultHandler},
1054 {"DefaultHandlerExpand",
1055 (xmlhandlersetter)XML_SetDefaultHandlerExpand,
1056 (xmlhandler)my_DefaultHandlerExpandHandler},
1057 {"NotStandaloneHandler",
1058 (xmlhandlersetter)XML_SetNotStandaloneHandler,
1059 (xmlhandler)my_NotStandaloneHandler},
1060 {"ExternalEntityRefHandler",
1061 (xmlhandlersetter)XML_SetExternalEntityRefHandler,
1062 (xmlhandler)my_ExternalEntityRefHandler },
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001063
Fred Drake0582df92000-07-12 04:49:00 +00001064 {NULL, NULL, NULL} /* sentinel */
Andrew M. Kuchlingb7f10532000-03-31 15:43:31 +00001065};