]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Modules/pyexpat.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Modules / pyexpat.c
CommitLineData
7eb75bcc
DM
1#include "Python.h"\r
2#include <ctype.h>\r
3\r
4#include "frameobject.h"\r
5#include "expat.h"\r
6\r
7#include "pyexpat.h"\r
8\r
9#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)\r
10\r
11#ifndef PyDoc_STRVAR\r
12\r
13/*\r
14 * fdrake says:\r
15 * Don't change the PyDoc_STR macro definition to (str), because\r
16 * '''the parentheses cause compile failures\r
17 * ("non-constant static initializer" or something like that)\r
18 * on some platforms (Irix?)'''\r
19 */\r
20#define PyDoc_STR(str) str\r
21#define PyDoc_VAR(name) static char name[]\r
22#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)\r
23#endif\r
24\r
25#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)\r
26/* In Python 2.0 and 2.1, disabling Unicode was not possible. */\r
27#define Py_USING_UNICODE\r
28#else\r
29#define FIX_TRACE\r
30#endif\r
31\r
32enum HandlerTypes {\r
33 StartElement,\r
34 EndElement,\r
35 ProcessingInstruction,\r
36 CharacterData,\r
37 UnparsedEntityDecl,\r
38 NotationDecl,\r
39 StartNamespaceDecl,\r
40 EndNamespaceDecl,\r
41 Comment,\r
42 StartCdataSection,\r
43 EndCdataSection,\r
44 Default,\r
45 DefaultHandlerExpand,\r
46 NotStandalone,\r
47 ExternalEntityRef,\r
48 StartDoctypeDecl,\r
49 EndDoctypeDecl,\r
50 EntityDecl,\r
51 XmlDecl,\r
52 ElementDecl,\r
53 AttlistDecl,\r
54#if XML_COMBINED_VERSION >= 19504\r
55 SkippedEntity,\r
56#endif\r
57 _DummyDecl\r
58};\r
59\r
60static PyObject *ErrorObject;\r
61\r
62/* ----------------------------------------------------- */\r
63\r
64/* Declarations for objects of type xmlparser */\r
65\r
66typedef struct {\r
67 PyObject_HEAD\r
68\r
69 XML_Parser itself;\r
70 int returns_unicode; /* True if Unicode strings are returned;\r
71 if false, UTF-8 strings are returned */\r
72 int ordered_attributes; /* Return attributes as a list. */\r
73 int specified_attributes; /* Report only specified attributes. */\r
74 int in_callback; /* Is a callback active? */\r
75 int ns_prefixes; /* Namespace-triplets mode? */\r
76 XML_Char *buffer; /* Buffer used when accumulating characters */\r
77 /* NULL if not enabled */\r
78 int buffer_size; /* Size of buffer, in XML_Char units */\r
79 int buffer_used; /* Buffer units in use */\r
80 PyObject *intern; /* Dictionary to intern strings */\r
81 PyObject **handlers;\r
82} xmlparseobject;\r
83\r
84#define CHARACTER_DATA_BUFFER_SIZE 8192\r
85\r
86static PyTypeObject Xmlparsetype;\r
87\r
88typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);\r
89typedef void* xmlhandler;\r
90\r
91struct HandlerInfo {\r
92 const char *name;\r
93 xmlhandlersetter setter;\r
94 xmlhandler handler;\r
95 PyCodeObject *tb_code;\r
96 PyObject *nameobj;\r
97};\r
98\r
99static struct HandlerInfo handler_info[64];\r
100\r
101/* Set an integer attribute on the error object; return true on success,\r
102 * false on an exception.\r
103 */\r
104static int\r
105set_error_attr(PyObject *err, char *name, int value)\r
106{\r
107 PyObject *v = PyInt_FromLong(value);\r
108\r
109 if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {\r
110 Py_XDECREF(v);\r
111 return 0;\r
112 }\r
113 Py_DECREF(v);\r
114 return 1;\r
115}\r
116\r
117/* Build and set an Expat exception, including positioning\r
118 * information. Always returns NULL.\r
119 */\r
120static PyObject *\r
121set_error(xmlparseobject *self, enum XML_Error code)\r
122{\r
123 PyObject *err;\r
124 char buffer[256];\r
125 XML_Parser parser = self->itself;\r
126 int lineno = XML_GetErrorLineNumber(parser);\r
127 int column = XML_GetErrorColumnNumber(parser);\r
128\r
129 /* There is no risk of overflowing this buffer, since\r
130 even for 64-bit integers, there is sufficient space. */\r
131 sprintf(buffer, "%.200s: line %i, column %i",\r
132 XML_ErrorString(code), lineno, column);\r
133 err = PyObject_CallFunction(ErrorObject, "s", buffer);\r
134 if ( err != NULL\r
135 && set_error_attr(err, "code", code)\r
136 && set_error_attr(err, "offset", column)\r
137 && set_error_attr(err, "lineno", lineno)) {\r
138 PyErr_SetObject(ErrorObject, err);\r
139 }\r
140 Py_XDECREF(err);\r
141 return NULL;\r
142}\r
143\r
144static int\r
145have_handler(xmlparseobject *self, int type)\r
146{\r
147 PyObject *handler = self->handlers[type];\r
148 return handler != NULL;\r
149}\r
150\r
151static PyObject *\r
152get_handler_name(struct HandlerInfo *hinfo)\r
153{\r
154 PyObject *name = hinfo->nameobj;\r
155 if (name == NULL) {\r
156 name = PyString_FromString(hinfo->name);\r
157 hinfo->nameobj = name;\r
158 }\r
159 Py_XINCREF(name);\r
160 return name;\r
161}\r
162\r
163\r
164#ifdef Py_USING_UNICODE\r
165/* Convert a string of XML_Chars into a Unicode string.\r
166 Returns None if str is a null pointer. */\r
167\r
168static PyObject *\r
169conv_string_to_unicode(const XML_Char *str)\r
170{\r
171 /* XXX currently this code assumes that XML_Char is 8-bit,\r
172 and hence in UTF-8. */\r
173 /* UTF-8 from Expat, Unicode desired */\r
174 if (str == NULL) {\r
175 Py_INCREF(Py_None);\r
176 return Py_None;\r
177 }\r
178 return PyUnicode_DecodeUTF8(str, strlen(str), "strict");\r
179}\r
180\r
181static PyObject *\r
182conv_string_len_to_unicode(const XML_Char *str, int len)\r
183{\r
184 /* XXX currently this code assumes that XML_Char is 8-bit,\r
185 and hence in UTF-8. */\r
186 /* UTF-8 from Expat, Unicode desired */\r
187 if (str == NULL) {\r
188 Py_INCREF(Py_None);\r
189 return Py_None;\r
190 }\r
191 return PyUnicode_DecodeUTF8((const char *)str, len, "strict");\r
192}\r
193#endif\r
194\r
195/* Convert a string of XML_Chars into an 8-bit Python string.\r
196 Returns None if str is a null pointer. */\r
197\r
198static PyObject *\r
199conv_string_to_utf8(const XML_Char *str)\r
200{\r
201 /* XXX currently this code assumes that XML_Char is 8-bit,\r
202 and hence in UTF-8. */\r
203 /* UTF-8 from Expat, UTF-8 desired */\r
204 if (str == NULL) {\r
205 Py_INCREF(Py_None);\r
206 return Py_None;\r
207 }\r
208 return PyString_FromString(str);\r
209}\r
210\r
211static PyObject *\r
212conv_string_len_to_utf8(const XML_Char *str, int len)\r
213{\r
214 /* XXX currently this code assumes that XML_Char is 8-bit,\r
215 and hence in UTF-8. */\r
216 /* UTF-8 from Expat, UTF-8 desired */\r
217 if (str == NULL) {\r
218 Py_INCREF(Py_None);\r
219 return Py_None;\r
220 }\r
221 return PyString_FromStringAndSize((const char *)str, len);\r
222}\r
223\r
224/* Callback routines */\r
225\r
226static void clear_handlers(xmlparseobject *self, int initial);\r
227\r
228/* This handler is used when an error has been detected, in the hope\r
229 that actual parsing can be terminated early. This will only help\r
230 if an external entity reference is encountered. */\r
231static int\r
232error_external_entity_ref_handler(XML_Parser parser,\r
233 const XML_Char *context,\r
234 const XML_Char *base,\r
235 const XML_Char *systemId,\r
236 const XML_Char *publicId)\r
237{\r
238 return 0;\r
239}\r
240\r
241/* Dummy character data handler used when an error (exception) has\r
242 been detected, and the actual parsing can be terminated early.\r
243 This is needed since character data handler can't be safely removed\r
244 from within the character data handler, but can be replaced. It is\r
245 used only from the character data handler trampoline, and must be\r
246 used right after `flag_error()` is called. */\r
247static void\r
248noop_character_data_handler(void *userData, const XML_Char *data, int len)\r
249{\r
250 /* Do nothing. */\r
251}\r
252\r
253static void\r
254flag_error(xmlparseobject *self)\r
255{\r
256 clear_handlers(self, 0);\r
257 XML_SetExternalEntityRefHandler(self->itself,\r
258 error_external_entity_ref_handler);\r
259}\r
260\r
261static PyCodeObject*\r
262getcode(enum HandlerTypes slot, char* func_name, int lineno)\r
263{\r
264 if (handler_info[slot].tb_code == NULL) {\r
265 handler_info[slot].tb_code =\r
266 PyCode_NewEmpty(__FILE__, func_name, lineno);\r
267 }\r
268 return handler_info[slot].tb_code;\r
269}\r
270\r
271#ifdef FIX_TRACE\r
272static int\r
273trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)\r
274{\r
275 int result = 0;\r
276 if (!tstate->use_tracing || tstate->tracing)\r
277 return 0;\r
278 if (tstate->c_profilefunc != NULL) {\r
279 tstate->tracing++;\r
280 result = tstate->c_profilefunc(tstate->c_profileobj,\r
281 f, code , val);\r
282 tstate->use_tracing = ((tstate->c_tracefunc != NULL)\r
283 || (tstate->c_profilefunc != NULL));\r
284 tstate->tracing--;\r
285 if (result)\r
286 return result;\r
287 }\r
288 if (tstate->c_tracefunc != NULL) {\r
289 tstate->tracing++;\r
290 result = tstate->c_tracefunc(tstate->c_traceobj,\r
291 f, code , val);\r
292 tstate->use_tracing = ((tstate->c_tracefunc != NULL)\r
293 || (tstate->c_profilefunc != NULL));\r
294 tstate->tracing--;\r
295 }\r
296 return result;\r
297}\r
298\r
299static int\r
300trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)\r
301{\r
302 PyObject *type, *value, *traceback, *arg;\r
303 int err;\r
304\r
305 if (tstate->c_tracefunc == NULL)\r
306 return 0;\r
307\r
308 PyErr_Fetch(&type, &value, &traceback);\r
309 if (value == NULL) {\r
310 value = Py_None;\r
311 Py_INCREF(value);\r
312 }\r
313#if PY_VERSION_HEX < 0x02040000\r
314 arg = Py_BuildValue("(OOO)", type, value, traceback);\r
315#else\r
316 arg = PyTuple_Pack(3, type, value, traceback);\r
317#endif\r
318 if (arg == NULL) {\r
319 PyErr_Restore(type, value, traceback);\r
320 return 0;\r
321 }\r
322 err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);\r
323 Py_DECREF(arg);\r
324 if (err == 0)\r
325 PyErr_Restore(type, value, traceback);\r
326 else {\r
327 Py_XDECREF(type);\r
328 Py_XDECREF(value);\r
329 Py_XDECREF(traceback);\r
330 }\r
331 return err;\r
332}\r
333#endif\r
334\r
335static PyObject*\r
336call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,\r
337 xmlparseobject *self)\r
338{\r
339 PyThreadState *tstate = PyThreadState_GET();\r
340 PyFrameObject *f;\r
341 PyObject *res;\r
342\r
343 if (c == NULL)\r
344 return NULL;\r
345\r
346 f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);\r
347 if (f == NULL)\r
348 return NULL;\r
349 tstate->frame = f;\r
350#ifdef FIX_TRACE\r
351 if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {\r
352 return NULL;\r
353 }\r
354#endif\r
355 res = PyEval_CallObject(func, args);\r
356 if (res == NULL) {\r
357 if (tstate->curexc_traceback == NULL)\r
358 PyTraceBack_Here(f);\r
359 XML_StopParser(self->itself, XML_FALSE);\r
360#ifdef FIX_TRACE\r
361 if (trace_frame_exc(tstate, f) < 0) {\r
362 return NULL;\r
363 }\r
364 }\r
365 else {\r
366 if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {\r
367 Py_XDECREF(res);\r
368 res = NULL;\r
369 }\r
370 }\r
371#else\r
372 }\r
373#endif\r
374 tstate->frame = f->f_back;\r
375 Py_DECREF(f);\r
376 return res;\r
377}\r
378\r
379#ifndef Py_USING_UNICODE\r
380#define STRING_CONV_FUNC conv_string_to_utf8\r
381#else\r
382/* Python 2.0 and later versions, when built with Unicode support */\r
383#define STRING_CONV_FUNC (self->returns_unicode \\r
384 ? conv_string_to_unicode : conv_string_to_utf8)\r
385#endif\r
386\r
387static PyObject*\r
388string_intern(xmlparseobject *self, const char* str)\r
389{\r
390 PyObject *result = STRING_CONV_FUNC(str);\r
391 PyObject *value;\r
392 /* result can be NULL if the unicode conversion failed. */\r
393 if (!result)\r
394 return result;\r
395 if (!self->intern)\r
396 return result;\r
397 value = PyDict_GetItem(self->intern, result);\r
398 if (!value) {\r
399 if (PyDict_SetItem(self->intern, result, result) == 0)\r
400 return result;\r
401 else\r
402 return NULL;\r
403 }\r
404 Py_INCREF(value);\r
405 Py_DECREF(result);\r
406 return value;\r
407}\r
408\r
409/* Return 0 on success, -1 on exception.\r
410 * flag_error() will be called before return if needed.\r
411 */\r
412static int\r
413call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)\r
414{\r
415 PyObject *args;\r
416 PyObject *temp;\r
417\r
418 if (!have_handler(self, CharacterData))\r
419 return -1;\r
420\r
421 args = PyTuple_New(1);\r
422 if (args == NULL)\r
423 return -1;\r
424#ifdef Py_USING_UNICODE\r
425 temp = (self->returns_unicode\r
426 ? conv_string_len_to_unicode(buffer, len)\r
427 : conv_string_len_to_utf8(buffer, len));\r
428#else\r
429 temp = conv_string_len_to_utf8(buffer, len);\r
430#endif\r
431 if (temp == NULL) {\r
432 Py_DECREF(args);\r
433 flag_error(self);\r
434 XML_SetCharacterDataHandler(self->itself,\r
435 noop_character_data_handler);\r
436 return -1;\r
437 }\r
438 PyTuple_SET_ITEM(args, 0, temp);\r
439 /* temp is now a borrowed reference; consider it unused. */\r
440 self->in_callback = 1;\r
441 temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),\r
442 self->handlers[CharacterData], args, self);\r
443 /* temp is an owned reference again, or NULL */\r
444 self->in_callback = 0;\r
445 Py_DECREF(args);\r
446 if (temp == NULL) {\r
447 flag_error(self);\r
448 XML_SetCharacterDataHandler(self->itself,\r
449 noop_character_data_handler);\r
450 return -1;\r
451 }\r
452 Py_DECREF(temp);\r
453 return 0;\r
454}\r
455\r
456static int\r
457flush_character_buffer(xmlparseobject *self)\r
458{\r
459 int rc;\r
460 if (self->buffer == NULL || self->buffer_used == 0)\r
461 return 0;\r
462 rc = call_character_handler(self, self->buffer, self->buffer_used);\r
463 self->buffer_used = 0;\r
464 return rc;\r
465}\r
466\r
467static void\r
468my_CharacterDataHandler(void *userData, const XML_Char *data, int len)\r
469{\r
470 xmlparseobject *self = (xmlparseobject *) userData;\r
471 if (self->buffer == NULL)\r
472 call_character_handler(self, data, len);\r
473 else {\r
474 if ((self->buffer_used + len) > self->buffer_size) {\r
475 if (flush_character_buffer(self) < 0)\r
476 return;\r
477 /* handler might have changed; drop the rest on the floor\r
478 * if there isn't a handler anymore\r
479 */\r
480 if (!have_handler(self, CharacterData))\r
481 return;\r
482 }\r
483 if (len > self->buffer_size) {\r
484 call_character_handler(self, data, len);\r
485 self->buffer_used = 0;\r
486 }\r
487 else {\r
488 memcpy(self->buffer + self->buffer_used,\r
489 data, len * sizeof(XML_Char));\r
490 self->buffer_used += len;\r
491 }\r
492 }\r
493}\r
494\r
495static void\r
496my_StartElementHandler(void *userData,\r
497 const XML_Char *name, const XML_Char *atts[])\r
498{\r
499 xmlparseobject *self = (xmlparseobject *)userData;\r
500\r
501 if (have_handler(self, StartElement)) {\r
502 PyObject *container, *rv, *args;\r
503 int i, max;\r
504\r
505 if (flush_character_buffer(self) < 0)\r
506 return;\r
507 /* Set max to the number of slots filled in atts[]; max/2 is\r
508 * the number of attributes we need to process.\r
509 */\r
510 if (self->specified_attributes) {\r
511 max = XML_GetSpecifiedAttributeCount(self->itself);\r
512 }\r
513 else {\r
514 max = 0;\r
515 while (atts[max] != NULL)\r
516 max += 2;\r
517 }\r
518 /* Build the container. */\r
519 if (self->ordered_attributes)\r
520 container = PyList_New(max);\r
521 else\r
522 container = PyDict_New();\r
523 if (container == NULL) {\r
524 flag_error(self);\r
525 return;\r
526 }\r
527 for (i = 0; i < max; i += 2) {\r
528 PyObject *n = string_intern(self, (XML_Char *) atts[i]);\r
529 PyObject *v;\r
530 if (n == NULL) {\r
531 flag_error(self);\r
532 Py_DECREF(container);\r
533 return;\r
534 }\r
535 v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);\r
536 if (v == NULL) {\r
537 flag_error(self);\r
538 Py_DECREF(container);\r
539 Py_DECREF(n);\r
540 return;\r
541 }\r
542 if (self->ordered_attributes) {\r
543 PyList_SET_ITEM(container, i, n);\r
544 PyList_SET_ITEM(container, i+1, v);\r
545 }\r
546 else if (PyDict_SetItem(container, n, v)) {\r
547 flag_error(self);\r
548 Py_DECREF(n);\r
549 Py_DECREF(v);\r
550 return;\r
551 }\r
552 else {\r
553 Py_DECREF(n);\r
554 Py_DECREF(v);\r
555 }\r
556 }\r
557 args = string_intern(self, name);\r
558 if (args != NULL)\r
559 args = Py_BuildValue("(NN)", args, container);\r
560 if (args == NULL) {\r
561 Py_DECREF(container);\r
562 return;\r
563 }\r
564 /* Container is now a borrowed reference; ignore it. */\r
565 self->in_callback = 1;\r
566 rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),\r
567 self->handlers[StartElement], args, self);\r
568 self->in_callback = 0;\r
569 Py_DECREF(args);\r
570 if (rv == NULL) {\r
571 flag_error(self);\r
572 return;\r
573 }\r
574 Py_DECREF(rv);\r
575 }\r
576}\r
577\r
578#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \\r
579 RETURN, GETUSERDATA) \\r
580static RC \\r
581my_##NAME##Handler PARAMS {\\r
582 xmlparseobject *self = GETUSERDATA ; \\r
583 PyObject *args = NULL; \\r
584 PyObject *rv = NULL; \\r
585 INIT \\r
586\\r
587 if (have_handler(self, NAME)) { \\r
588 if (flush_character_buffer(self) < 0) \\r
589 return RETURN; \\r
590 args = Py_BuildValue PARAM_FORMAT ;\\r
591 if (!args) { flag_error(self); return RETURN;} \\r
592 self->in_callback = 1; \\r
593 rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \\r
594 self->handlers[NAME], args, self); \\r
595 self->in_callback = 0; \\r
596 Py_DECREF(args); \\r
597 if (rv == NULL) { \\r
598 flag_error(self); \\r
599 return RETURN; \\r
600 } \\r
601 CONVERSION \\r
602 Py_DECREF(rv); \\r
603 } \\r
604 return RETURN; \\r
605}\r
606\r
607#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \\r
608 RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\\r
609 (xmlparseobject *)userData)\r
610\r
611#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\\r
612 RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \\r
613 rc = PyInt_AsLong(rv);, rc, \\r
614 (xmlparseobject *)userData)\r
615\r
616VOID_HANDLER(EndElement,\r
617 (void *userData, const XML_Char *name),\r
618 ("(N)", string_intern(self, name)))\r
619\r
620VOID_HANDLER(ProcessingInstruction,\r
621 (void *userData,\r
622 const XML_Char *target,\r
623 const XML_Char *data),\r
624 ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))\r
625\r
626VOID_HANDLER(UnparsedEntityDecl,\r
627 (void *userData,\r
628 const XML_Char *entityName,\r
629 const XML_Char *base,\r
630 const XML_Char *systemId,\r
631 const XML_Char *publicId,\r
632 const XML_Char *notationName),\r
633 ("(NNNNN)",\r
634 string_intern(self, entityName), string_intern(self, base),\r
635 string_intern(self, systemId), string_intern(self, publicId),\r
636 string_intern(self, notationName)))\r
637\r
638#ifndef Py_USING_UNICODE\r
639VOID_HANDLER(EntityDecl,\r
640 (void *userData,\r
641 const XML_Char *entityName,\r
642 int is_parameter_entity,\r
643 const XML_Char *value,\r
644 int value_length,\r
645 const XML_Char *base,\r
646 const XML_Char *systemId,\r
647 const XML_Char *publicId,\r
648 const XML_Char *notationName),\r
649 ("NiNNNNN",\r
650 string_intern(self, entityName), is_parameter_entity,\r
651 conv_string_len_to_utf8(value, value_length),\r
652 string_intern(self, base), string_intern(self, systemId),\r
653 string_intern(self, publicId),\r
654 string_intern(self, notationName)))\r
655#else\r
656VOID_HANDLER(EntityDecl,\r
657 (void *userData,\r
658 const XML_Char *entityName,\r
659 int is_parameter_entity,\r
660 const XML_Char *value,\r
661 int value_length,\r
662 const XML_Char *base,\r
663 const XML_Char *systemId,\r
664 const XML_Char *publicId,\r
665 const XML_Char *notationName),\r
666 ("NiNNNNN",\r
667 string_intern(self, entityName), is_parameter_entity,\r
668 (self->returns_unicode\r
669 ? conv_string_len_to_unicode(value, value_length)\r
670 : conv_string_len_to_utf8(value, value_length)),\r
671 string_intern(self, base), string_intern(self, systemId),\r
672 string_intern(self, publicId),\r
673 string_intern(self, notationName)))\r
674#endif\r
675\r
676VOID_HANDLER(XmlDecl,\r
677 (void *userData,\r
678 const XML_Char *version,\r
679 const XML_Char *encoding,\r
680 int standalone),\r
681 ("(O&O&i)",\r
682 STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,\r
683 standalone))\r
684\r
685static PyObject *\r
686conv_content_model(XML_Content * const model,\r
687 PyObject *(*conv_string)(const XML_Char *))\r
688{\r
689 PyObject *result = NULL;\r
690 PyObject *children = PyTuple_New(model->numchildren);\r
691 int i;\r
692\r
693 if (children != NULL) {\r
694 assert(model->numchildren < INT_MAX);\r
695 for (i = 0; i < (int)model->numchildren; ++i) {\r
696 PyObject *child = conv_content_model(&model->children[i],\r
697 conv_string);\r
698 if (child == NULL) {\r
699 Py_XDECREF(children);\r
700 return NULL;\r
701 }\r
702 PyTuple_SET_ITEM(children, i, child);\r
703 }\r
704 result = Py_BuildValue("(iiO&N)",\r
705 model->type, model->quant,\r
706 conv_string,model->name, children);\r
707 }\r
708 return result;\r
709}\r
710\r
711static void\r
712my_ElementDeclHandler(void *userData,\r
713 const XML_Char *name,\r
714 XML_Content *model)\r
715{\r
716 xmlparseobject *self = (xmlparseobject *)userData;\r
717 PyObject *args = NULL;\r
718\r
719 if (have_handler(self, ElementDecl)) {\r
720 PyObject *rv = NULL;\r
721 PyObject *modelobj, *nameobj;\r
722\r
723 if (flush_character_buffer(self) < 0)\r
724 goto finally;\r
725#ifdef Py_USING_UNICODE\r
726 modelobj = conv_content_model(model,\r
727 (self->returns_unicode\r
728 ? conv_string_to_unicode\r
729 : conv_string_to_utf8));\r
730#else\r
731 modelobj = conv_content_model(model, conv_string_to_utf8);\r
732#endif\r
733 if (modelobj == NULL) {\r
734 flag_error(self);\r
735 goto finally;\r
736 }\r
737 nameobj = string_intern(self, name);\r
738 if (nameobj == NULL) {\r
739 Py_DECREF(modelobj);\r
740 flag_error(self);\r
741 goto finally;\r
742 }\r
743 args = Py_BuildValue("NN", nameobj, modelobj);\r
744 if (args == NULL) {\r
745 Py_DECREF(modelobj);\r
746 flag_error(self);\r
747 goto finally;\r
748 }\r
749 self->in_callback = 1;\r
750 rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),\r
751 self->handlers[ElementDecl], args, self);\r
752 self->in_callback = 0;\r
753 if (rv == NULL) {\r
754 flag_error(self);\r
755 goto finally;\r
756 }\r
757 Py_DECREF(rv);\r
758 }\r
759 finally:\r
760 Py_XDECREF(args);\r
761 XML_FreeContentModel(self->itself, model);\r
762 return;\r
763}\r
764\r
765VOID_HANDLER(AttlistDecl,\r
766 (void *userData,\r
767 const XML_Char *elname,\r
768 const XML_Char *attname,\r
769 const XML_Char *att_type,\r
770 const XML_Char *dflt,\r
771 int isrequired),\r
772 ("(NNO&O&i)",\r
773 string_intern(self, elname), string_intern(self, attname),\r
774 STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,\r
775 isrequired))\r
776\r
777#if XML_COMBINED_VERSION >= 19504\r
778VOID_HANDLER(SkippedEntity,\r
779 (void *userData,\r
780 const XML_Char *entityName,\r
781 int is_parameter_entity),\r
782 ("Ni",\r
783 string_intern(self, entityName), is_parameter_entity))\r
784#endif\r
785\r
786VOID_HANDLER(NotationDecl,\r
787 (void *userData,\r
788 const XML_Char *notationName,\r
789 const XML_Char *base,\r
790 const XML_Char *systemId,\r
791 const XML_Char *publicId),\r
792 ("(NNNN)",\r
793 string_intern(self, notationName), string_intern(self, base),\r
794 string_intern(self, systemId), string_intern(self, publicId)))\r
795\r
796VOID_HANDLER(StartNamespaceDecl,\r
797 (void *userData,\r
798 const XML_Char *prefix,\r
799 const XML_Char *uri),\r
800 ("(NN)",\r
801 string_intern(self, prefix), string_intern(self, uri)))\r
802\r
803VOID_HANDLER(EndNamespaceDecl,\r
804 (void *userData,\r
805 const XML_Char *prefix),\r
806 ("(N)", string_intern(self, prefix)))\r
807\r
808VOID_HANDLER(Comment,\r
809 (void *userData, const XML_Char *data),\r
810 ("(O&)", STRING_CONV_FUNC,data))\r
811\r
812VOID_HANDLER(StartCdataSection,\r
813 (void *userData),\r
814 ("()"))\r
815\r
816VOID_HANDLER(EndCdataSection,\r
817 (void *userData),\r
818 ("()"))\r
819\r
820#ifndef Py_USING_UNICODE\r
821VOID_HANDLER(Default,\r
822 (void *userData, const XML_Char *s, int len),\r
823 ("(N)", conv_string_len_to_utf8(s,len)))\r
824\r
825VOID_HANDLER(DefaultHandlerExpand,\r
826 (void *userData, const XML_Char *s, int len),\r
827 ("(N)", conv_string_len_to_utf8(s,len)))\r
828#else\r
829VOID_HANDLER(Default,\r
830 (void *userData, const XML_Char *s, int len),\r
831 ("(N)", (self->returns_unicode\r
832 ? conv_string_len_to_unicode(s,len)\r
833 : conv_string_len_to_utf8(s,len))))\r
834\r
835VOID_HANDLER(DefaultHandlerExpand,\r
836 (void *userData, const XML_Char *s, int len),\r
837 ("(N)", (self->returns_unicode\r
838 ? conv_string_len_to_unicode(s,len)\r
839 : conv_string_len_to_utf8(s,len))))\r
840#endif\r
841\r
842INT_HANDLER(NotStandalone,\r
843 (void *userData),\r
844 ("()"))\r
845\r
846RC_HANDLER(int, ExternalEntityRef,\r
847 (XML_Parser parser,\r
848 const XML_Char *context,\r
849 const XML_Char *base,\r
850 const XML_Char *systemId,\r
851 const XML_Char *publicId),\r
852 int rc=0;,\r
853 ("(O&NNN)",\r
854 STRING_CONV_FUNC,context, string_intern(self, base),\r
855 string_intern(self, systemId), string_intern(self, publicId)),\r
856 rc = PyInt_AsLong(rv);, rc,\r
857 XML_GetUserData(parser))\r
858\r
859/* XXX UnknownEncodingHandler */\r
860\r
861VOID_HANDLER(StartDoctypeDecl,\r
862 (void *userData, const XML_Char *doctypeName,\r
863 const XML_Char *sysid, const XML_Char *pubid,\r
864 int has_internal_subset),\r
865 ("(NNNi)", string_intern(self, doctypeName),\r
866 string_intern(self, sysid), string_intern(self, pubid),\r
867 has_internal_subset))\r
868\r
869VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))\r
870\r
871/* ---------------------------------------------------------------- */\r
872\r
873static PyObject *\r
874get_parse_result(xmlparseobject *self, int rv)\r
875{\r
876 if (PyErr_Occurred()) {\r
877 return NULL;\r
878 }\r
879 if (rv == 0) {\r
880 return set_error(self, XML_GetErrorCode(self->itself));\r
881 }\r
882 if (flush_character_buffer(self) < 0) {\r
883 return NULL;\r
884 }\r
885 return PyInt_FromLong(rv);\r
886}\r
887\r
888PyDoc_STRVAR(xmlparse_Parse__doc__,\r
889"Parse(data[, isfinal])\n\\r
890Parse XML data. `isfinal' should be true at end of input.");\r
891\r
892static PyObject *\r
893xmlparse_Parse(xmlparseobject *self, PyObject *args)\r
894{\r
895 char *s;\r
896 int slen;\r
897 int isFinal = 0;\r
898\r
899 if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))\r
900 return NULL;\r
901\r
902 return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));\r
903}\r
904\r
905/* File reading copied from cPickle */\r
906\r
907#define BUF_SIZE 2048\r
908\r
909static int\r
910readinst(char *buf, int buf_size, PyObject *meth)\r
911{\r
912 PyObject *arg = NULL;\r
913 PyObject *bytes = NULL;\r
914 PyObject *str = NULL;\r
915 int len = -1;\r
916\r
917 if ((bytes = PyInt_FromLong(buf_size)) == NULL)\r
918 goto finally;\r
919\r
920 if ((arg = PyTuple_New(1)) == NULL) {\r
921 Py_DECREF(bytes);\r
922 goto finally;\r
923 }\r
924\r
925 PyTuple_SET_ITEM(arg, 0, bytes);\r
926\r
927#if PY_VERSION_HEX < 0x02020000\r
928 str = PyObject_CallObject(meth, arg);\r
929#else\r
930 str = PyObject_Call(meth, arg, NULL);\r
931#endif\r
932 if (str == NULL)\r
933 goto finally;\r
934\r
935 /* XXX what to do if it returns a Unicode string? */\r
936 if (!PyString_Check(str)) {\r
937 PyErr_Format(PyExc_TypeError,\r
938 "read() did not return a string object (type=%.400s)",\r
939 Py_TYPE(str)->tp_name);\r
940 goto finally;\r
941 }\r
942 len = PyString_GET_SIZE(str);\r
943 if (len > buf_size) {\r
944 PyErr_Format(PyExc_ValueError,\r
945 "read() returned too much data: "\r
946 "%i bytes requested, %i returned",\r
947 buf_size, len);\r
948 goto finally;\r
949 }\r
950 memcpy(buf, PyString_AsString(str), len);\r
951finally:\r
952 Py_XDECREF(arg);\r
953 Py_XDECREF(str);\r
954 return len;\r
955}\r
956\r
957PyDoc_STRVAR(xmlparse_ParseFile__doc__,\r
958"ParseFile(file)\n\\r
959Parse XML data from file-like object.");\r
960\r
961static PyObject *\r
962xmlparse_ParseFile(xmlparseobject *self, PyObject *f)\r
963{\r
964 int rv = 1;\r
965 PyObject *readmethod = NULL;\r
966\r
967 readmethod = PyObject_GetAttrString(f, "read");\r
968 if (readmethod == NULL) {\r
969 PyErr_SetString(PyExc_TypeError,\r
970 "argument must have 'read' attribute");\r
971 return NULL;\r
972\r
973 }\r
974 for (;;) {\r
975 int bytes_read;\r
976 void *buf = XML_GetBuffer(self->itself, BUF_SIZE);\r
977 if (buf == NULL) {\r
978 Py_XDECREF(readmethod);\r
979 return get_parse_result(self, 0);\r
980 }\r
981\r
982 bytes_read = readinst(buf, BUF_SIZE, readmethod);\r
983 if (bytes_read < 0) {\r
984 Py_XDECREF(readmethod);\r
985 return NULL;\r
986 }\r
987\r
988 rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);\r
989 if (PyErr_Occurred()) {\r
990 Py_XDECREF(readmethod);\r
991 return NULL;\r
992 }\r
993\r
994 if (!rv || bytes_read == 0)\r
995 break;\r
996 }\r
997 Py_XDECREF(readmethod);\r
998 return get_parse_result(self, rv);\r
999}\r
1000\r
1001PyDoc_STRVAR(xmlparse_SetBase__doc__,\r
1002"SetBase(base_url)\n\\r
1003Set the base URL for the parser.");\r
1004\r
1005static PyObject *\r
1006xmlparse_SetBase(xmlparseobject *self, PyObject *args)\r
1007{\r
1008 char *base;\r
1009\r
1010 if (!PyArg_ParseTuple(args, "s:SetBase", &base))\r
1011 return NULL;\r
1012 if (!XML_SetBase(self->itself, base)) {\r
1013 return PyErr_NoMemory();\r
1014 }\r
1015 Py_INCREF(Py_None);\r
1016 return Py_None;\r
1017}\r
1018\r
1019PyDoc_STRVAR(xmlparse_GetBase__doc__,\r
1020"GetBase() -> url\n\\r
1021Return base URL string for the parser.");\r
1022\r
1023static PyObject *\r
1024xmlparse_GetBase(xmlparseobject *self, PyObject *unused)\r
1025{\r
1026 return Py_BuildValue("z", XML_GetBase(self->itself));\r
1027}\r
1028\r
1029PyDoc_STRVAR(xmlparse_GetInputContext__doc__,\r
1030"GetInputContext() -> string\n\\r
1031Return the untranslated text of the input that caused the current event.\n\\r
1032If the event was generated by a large amount of text (such as a start tag\n\\r
1033for an element with many attributes), not all of the text may be available.");\r
1034\r
1035static PyObject *\r
1036xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)\r
1037{\r
1038 if (self->in_callback) {\r
1039 int offset, size;\r
1040 const char *buffer\r
1041 = XML_GetInputContext(self->itself, &offset, &size);\r
1042\r
1043 if (buffer != NULL)\r
1044 return PyString_FromStringAndSize(buffer + offset,\r
1045 size - offset);\r
1046 else\r
1047 Py_RETURN_NONE;\r
1048 }\r
1049 else\r
1050 Py_RETURN_NONE;\r
1051}\r
1052\r
1053PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,\r
1054"ExternalEntityParserCreate(context[, encoding])\n\\r
1055Create a parser for parsing an external entity based on the\n\\r
1056information passed to the ExternalEntityRefHandler.");\r
1057\r
1058static PyObject *\r
1059xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)\r
1060{\r
1061 char *context;\r
1062 char *encoding = NULL;\r
1063 xmlparseobject *new_parser;\r
1064 int i;\r
1065\r
1066 if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",\r
1067 &context, &encoding)) {\r
1068 return NULL;\r
1069 }\r
1070\r
1071#ifndef Py_TPFLAGS_HAVE_GC\r
1072 /* Python versions 2.0 and 2.1 */\r
1073 new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);\r
1074#else\r
1075 /* Python versions 2.2 and later */\r
1076 new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);\r
1077#endif\r
1078\r
1079 if (new_parser == NULL)\r
1080 return NULL;\r
1081 new_parser->buffer_size = self->buffer_size;\r
1082 new_parser->buffer_used = 0;\r
1083 if (self->buffer != NULL) {\r
1084 new_parser->buffer = malloc(new_parser->buffer_size);\r
1085 if (new_parser->buffer == NULL) {\r
1086#ifndef Py_TPFLAGS_HAVE_GC\r
1087 /* Code for versions 2.0 and 2.1 */\r
1088 PyObject_Del(new_parser);\r
1089#else\r
1090 /* Code for versions 2.2 and later. */\r
1091 PyObject_GC_Del(new_parser);\r
1092#endif\r
1093 return PyErr_NoMemory();\r
1094 }\r
1095 }\r
1096 else\r
1097 new_parser->buffer = NULL;\r
1098 new_parser->returns_unicode = self->returns_unicode;\r
1099 new_parser->ordered_attributes = self->ordered_attributes;\r
1100 new_parser->specified_attributes = self->specified_attributes;\r
1101 new_parser->in_callback = 0;\r
1102 new_parser->ns_prefixes = self->ns_prefixes;\r
1103 new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,\r
1104 encoding);\r
1105 new_parser->handlers = 0;\r
1106 new_parser->intern = self->intern;\r
1107 Py_XINCREF(new_parser->intern);\r
1108#ifdef Py_TPFLAGS_HAVE_GC\r
1109 PyObject_GC_Track(new_parser);\r
1110#else\r
1111 PyObject_GC_Init(new_parser);\r
1112#endif\r
1113\r
1114 if (!new_parser->itself) {\r
1115 Py_DECREF(new_parser);\r
1116 return PyErr_NoMemory();\r
1117 }\r
1118\r
1119 XML_SetUserData(new_parser->itself, (void *)new_parser);\r
1120\r
1121 /* allocate and clear handlers first */\r
1122 for (i = 0; handler_info[i].name != NULL; i++)\r
1123 /* do nothing */;\r
1124\r
1125 new_parser->handlers = malloc(sizeof(PyObject *) * i);\r
1126 if (!new_parser->handlers) {\r
1127 Py_DECREF(new_parser);\r
1128 return PyErr_NoMemory();\r
1129 }\r
1130 clear_handlers(new_parser, 1);\r
1131\r
1132 /* then copy handlers from self */\r
1133 for (i = 0; handler_info[i].name != NULL; i++) {\r
1134 PyObject *handler = self->handlers[i];\r
1135 if (handler != NULL) {\r
1136 Py_INCREF(handler);\r
1137 new_parser->handlers[i] = handler;\r
1138 handler_info[i].setter(new_parser->itself,\r
1139 handler_info[i].handler);\r
1140 }\r
1141 }\r
1142 return (PyObject *)new_parser;\r
1143}\r
1144\r
1145PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,\r
1146"SetParamEntityParsing(flag) -> success\n\\r
1147Controls parsing of parameter entities (including the external DTD\n\\r
1148subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\\r
1149XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\\r
1150XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\\r
1151was successful.");\r
1152\r
1153static PyObject*\r
1154xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)\r
1155{\r
1156 int flag;\r
1157 if (!PyArg_ParseTuple(args, "i", &flag))\r
1158 return NULL;\r
1159 flag = XML_SetParamEntityParsing(p->itself, flag);\r
1160 return PyInt_FromLong(flag);\r
1161}\r
1162\r
1163\r
1164#if XML_COMBINED_VERSION >= 19505\r
1165PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,\r
1166"UseForeignDTD([flag])\n\\r
1167Allows the application to provide an artificial external subset if one is\n\\r
1168not specified as part of the document instance. This readily allows the\n\\r
1169use of a 'default' document type controlled by the application, while still\n\\r
1170getting the advantage of providing document type information to the parser.\n\\r
1171'flag' defaults to True if not provided.");\r
1172\r
1173static PyObject *\r
1174xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)\r
1175{\r
1176 PyObject *flagobj = NULL;\r
1177 int flag = 1;\r
1178 enum XML_Error rc;\r
1179 if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))\r
1180 return NULL;\r
1181 if (flagobj != NULL) {\r
1182 flag = PyObject_IsTrue(flagobj);\r
1183 if (flag < 0)\r
1184 return NULL;\r
1185 }\r
1186 rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);\r
1187 if (rc != XML_ERROR_NONE) {\r
1188 return set_error(self, rc);\r
1189 }\r
1190 Py_INCREF(Py_None);\r
1191 return Py_None;\r
1192}\r
1193#endif\r
1194\r
1195static struct PyMethodDef xmlparse_methods[] = {\r
1196 {"Parse", (PyCFunction)xmlparse_Parse,\r
1197 METH_VARARGS, xmlparse_Parse__doc__},\r
1198 {"ParseFile", (PyCFunction)xmlparse_ParseFile,\r
1199 METH_O, xmlparse_ParseFile__doc__},\r
1200 {"SetBase", (PyCFunction)xmlparse_SetBase,\r
1201 METH_VARARGS, xmlparse_SetBase__doc__},\r
1202 {"GetBase", (PyCFunction)xmlparse_GetBase,\r
1203 METH_NOARGS, xmlparse_GetBase__doc__},\r
1204 {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,\r
1205 METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},\r
1206 {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,\r
1207 METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},\r
1208 {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,\r
1209 METH_NOARGS, xmlparse_GetInputContext__doc__},\r
1210#if XML_COMBINED_VERSION >= 19505\r
1211 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,\r
1212 METH_VARARGS, xmlparse_UseForeignDTD__doc__},\r
1213#endif\r
1214 {NULL, NULL} /* sentinel */\r
1215};\r
1216\r
1217/* ---------- */\r
1218\r
1219\r
1220#ifdef Py_USING_UNICODE\r
1221\r
1222/* pyexpat international encoding support.\r
1223 Make it as simple as possible.\r
1224*/\r
1225\r
1226static char template_buffer[257];\r
1227PyObject *template_string = NULL;\r
1228\r
1229static void\r
1230init_template_buffer(void)\r
1231{\r
1232 int i;\r
1233 for (i = 0; i < 256; i++) {\r
1234 template_buffer[i] = i;\r
1235 }\r
1236 template_buffer[256] = 0;\r
1237}\r
1238\r
1239static int\r
1240PyUnknownEncodingHandler(void *encodingHandlerData,\r
1241 const XML_Char *name,\r
1242 XML_Encoding *info)\r
1243{\r
1244 PyUnicodeObject *_u_string = NULL;\r
1245 int result = 0;\r
1246 int i;\r
1247\r
1248 /* Yes, supports only 8bit encodings */\r
1249 _u_string = (PyUnicodeObject *)\r
1250 PyUnicode_Decode(template_buffer, 256, name, "replace");\r
1251\r
1252 if (_u_string == NULL)\r
1253 return result;\r
1254\r
1255 if (PyUnicode_GET_SIZE(_u_string) != 256) {\r
1256 Py_DECREF(_u_string);\r
1257 PyErr_SetString(PyExc_ValueError,\r
1258 "multi-byte encodings are not supported");\r
1259 return result;\r
1260 }\r
1261\r
1262 for (i = 0; i < 256; i++) {\r
1263 /* Stupid to access directly, but fast */\r
1264 Py_UNICODE c = _u_string->str[i];\r
1265 if (c == Py_UNICODE_REPLACEMENT_CHARACTER)\r
1266 info->map[i] = -1;\r
1267 else\r
1268 info->map[i] = c;\r
1269 }\r
1270 info->data = NULL;\r
1271 info->convert = NULL;\r
1272 info->release = NULL;\r
1273 result = 1;\r
1274 Py_DECREF(_u_string);\r
1275 return result;\r
1276}\r
1277\r
1278#endif\r
1279\r
1280static PyObject *\r
1281newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)\r
1282{\r
1283 int i;\r
1284 xmlparseobject *self;\r
1285\r
1286#ifdef Py_TPFLAGS_HAVE_GC\r
1287 /* Code for versions 2.2 and later */\r
1288 self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);\r
1289#else\r
1290 self = PyObject_New(xmlparseobject, &Xmlparsetype);\r
1291#endif\r
1292 if (self == NULL)\r
1293 return NULL;\r
1294\r
1295#ifdef Py_USING_UNICODE\r
1296 self->returns_unicode = 1;\r
1297#else\r
1298 self->returns_unicode = 0;\r
1299#endif\r
1300\r
1301 self->buffer = NULL;\r
1302 self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;\r
1303 self->buffer_used = 0;\r
1304 self->ordered_attributes = 0;\r
1305 self->specified_attributes = 0;\r
1306 self->in_callback = 0;\r
1307 self->ns_prefixes = 0;\r
1308 self->handlers = NULL;\r
1309 if (namespace_separator != NULL) {\r
1310 self->itself = XML_ParserCreateNS(encoding, *namespace_separator);\r
1311 }\r
1312 else {\r
1313 self->itself = XML_ParserCreate(encoding);\r
1314 }\r
1315#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)\r
1316 /* This feature was added upstream in libexpat 2.1.0. Our expat copy\r
1317 * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT\r
1318 * to indicate that we can still use it. */\r
1319 XML_SetHashSalt(self->itself,\r
1320 (unsigned long)_Py_HashSecret.prefix);\r
1321#endif\r
1322 self->intern = intern;\r
1323 Py_XINCREF(self->intern);\r
1324#ifdef Py_TPFLAGS_HAVE_GC\r
1325 PyObject_GC_Track(self);\r
1326#else\r
1327 PyObject_GC_Init(self);\r
1328#endif\r
1329 if (self->itself == NULL) {\r
1330 PyErr_SetString(PyExc_RuntimeError,\r
1331 "XML_ParserCreate failed");\r
1332 Py_DECREF(self);\r
1333 return NULL;\r
1334 }\r
1335 XML_SetUserData(self->itself, (void *)self);\r
1336#ifdef Py_USING_UNICODE\r
1337 XML_SetUnknownEncodingHandler(self->itself,\r
1338 (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);\r
1339#endif\r
1340\r
1341 for (i = 0; handler_info[i].name != NULL; i++)\r
1342 /* do nothing */;\r
1343\r
1344 self->handlers = malloc(sizeof(PyObject *) * i);\r
1345 if (!self->handlers) {\r
1346 Py_DECREF(self);\r
1347 return PyErr_NoMemory();\r
1348 }\r
1349 clear_handlers(self, 1);\r
1350\r
1351 return (PyObject*)self;\r
1352}\r
1353\r
1354\r
1355static void\r
1356xmlparse_dealloc(xmlparseobject *self)\r
1357{\r
1358 int i;\r
1359#ifdef Py_TPFLAGS_HAVE_GC\r
1360 PyObject_GC_UnTrack(self);\r
1361#else\r
1362 PyObject_GC_Fini(self);\r
1363#endif\r
1364 if (self->itself != NULL)\r
1365 XML_ParserFree(self->itself);\r
1366 self->itself = NULL;\r
1367\r
1368 if (self->handlers != NULL) {\r
1369 PyObject *temp;\r
1370 for (i = 0; handler_info[i].name != NULL; i++) {\r
1371 temp = self->handlers[i];\r
1372 self->handlers[i] = NULL;\r
1373 Py_XDECREF(temp);\r
1374 }\r
1375 free(self->handlers);\r
1376 self->handlers = NULL;\r
1377 }\r
1378 if (self->buffer != NULL) {\r
1379 free(self->buffer);\r
1380 self->buffer = NULL;\r
1381 }\r
1382 Py_XDECREF(self->intern);\r
1383#ifndef Py_TPFLAGS_HAVE_GC\r
1384 /* Code for versions 2.0 and 2.1 */\r
1385 PyObject_Del(self);\r
1386#else\r
1387 /* Code for versions 2.2 and later. */\r
1388 PyObject_GC_Del(self);\r
1389#endif\r
1390}\r
1391\r
1392static int\r
1393handlername2int(const char *name)\r
1394{\r
1395 int i;\r
1396 for (i = 0; handler_info[i].name != NULL; i++) {\r
1397 if (strcmp(name, handler_info[i].name) == 0) {\r
1398 return i;\r
1399 }\r
1400 }\r
1401 return -1;\r
1402}\r
1403\r
1404static PyObject *\r
1405get_pybool(int istrue)\r
1406{\r
1407 PyObject *result = istrue ? Py_True : Py_False;\r
1408 Py_INCREF(result);\r
1409 return result;\r
1410}\r
1411\r
1412static PyObject *\r
1413xmlparse_getattr(xmlparseobject *self, char *name)\r
1414{\r
1415 int handlernum = handlername2int(name);\r
1416\r
1417 if (handlernum != -1) {\r
1418 PyObject *result = self->handlers[handlernum];\r
1419 if (result == NULL)\r
1420 result = Py_None;\r
1421 Py_INCREF(result);\r
1422 return result;\r
1423 }\r
1424 if (name[0] == 'E') {\r
1425 if (strcmp(name, "ErrorCode") == 0)\r
1426 return PyInt_FromLong((long)\r
1427 XML_GetErrorCode(self->itself));\r
1428 if (strcmp(name, "ErrorLineNumber") == 0)\r
1429 return PyInt_FromLong((long)\r
1430 XML_GetErrorLineNumber(self->itself));\r
1431 if (strcmp(name, "ErrorColumnNumber") == 0)\r
1432 return PyInt_FromLong((long)\r
1433 XML_GetErrorColumnNumber(self->itself));\r
1434 if (strcmp(name, "ErrorByteIndex") == 0)\r
1435 return PyInt_FromLong((long)\r
1436 XML_GetErrorByteIndex(self->itself));\r
1437 }\r
1438 if (name[0] == 'C') {\r
1439 if (strcmp(name, "CurrentLineNumber") == 0)\r
1440 return PyInt_FromLong((long)\r
1441 XML_GetCurrentLineNumber(self->itself));\r
1442 if (strcmp(name, "CurrentColumnNumber") == 0)\r
1443 return PyInt_FromLong((long)\r
1444 XML_GetCurrentColumnNumber(self->itself));\r
1445 if (strcmp(name, "CurrentByteIndex") == 0)\r
1446 return PyInt_FromLong((long)\r
1447 XML_GetCurrentByteIndex(self->itself));\r
1448 }\r
1449 if (name[0] == 'b') {\r
1450 if (strcmp(name, "buffer_size") == 0)\r
1451 return PyInt_FromLong((long) self->buffer_size);\r
1452 if (strcmp(name, "buffer_text") == 0)\r
1453 return get_pybool(self->buffer != NULL);\r
1454 if (strcmp(name, "buffer_used") == 0)\r
1455 return PyInt_FromLong((long) self->buffer_used);\r
1456 }\r
1457 if (strcmp(name, "namespace_prefixes") == 0)\r
1458 return get_pybool(self->ns_prefixes);\r
1459 if (strcmp(name, "ordered_attributes") == 0)\r
1460 return get_pybool(self->ordered_attributes);\r
1461 if (strcmp(name, "returns_unicode") == 0)\r
1462 return get_pybool((long) self->returns_unicode);\r
1463 if (strcmp(name, "specified_attributes") == 0)\r
1464 return get_pybool((long) self->specified_attributes);\r
1465 if (strcmp(name, "intern") == 0) {\r
1466 if (self->intern == NULL) {\r
1467 Py_INCREF(Py_None);\r
1468 return Py_None;\r
1469 }\r
1470 else {\r
1471 Py_INCREF(self->intern);\r
1472 return self->intern;\r
1473 }\r
1474 }\r
1475\r
1476#define APPEND(list, str) \\r
1477 do { \\r
1478 PyObject *o = PyString_FromString(str); \\r
1479 if (o != NULL) \\r
1480 PyList_Append(list, o); \\r
1481 Py_XDECREF(o); \\r
1482 } while (0)\r
1483\r
1484 if (strcmp(name, "__members__") == 0) {\r
1485 int i;\r
1486 PyObject *rc = PyList_New(0);\r
1487 if (!rc)\r
1488 return NULL;\r
1489 for (i = 0; handler_info[i].name != NULL; i++) {\r
1490 PyObject *o = get_handler_name(&handler_info[i]);\r
1491 if (o != NULL)\r
1492 PyList_Append(rc, o);\r
1493 Py_XDECREF(o);\r
1494 }\r
1495 APPEND(rc, "ErrorCode");\r
1496 APPEND(rc, "ErrorLineNumber");\r
1497 APPEND(rc, "ErrorColumnNumber");\r
1498 APPEND(rc, "ErrorByteIndex");\r
1499 APPEND(rc, "CurrentLineNumber");\r
1500 APPEND(rc, "CurrentColumnNumber");\r
1501 APPEND(rc, "CurrentByteIndex");\r
1502 APPEND(rc, "buffer_size");\r
1503 APPEND(rc, "buffer_text");\r
1504 APPEND(rc, "buffer_used");\r
1505 APPEND(rc, "namespace_prefixes");\r
1506 APPEND(rc, "ordered_attributes");\r
1507 APPEND(rc, "returns_unicode");\r
1508 APPEND(rc, "specified_attributes");\r
1509 APPEND(rc, "intern");\r
1510\r
1511#undef APPEND\r
1512 return rc;\r
1513 }\r
1514 return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);\r
1515}\r
1516\r
1517static int\r
1518sethandler(xmlparseobject *self, const char *name, PyObject* v)\r
1519{\r
1520 int handlernum = handlername2int(name);\r
1521 if (handlernum >= 0) {\r
1522 xmlhandler c_handler = NULL;\r
1523 PyObject *temp = self->handlers[handlernum];\r
1524\r
1525 if (v == Py_None) {\r
1526 /* If this is the character data handler, and a character\r
1527 data handler is already active, we need to be more\r
1528 careful. What we can safely do is replace the existing\r
1529 character data handler callback function with a no-op\r
1530 function that will refuse to call Python. The downside\r
1531 is that this doesn't completely remove the character\r
1532 data handler from the C layer if there's any callback\r
1533 active, so Expat does a little more work than it\r
1534 otherwise would, but that's really an odd case. A more\r
1535 elaborate system of handlers and state could remove the\r
1536 C handler more effectively. */\r
1537 if (handlernum == CharacterData && self->in_callback)\r
1538 c_handler = noop_character_data_handler;\r
1539 v = NULL;\r
1540 }\r
1541 else if (v != NULL) {\r
1542 Py_INCREF(v);\r
1543 c_handler = handler_info[handlernum].handler;\r
1544 }\r
1545 self->handlers[handlernum] = v;\r
1546 Py_XDECREF(temp);\r
1547 handler_info[handlernum].setter(self->itself, c_handler);\r
1548 return 1;\r
1549 }\r
1550 return 0;\r
1551}\r
1552\r
1553static int\r
1554xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)\r
1555{\r
1556 /* Set attribute 'name' to value 'v'. v==NULL means delete */\r
1557 if (v == NULL) {\r
1558 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");\r
1559 return -1;\r
1560 }\r
1561 if (strcmp(name, "buffer_text") == 0) {\r
1562 int b = PyObject_IsTrue(v);\r
1563 if (b < 0)\r
1564 return -1;\r
1565 if (b) {\r
1566 if (self->buffer == NULL) {\r
1567 self->buffer = malloc(self->buffer_size);\r
1568 if (self->buffer == NULL) {\r
1569 PyErr_NoMemory();\r
1570 return -1;\r
1571 }\r
1572 self->buffer_used = 0;\r
1573 }\r
1574 }\r
1575 else if (self->buffer != NULL) {\r
1576 if (flush_character_buffer(self) < 0)\r
1577 return -1;\r
1578 free(self->buffer);\r
1579 self->buffer = NULL;\r
1580 }\r
1581 return 0;\r
1582 }\r
1583 if (strcmp(name, "namespace_prefixes") == 0) {\r
1584 int b = PyObject_IsTrue(v);\r
1585 if (b < 0)\r
1586 return -1;\r
1587 self->ns_prefixes = b;\r
1588 XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);\r
1589 return 0;\r
1590 }\r
1591 if (strcmp(name, "ordered_attributes") == 0) {\r
1592 int b = PyObject_IsTrue(v);\r
1593 if (b < 0)\r
1594 return -1;\r
1595 self->ordered_attributes = b;\r
1596 return 0;\r
1597 }\r
1598 if (strcmp(name, "returns_unicode") == 0) {\r
1599 int b = PyObject_IsTrue(v);\r
1600 if (b < 0)\r
1601 return -1;\r
1602#ifndef Py_USING_UNICODE\r
1603 if (b) {\r
1604 PyErr_SetString(PyExc_ValueError,\r
1605 "Unicode support not available");\r
1606 return -1;\r
1607 }\r
1608#endif\r
1609 self->returns_unicode = b;\r
1610 return 0;\r
1611 }\r
1612 if (strcmp(name, "specified_attributes") == 0) {\r
1613 int b = PyObject_IsTrue(v);\r
1614 if (b < 0)\r
1615 return -1;\r
1616 self->specified_attributes = b;\r
1617 return 0;\r
1618 }\r
1619\r
1620 if (strcmp(name, "buffer_size") == 0) {\r
1621 long new_buffer_size;\r
1622 if (!PyInt_Check(v)) {\r
1623 PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");\r
1624 return -1;\r
1625 }\r
1626\r
1627 new_buffer_size=PyInt_AS_LONG(v);\r
1628 /* trivial case -- no change */\r
1629 if (new_buffer_size == self->buffer_size) {\r
1630 return 0;\r
1631 }\r
1632\r
1633 if (new_buffer_size <= 0) {\r
1634 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");\r
1635 return -1;\r
1636 }\r
1637\r
1638 /* check maximum */\r
1639 if (new_buffer_size > INT_MAX) {\r
1640 char errmsg[100];\r
1641 sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);\r
1642 PyErr_SetString(PyExc_ValueError, errmsg);\r
1643 return -1;\r
1644 }\r
1645\r
1646 if (self->buffer != NULL) {\r
1647 /* there is already a buffer */\r
1648 if (self->buffer_used != 0) {\r
1649 flush_character_buffer(self);\r
1650 }\r
1651 /* free existing buffer */\r
1652 free(self->buffer);\r
1653 }\r
1654 self->buffer = malloc(new_buffer_size);\r
1655 if (self->buffer == NULL) {\r
1656 PyErr_NoMemory();\r
1657 return -1;\r
1658 }\r
1659 self->buffer_size = new_buffer_size;\r
1660 return 0;\r
1661 }\r
1662\r
1663 if (strcmp(name, "CharacterDataHandler") == 0) {\r
1664 /* If we're changing the character data handler, flush all\r
1665 * cached data with the old handler. Not sure there's a\r
1666 * "right" thing to do, though, but this probably won't\r
1667 * happen.\r
1668 */\r
1669 if (flush_character_buffer(self) < 0)\r
1670 return -1;\r
1671 }\r
1672 if (sethandler(self, name, v)) {\r
1673 return 0;\r
1674 }\r
1675 PyErr_SetString(PyExc_AttributeError, name);\r
1676 return -1;\r
1677}\r
1678\r
1679#ifdef WITH_CYCLE_GC\r
1680static int\r
1681xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)\r
1682{\r
1683 int i;\r
1684 for (i = 0; handler_info[i].name != NULL; i++)\r
1685 Py_VISIT(op->handlers[i]);\r
1686 return 0;\r
1687}\r
1688\r
1689static int\r
1690xmlparse_clear(xmlparseobject *op)\r
1691{\r
1692 clear_handlers(op, 0);\r
1693 Py_CLEAR(op->intern);\r
1694 return 0;\r
1695}\r
1696#endif\r
1697\r
1698PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");\r
1699\r
1700static PyTypeObject Xmlparsetype = {\r
1701 PyVarObject_HEAD_INIT(NULL, 0)\r
1702 "pyexpat.xmlparser", /*tp_name*/\r
1703 sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/\r
1704 0, /*tp_itemsize*/\r
1705 /* methods */\r
1706 (destructor)xmlparse_dealloc, /*tp_dealloc*/\r
1707 (printfunc)0, /*tp_print*/\r
1708 (getattrfunc)xmlparse_getattr, /*tp_getattr*/\r
1709 (setattrfunc)xmlparse_setattr, /*tp_setattr*/\r
1710 (cmpfunc)0, /*tp_compare*/\r
1711 (reprfunc)0, /*tp_repr*/\r
1712 0, /*tp_as_number*/\r
1713 0, /*tp_as_sequence*/\r
1714 0, /*tp_as_mapping*/\r
1715 (hashfunc)0, /*tp_hash*/\r
1716 (ternaryfunc)0, /*tp_call*/\r
1717 (reprfunc)0, /*tp_str*/\r
1718 0, /* tp_getattro */\r
1719 0, /* tp_setattro */\r
1720 0, /* tp_as_buffer */\r
1721#ifdef Py_TPFLAGS_HAVE_GC\r
1722 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/\r
1723#else\r
1724 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/\r
1725#endif\r
1726 Xmlparsetype__doc__, /* tp_doc - Documentation string */\r
1727#ifdef WITH_CYCLE_GC\r
1728 (traverseproc)xmlparse_traverse, /* tp_traverse */\r
1729 (inquiry)xmlparse_clear /* tp_clear */\r
1730#else\r
1731 0, 0\r
1732#endif\r
1733};\r
1734\r
1735/* End of code for xmlparser objects */\r
1736/* -------------------------------------------------------- */\r
1737\r
1738PyDoc_STRVAR(pyexpat_ParserCreate__doc__,\r
1739"ParserCreate([encoding[, namespace_separator]]) -> parser\n\\r
1740Return a new XML parser object.");\r
1741\r
1742static PyObject *\r
1743pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)\r
1744{\r
1745 char *encoding = NULL;\r
1746 char *namespace_separator = NULL;\r
1747 PyObject *intern = NULL;\r
1748 PyObject *result;\r
1749 int intern_decref = 0;\r
1750 static char *kwlist[] = {"encoding", "namespace_separator",\r
1751 "intern", NULL};\r
1752\r
1753 if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,\r
1754 &encoding, &namespace_separator, &intern))\r
1755 return NULL;\r
1756 if (namespace_separator != NULL\r
1757 && strlen(namespace_separator) > 1) {\r
1758 PyErr_SetString(PyExc_ValueError,\r
1759 "namespace_separator must be at most one"\r
1760 " character, omitted, or None");\r
1761 return NULL;\r
1762 }\r
1763 /* Explicitly passing None means no interning is desired.\r
1764 Not passing anything means that a new dictionary is used. */\r
1765 if (intern == Py_None)\r
1766 intern = NULL;\r
1767 else if (intern == NULL) {\r
1768 intern = PyDict_New();\r
1769 if (!intern)\r
1770 return NULL;\r
1771 intern_decref = 1;\r
1772 }\r
1773 else if (!PyDict_Check(intern)) {\r
1774 PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");\r
1775 return NULL;\r
1776 }\r
1777\r
1778 result = newxmlparseobject(encoding, namespace_separator, intern);\r
1779 if (intern_decref) {\r
1780 Py_DECREF(intern);\r
1781 }\r
1782 return result;\r
1783}\r
1784\r
1785PyDoc_STRVAR(pyexpat_ErrorString__doc__,\r
1786"ErrorString(errno) -> string\n\\r
1787Returns string error for given number.");\r
1788\r
1789static PyObject *\r
1790pyexpat_ErrorString(PyObject *self, PyObject *args)\r
1791{\r
1792 long code = 0;\r
1793\r
1794 if (!PyArg_ParseTuple(args, "l:ErrorString", &code))\r
1795 return NULL;\r
1796 return Py_BuildValue("z", XML_ErrorString((int)code));\r
1797}\r
1798\r
1799/* List of methods defined in the module */\r
1800\r
1801static struct PyMethodDef pyexpat_methods[] = {\r
1802 {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,\r
1803 METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},\r
1804 {"ErrorString", (PyCFunction)pyexpat_ErrorString,\r
1805 METH_VARARGS, pyexpat_ErrorString__doc__},\r
1806\r
1807 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */\r
1808};\r
1809\r
1810/* Module docstring */\r
1811\r
1812PyDoc_STRVAR(pyexpat_module_documentation,\r
1813"Python wrapper for Expat parser.");\r
1814\r
1815/* Initialization function for the module */\r
1816\r
1817#ifndef MODULE_NAME\r
1818#define MODULE_NAME "pyexpat"\r
1819#endif\r
1820\r
1821#ifndef MODULE_INITFUNC\r
1822#define MODULE_INITFUNC initpyexpat\r
1823#endif\r
1824\r
1825#ifndef PyMODINIT_FUNC\r
1826# ifdef MS_WINDOWS\r
1827# define PyMODINIT_FUNC __declspec(dllexport) void\r
1828# else\r
1829# define PyMODINIT_FUNC void\r
1830# endif\r
1831#endif\r
1832\r
1833PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */\r
1834\r
1835PyMODINIT_FUNC\r
1836MODULE_INITFUNC(void)\r
1837{\r
1838 PyObject *m, *d;\r
1839 PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");\r
1840 PyObject *errors_module;\r
1841 PyObject *modelmod_name;\r
1842 PyObject *model_module;\r
1843 PyObject *sys_modules;\r
1844 PyObject *version;\r
1845 static struct PyExpat_CAPI capi;\r
1846 PyObject* capi_object;\r
1847\r
1848 if (errmod_name == NULL)\r
1849 return;\r
1850 modelmod_name = PyString_FromString(MODULE_NAME ".model");\r
1851 if (modelmod_name == NULL)\r
1852 return;\r
1853\r
1854 Py_TYPE(&Xmlparsetype) = &PyType_Type;\r
1855\r
1856 /* Create the module and add the functions */\r
1857 m = Py_InitModule3(MODULE_NAME, pyexpat_methods,\r
1858 pyexpat_module_documentation);\r
1859 if (m == NULL)\r
1860 return;\r
1861\r
1862 /* Add some symbolic constants to the module */\r
1863 if (ErrorObject == NULL) {\r
1864 ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",\r
1865 NULL, NULL);\r
1866 if (ErrorObject == NULL)\r
1867 return;\r
1868 }\r
1869 Py_INCREF(ErrorObject);\r
1870 PyModule_AddObject(m, "error", ErrorObject);\r
1871 Py_INCREF(ErrorObject);\r
1872 PyModule_AddObject(m, "ExpatError", ErrorObject);\r
1873 Py_INCREF(&Xmlparsetype);\r
1874 PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);\r
1875\r
1876 version = PyString_FromString(PY_VERSION);\r
1877 if (!version)\r
1878 return;\r
1879 PyModule_AddObject(m, "__version__", version);\r
1880 PyModule_AddStringConstant(m, "EXPAT_VERSION",\r
1881 (char *) XML_ExpatVersion());\r
1882 {\r
1883 XML_Expat_Version info = XML_ExpatVersionInfo();\r
1884 PyModule_AddObject(m, "version_info",\r
1885 Py_BuildValue("(iii)", info.major,\r
1886 info.minor, info.micro));\r
1887 }\r
1888#ifdef Py_USING_UNICODE\r
1889 init_template_buffer();\r
1890#endif\r
1891 /* XXX When Expat supports some way of figuring out how it was\r
1892 compiled, this should check and set native_encoding\r
1893 appropriately.\r
1894 */\r
1895 PyModule_AddStringConstant(m, "native_encoding", "UTF-8");\r
1896\r
1897 sys_modules = PySys_GetObject("modules");\r
1898 d = PyModule_GetDict(m);\r
1899 errors_module = PyDict_GetItem(d, errmod_name);\r
1900 if (errors_module == NULL) {\r
1901 errors_module = PyModule_New(MODULE_NAME ".errors");\r
1902 if (errors_module != NULL) {\r
1903 PyDict_SetItem(sys_modules, errmod_name, errors_module);\r
1904 /* gives away the reference to errors_module */\r
1905 PyModule_AddObject(m, "errors", errors_module);\r
1906 }\r
1907 }\r
1908 Py_DECREF(errmod_name);\r
1909 model_module = PyDict_GetItem(d, modelmod_name);\r
1910 if (model_module == NULL) {\r
1911 model_module = PyModule_New(MODULE_NAME ".model");\r
1912 if (model_module != NULL) {\r
1913 PyDict_SetItem(sys_modules, modelmod_name, model_module);\r
1914 /* gives away the reference to model_module */\r
1915 PyModule_AddObject(m, "model", model_module);\r
1916 }\r
1917 }\r
1918 Py_DECREF(modelmod_name);\r
1919 if (errors_module == NULL || model_module == NULL)\r
1920 /* Don't core dump later! */\r
1921 return;\r
1922\r
1923#if XML_COMBINED_VERSION > 19505\r
1924 {\r
1925 const XML_Feature *features = XML_GetFeatureList();\r
1926 PyObject *list = PyList_New(0);\r
1927 if (list == NULL)\r
1928 /* just ignore it */\r
1929 PyErr_Clear();\r
1930 else {\r
1931 int i = 0;\r
1932 for (; features[i].feature != XML_FEATURE_END; ++i) {\r
1933 int ok;\r
1934 PyObject *item = Py_BuildValue("si", features[i].name,\r
1935 features[i].value);\r
1936 if (item == NULL) {\r
1937 Py_DECREF(list);\r
1938 list = NULL;\r
1939 break;\r
1940 }\r
1941 ok = PyList_Append(list, item);\r
1942 Py_DECREF(item);\r
1943 if (ok < 0) {\r
1944 PyErr_Clear();\r
1945 break;\r
1946 }\r
1947 }\r
1948 if (list != NULL)\r
1949 PyModule_AddObject(m, "features", list);\r
1950 }\r
1951 }\r
1952#endif\r
1953\r
1954#define MYCONST(name) \\r
1955 PyModule_AddStringConstant(errors_module, #name, \\r
1956 (char*)XML_ErrorString(name))\r
1957\r
1958 MYCONST(XML_ERROR_NO_MEMORY);\r
1959 MYCONST(XML_ERROR_SYNTAX);\r
1960 MYCONST(XML_ERROR_NO_ELEMENTS);\r
1961 MYCONST(XML_ERROR_INVALID_TOKEN);\r
1962 MYCONST(XML_ERROR_UNCLOSED_TOKEN);\r
1963 MYCONST(XML_ERROR_PARTIAL_CHAR);\r
1964 MYCONST(XML_ERROR_TAG_MISMATCH);\r
1965 MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);\r
1966 MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);\r
1967 MYCONST(XML_ERROR_PARAM_ENTITY_REF);\r
1968 MYCONST(XML_ERROR_UNDEFINED_ENTITY);\r
1969 MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);\r
1970 MYCONST(XML_ERROR_ASYNC_ENTITY);\r
1971 MYCONST(XML_ERROR_BAD_CHAR_REF);\r
1972 MYCONST(XML_ERROR_BINARY_ENTITY_REF);\r
1973 MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);\r
1974 MYCONST(XML_ERROR_MISPLACED_XML_PI);\r
1975 MYCONST(XML_ERROR_UNKNOWN_ENCODING);\r
1976 MYCONST(XML_ERROR_INCORRECT_ENCODING);\r
1977 MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);\r
1978 MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);\r
1979 MYCONST(XML_ERROR_NOT_STANDALONE);\r
1980 MYCONST(XML_ERROR_UNEXPECTED_STATE);\r
1981 MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);\r
1982 MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);\r
1983 MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);\r
1984 /* Added in Expat 1.95.7. */\r
1985 MYCONST(XML_ERROR_UNBOUND_PREFIX);\r
1986 /* Added in Expat 1.95.8. */\r
1987 MYCONST(XML_ERROR_UNDECLARING_PREFIX);\r
1988 MYCONST(XML_ERROR_INCOMPLETE_PE);\r
1989 MYCONST(XML_ERROR_XML_DECL);\r
1990 MYCONST(XML_ERROR_TEXT_DECL);\r
1991 MYCONST(XML_ERROR_PUBLICID);\r
1992 MYCONST(XML_ERROR_SUSPENDED);\r
1993 MYCONST(XML_ERROR_NOT_SUSPENDED);\r
1994 MYCONST(XML_ERROR_ABORTED);\r
1995 MYCONST(XML_ERROR_FINISHED);\r
1996 MYCONST(XML_ERROR_SUSPEND_PE);\r
1997\r
1998 PyModule_AddStringConstant(errors_module, "__doc__",\r
1999 "Constants used to describe error conditions.");\r
2000\r
2001#undef MYCONST\r
2002\r
2003#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)\r
2004 MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);\r
2005 MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);\r
2006 MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);\r
2007#undef MYCONST\r
2008\r
2009#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)\r
2010 PyModule_AddStringConstant(model_module, "__doc__",\r
2011 "Constants used to interpret content model information.");\r
2012\r
2013 MYCONST(XML_CTYPE_EMPTY);\r
2014 MYCONST(XML_CTYPE_ANY);\r
2015 MYCONST(XML_CTYPE_MIXED);\r
2016 MYCONST(XML_CTYPE_NAME);\r
2017 MYCONST(XML_CTYPE_CHOICE);\r
2018 MYCONST(XML_CTYPE_SEQ);\r
2019\r
2020 MYCONST(XML_CQUANT_NONE);\r
2021 MYCONST(XML_CQUANT_OPT);\r
2022 MYCONST(XML_CQUANT_REP);\r
2023 MYCONST(XML_CQUANT_PLUS);\r
2024#undef MYCONST\r
2025\r
2026 /* initialize pyexpat dispatch table */\r
2027 capi.size = sizeof(capi);\r
2028 capi.magic = PyExpat_CAPI_MAGIC;\r
2029 capi.MAJOR_VERSION = XML_MAJOR_VERSION;\r
2030 capi.MINOR_VERSION = XML_MINOR_VERSION;\r
2031 capi.MICRO_VERSION = XML_MICRO_VERSION;\r
2032 capi.ErrorString = XML_ErrorString;\r
2033 capi.GetErrorCode = XML_GetErrorCode;\r
2034 capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;\r
2035 capi.GetErrorLineNumber = XML_GetErrorLineNumber;\r
2036 capi.Parse = XML_Parse;\r
2037 capi.ParserCreate_MM = XML_ParserCreate_MM;\r
2038 capi.ParserFree = XML_ParserFree;\r
2039 capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;\r
2040 capi.SetCommentHandler = XML_SetCommentHandler;\r
2041 capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;\r
2042 capi.SetElementHandler = XML_SetElementHandler;\r
2043 capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;\r
2044 capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;\r
2045 capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;\r
2046 capi.SetUserData = XML_SetUserData;\r
2047\r
2048 /* export using capsule */\r
2049 capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);\r
2050 if (capi_object)\r
2051 PyModule_AddObject(m, "expat_CAPI", capi_object);\r
2052}\r
2053\r
2054static void\r
2055clear_handlers(xmlparseobject *self, int initial)\r
2056{\r
2057 int i = 0;\r
2058 PyObject *temp;\r
2059\r
2060 for (; handler_info[i].name != NULL; i++) {\r
2061 if (initial)\r
2062 self->handlers[i] = NULL;\r
2063 else {\r
2064 temp = self->handlers[i];\r
2065 self->handlers[i] = NULL;\r
2066 Py_XDECREF(temp);\r
2067 handler_info[i].setter(self->itself, NULL);\r
2068 }\r
2069 }\r
2070}\r
2071\r
2072static struct HandlerInfo handler_info[] = {\r
2073 {"StartElementHandler",\r
2074 (xmlhandlersetter)XML_SetStartElementHandler,\r
2075 (xmlhandler)my_StartElementHandler},\r
2076 {"EndElementHandler",\r
2077 (xmlhandlersetter)XML_SetEndElementHandler,\r
2078 (xmlhandler)my_EndElementHandler},\r
2079 {"ProcessingInstructionHandler",\r
2080 (xmlhandlersetter)XML_SetProcessingInstructionHandler,\r
2081 (xmlhandler)my_ProcessingInstructionHandler},\r
2082 {"CharacterDataHandler",\r
2083 (xmlhandlersetter)XML_SetCharacterDataHandler,\r
2084 (xmlhandler)my_CharacterDataHandler},\r
2085 {"UnparsedEntityDeclHandler",\r
2086 (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,\r
2087 (xmlhandler)my_UnparsedEntityDeclHandler},\r
2088 {"NotationDeclHandler",\r
2089 (xmlhandlersetter)XML_SetNotationDeclHandler,\r
2090 (xmlhandler)my_NotationDeclHandler},\r
2091 {"StartNamespaceDeclHandler",\r
2092 (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,\r
2093 (xmlhandler)my_StartNamespaceDeclHandler},\r
2094 {"EndNamespaceDeclHandler",\r
2095 (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,\r
2096 (xmlhandler)my_EndNamespaceDeclHandler},\r
2097 {"CommentHandler",\r
2098 (xmlhandlersetter)XML_SetCommentHandler,\r
2099 (xmlhandler)my_CommentHandler},\r
2100 {"StartCdataSectionHandler",\r
2101 (xmlhandlersetter)XML_SetStartCdataSectionHandler,\r
2102 (xmlhandler)my_StartCdataSectionHandler},\r
2103 {"EndCdataSectionHandler",\r
2104 (xmlhandlersetter)XML_SetEndCdataSectionHandler,\r
2105 (xmlhandler)my_EndCdataSectionHandler},\r
2106 {"DefaultHandler",\r
2107 (xmlhandlersetter)XML_SetDefaultHandler,\r
2108 (xmlhandler)my_DefaultHandler},\r
2109 {"DefaultHandlerExpand",\r
2110 (xmlhandlersetter)XML_SetDefaultHandlerExpand,\r
2111 (xmlhandler)my_DefaultHandlerExpandHandler},\r
2112 {"NotStandaloneHandler",\r
2113 (xmlhandlersetter)XML_SetNotStandaloneHandler,\r
2114 (xmlhandler)my_NotStandaloneHandler},\r
2115 {"ExternalEntityRefHandler",\r
2116 (xmlhandlersetter)XML_SetExternalEntityRefHandler,\r
2117 (xmlhandler)my_ExternalEntityRefHandler},\r
2118 {"StartDoctypeDeclHandler",\r
2119 (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,\r
2120 (xmlhandler)my_StartDoctypeDeclHandler},\r
2121 {"EndDoctypeDeclHandler",\r
2122 (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,\r
2123 (xmlhandler)my_EndDoctypeDeclHandler},\r
2124 {"EntityDeclHandler",\r
2125 (xmlhandlersetter)XML_SetEntityDeclHandler,\r
2126 (xmlhandler)my_EntityDeclHandler},\r
2127 {"XmlDeclHandler",\r
2128 (xmlhandlersetter)XML_SetXmlDeclHandler,\r
2129 (xmlhandler)my_XmlDeclHandler},\r
2130 {"ElementDeclHandler",\r
2131 (xmlhandlersetter)XML_SetElementDeclHandler,\r
2132 (xmlhandler)my_ElementDeclHandler},\r
2133 {"AttlistDeclHandler",\r
2134 (xmlhandlersetter)XML_SetAttlistDeclHandler,\r
2135 (xmlhandler)my_AttlistDeclHandler},\r
2136#if XML_COMBINED_VERSION >= 19504\r
2137 {"SkippedEntityHandler",\r
2138 (xmlhandlersetter)XML_SetSkippedEntityHandler,\r
2139 (xmlhandler)my_SkippedEntityHandler},\r
2140#endif\r
2141\r
2142 {NULL, NULL, NULL} /* sentinel */\r
2143};\r