home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / pyexpat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  30.9 KB  |  1,100 lines

  1. #include "Python.h"
  2. #ifdef HAVE_EXPAT_H
  3. #include "expat.h"
  4. #else
  5. #include "xmlparse.h"
  6. #endif
  7.  
  8. enum HandlerTypes {
  9.     StartElement,
  10.     EndElement,
  11.     ProcessingInstruction,
  12.     CharacterData,
  13.     UnparsedEntityDecl,
  14.     NotationDecl,
  15.     StartNamespaceDecl,
  16.     EndNamespaceDecl,
  17.     Comment,
  18.     StartCdataSection,
  19.     EndCdataSection,
  20.     Default,
  21.     DefaultHandlerExpand,
  22.     NotStandalone,
  23.     ExternalEntityRef
  24. };
  25.  
  26. static PyObject *ErrorObject;
  27.  
  28. /* ----------------------------------------------------- */
  29.  
  30. /* Declarations for objects of type xmlparser */
  31.  
  32. typedef struct {
  33.     PyObject_HEAD
  34.  
  35.     XML_Parser itself;
  36.     int returns_unicode; /* True if Unicode strings are returned;
  37.                             if false, UTF-8 strings are returned */
  38.     PyObject **handlers;
  39. } xmlparseobject;
  40.  
  41. staticforward PyTypeObject Xmlparsetype;
  42.  
  43. typedef void (*xmlhandlersetter)(XML_Parser *self, void *meth);
  44. typedef void* xmlhandler;
  45.  
  46. struct HandlerInfo {
  47.     const char *name;
  48.     xmlhandlersetter setter;
  49.     xmlhandler handler;
  50. };
  51.  
  52. staticforward struct HandlerInfo handler_info[64];
  53.  
  54. /* Convert an array of attributes and their values into a Python dict */
  55.  
  56. static PyObject *
  57. conv_atts_using_string(XML_Char **atts)
  58. {
  59.     PyObject *attrs_obj = NULL;
  60.     XML_Char **attrs_p, **attrs_k = NULL;
  61.     int attrs_len;
  62.     PyObject *rv;
  63.  
  64.     if ((attrs_obj = PyDict_New()) == NULL) 
  65.         goto finally;
  66.     for (attrs_len = 0, attrs_p = atts; 
  67.          *attrs_p;
  68.          attrs_p++, attrs_len++) {
  69.         if (attrs_len % 2) {
  70.             rv = PyString_FromString(*attrs_p);  
  71.             if (!rv) {
  72.                 Py_DECREF(attrs_obj);
  73.                 attrs_obj = NULL;
  74.                 goto finally;
  75.             }
  76.             if (PyDict_SetItemString(attrs_obj,
  77.                                      (char*)*attrs_k, rv) < 0) {
  78.                 Py_DECREF(attrs_obj);
  79.                 attrs_obj = NULL;
  80.                 goto finally;
  81.             }
  82.             Py_DECREF(rv);
  83.         }
  84.         else 
  85.             attrs_k = attrs_p;
  86.     }
  87.  finally:
  88.     return attrs_obj;
  89. }
  90.  
  91. #if !(PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6)
  92. static PyObject *
  93. conv_atts_using_unicode(XML_Char **atts)
  94. {
  95.     PyObject *attrs_obj;
  96.     XML_Char **attrs_p, **attrs_k = NULL;
  97.     int attrs_len;
  98.  
  99.     if ((attrs_obj = PyDict_New()) == NULL) 
  100.         goto finally;
  101.     for (attrs_len = 0, attrs_p = atts; 
  102.          *attrs_p;
  103.          attrs_p++, attrs_len++) {
  104.         if (attrs_len % 2) {
  105.             PyObject *attr_str, *value_str;
  106.             const char *p = (const char *) (*attrs_k);
  107.             attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict"); 
  108.             if (!attr_str) {
  109.                 Py_DECREF(attrs_obj);
  110.                 attrs_obj = NULL;
  111.                 goto finally;
  112.             }
  113.             p = (const char *) *attrs_p;
  114.             value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
  115.             if (!value_str) {
  116.                 Py_DECREF(attrs_obj);
  117.                 Py_DECREF(attr_str);
  118.                 attrs_obj = NULL;
  119.                 goto finally;
  120.             }
  121.             if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
  122.                 Py_DECREF(attrs_obj);
  123.                 Py_DECREF(attr_str);
  124.                 Py_DECREF(value_str);
  125.                 attrs_obj = NULL;
  126.                 goto finally;
  127.             }
  128.             Py_DECREF(attr_str);
  129.             Py_DECREF(value_str);
  130.         }
  131.         else
  132.             attrs_k = attrs_p;
  133.     }
  134.  finally:
  135.     return attrs_obj;
  136. }
  137.  
  138. /* Convert a string of XML_Chars into a Unicode string.
  139.    Returns None if str is a null pointer. */
  140.  
  141. static PyObject *
  142. conv_string_to_unicode(XML_Char *str)
  143. {
  144.     /* XXX currently this code assumes that XML_Char is 8-bit, 
  145.        and hence in UTF-8.  */
  146.     /* UTF-8 from Expat, Unicode desired */
  147.     if (str == NULL) {
  148.         Py_INCREF(Py_None);
  149.         return Py_None;
  150.     }
  151.     return PyUnicode_DecodeUTF8((const char *)str, 
  152.                                 strlen((const char *)str), 
  153.                                 "strict");
  154. }
  155.  
  156. static PyObject *
  157. conv_string_len_to_unicode(const XML_Char *str, int len)
  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, len, "strict");
  167. }
  168. #endif
  169.  
  170. /* Convert a string of XML_Chars into an 8-bit Python string.
  171.    Returns None if str is a null pointer. */
  172.  
  173. static PyObject *
  174. conv_string_to_utf8(XML_Char *str)
  175. {
  176.     /* XXX currently this code assumes that XML_Char is 8-bit, 
  177.        and hence in UTF-8.  */
  178.     /* UTF-8 from Expat, UTF-8 desired */
  179.     if (str == NULL) {
  180.         Py_INCREF(Py_None);
  181.         return Py_None;
  182.     }
  183.     return PyString_FromString((const char *)str);
  184. }
  185.  
  186. static PyObject *
  187. conv_string_len_to_utf8(const XML_Char *str,  int len) 
  188. {
  189.     /* XXX currently this code assumes that XML_Char is 8-bit, 
  190.        and hence in UTF-8.  */
  191.     /* UTF-8 from Expat, UTF-8 desired */
  192.     if (str == NULL) {
  193.         Py_INCREF(Py_None);
  194.         return Py_None;
  195.     }
  196.     return PyString_FromStringAndSize((const char *)str, len);
  197. }
  198.  
  199. /* Callback routines */
  200.  
  201. static void clear_handlers(xmlparseobject *self);
  202.  
  203. static void
  204. flag_error(xmlparseobject *self)
  205. {
  206.     clear_handlers(self);
  207. }
  208.  
  209. #define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
  210.         RETURN, GETUSERDATA) \
  211. \
  212. static RC my_##NAME##Handler PARAMS {\
  213.     xmlparseobject *self = GETUSERDATA ; \
  214.     PyObject *args=NULL; \
  215.     PyObject *rv=NULL; \
  216.     INIT \
  217. \
  218.     if (self->handlers[NAME] \
  219.         && self->handlers[NAME] != Py_None) { \
  220.         args = Py_BuildValue PARAM_FORMAT ;\
  221.         if (!args) return RETURN; \
  222.         rv = PyEval_CallObject(self->handlers[NAME], args); \
  223.         Py_DECREF(args); \
  224.         if (rv == NULL) { \
  225.             flag_error(self); \
  226.             return RETURN; \
  227.         } \
  228.         CONVERSION \
  229.         Py_DECREF(rv); \
  230.     } \
  231.     return RETURN; \
  232. }
  233.  
  234. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  235. #define STRING_CONV_FUNC conv_string_to_utf8
  236. #else
  237. /* Python 1.6 and later versions */
  238. #define STRING_CONV_FUNC (self->returns_unicode \
  239.                           ? conv_string_to_unicode : conv_string_to_utf8)
  240. #endif
  241.  
  242. #define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
  243.     RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
  244.     (xmlparseobject *)userData)
  245.  
  246. #define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
  247.     RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
  248.             rc = PyInt_AsLong(rv);, rc, \
  249.     (xmlparseobject *)userData)
  250.  
  251. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  252. VOID_HANDLER(StartElement, 
  253.         (void *userData, const XML_Char *name, const XML_Char **atts), 
  254.                 ("(O&O&)", STRING_CONV_FUNC, name, 
  255.          conv_atts_using_string, atts ) )
  256. #else
  257. /* Python 1.6 and later */
  258. VOID_HANDLER(StartElement, 
  259.         (void *userData, const XML_Char *name, const XML_Char **atts), 
  260.                 ("(O&O&)", STRING_CONV_FUNC, name, 
  261.          (self->returns_unicode  
  262.           ? conv_atts_using_unicode 
  263.           : conv_atts_using_string), atts))
  264. #endif
  265.  
  266. VOID_HANDLER(EndElement, 
  267.         (void *userData, const XML_Char *name), 
  268.                 ("(O&)", STRING_CONV_FUNC, name))
  269.  
  270. VOID_HANDLER(ProcessingInstruction,
  271.         (void *userData, 
  272.         const XML_Char *target, 
  273.         const XML_Char *data),
  274.                 ("(O&O&)",STRING_CONV_FUNC,target, STRING_CONV_FUNC,data))
  275.  
  276. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  277. VOID_HANDLER(CharacterData, 
  278.           (void *userData, const XML_Char *data, int len), 
  279.           ("(N)", conv_string_len_to_utf8(data,len)))
  280. #else
  281. VOID_HANDLER(CharacterData, 
  282.           (void *userData, const XML_Char *data, int len), 
  283.           ("(N)", (self->returns_unicode 
  284.                ? conv_string_len_to_unicode(data,len) 
  285.                : conv_string_len_to_utf8(data,len))))
  286. #endif
  287.  
  288. VOID_HANDLER(UnparsedEntityDecl,
  289.         (void *userData, 
  290.             const XML_Char *entityName,
  291.             const XML_Char *base,
  292.             const XML_Char *systemId,
  293.                 const XML_Char *publicId,
  294.                 const XML_Char *notationName),
  295.                 ("(O&O&O&O&O&)", 
  296.          STRING_CONV_FUNC,entityName, STRING_CONV_FUNC,base, 
  297.          STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId, 
  298.          STRING_CONV_FUNC,notationName))
  299.  
  300. VOID_HANDLER(NotationDecl, 
  301.         (void *userData,
  302.             const XML_Char *notationName,
  303.             const XML_Char *base,
  304.             const XML_Char *systemId,
  305.             const XML_Char *publicId),
  306.                 ("(O&O&O&O&)", 
  307.          STRING_CONV_FUNC,notationName, STRING_CONV_FUNC,base, 
  308.          STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId))
  309.  
  310. VOID_HANDLER(StartNamespaceDecl,
  311.         (void *userData,
  312.               const XML_Char *prefix,
  313.               const XML_Char *uri),
  314.                 ("(O&O&)", STRING_CONV_FUNC,prefix, STRING_CONV_FUNC,uri))
  315.  
  316. VOID_HANDLER(EndNamespaceDecl,
  317.         (void *userData,
  318.             const XML_Char *prefix),
  319.                 ("(O&)", STRING_CONV_FUNC,prefix))
  320.  
  321. VOID_HANDLER(Comment,
  322.                (void *userData, const XML_Char *prefix),
  323.                 ("(O&)", STRING_CONV_FUNC,prefix))
  324.  
  325. VOID_HANDLER(StartCdataSection,
  326.                (void *userData),
  327.         ("()"))
  328.         
  329. VOID_HANDLER(EndCdataSection,
  330.                (void *userData),
  331.         ("()"))
  332.  
  333. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  334. VOID_HANDLER(Default,
  335.           (void *userData,  const XML_Char *s, int len),
  336.           ("(N)", conv_string_len_to_utf8(s,len)))
  337.  
  338. VOID_HANDLER(DefaultHandlerExpand,
  339.           (void *userData,  const XML_Char *s, int len),
  340.           ("(N)", conv_string_len_to_utf8(s,len)))
  341. #else
  342. VOID_HANDLER(Default,
  343.           (void *userData,  const XML_Char *s, int len),
  344.           ("(N)", (self->returns_unicode 
  345.                ? conv_string_len_to_unicode(s,len) 
  346.                : conv_string_len_to_utf8(s,len))))
  347.  
  348. VOID_HANDLER(DefaultHandlerExpand,
  349.           (void *userData,  const XML_Char *s, int len),
  350.           ("(N)", (self->returns_unicode 
  351.                ? conv_string_len_to_unicode(s,len) 
  352.                : conv_string_len_to_utf8(s,len))))
  353. #endif
  354.  
  355. INT_HANDLER(NotStandalone, 
  356.         (void *userData), 
  357.         ("()"))
  358.  
  359. RC_HANDLER(int, ExternalEntityRef,
  360.         (XML_Parser parser,
  361.             const XML_Char *context,
  362.             const XML_Char *base,
  363.             const XML_Char *systemId,
  364.             const XML_Char *publicId),
  365.         int rc=0;,
  366.                 ("(O&O&O&O&)", 
  367.          STRING_CONV_FUNC,context, STRING_CONV_FUNC,base, 
  368.          STRING_CONV_FUNC,systemId, STRING_CONV_FUNC,publicId),
  369.         rc = PyInt_AsLong(rv);, rc,
  370.         XML_GetUserData(parser))
  371.         
  372.  
  373.  
  374. /* ---------------------------------------------------------------- */
  375.  
  376. static char xmlparse_Parse__doc__[] = 
  377. "Parse(data[, isfinal])\n\
  378. Parse XML data.  `isfinal' should be true at end of input.";
  379.  
  380. static PyObject *
  381. xmlparse_Parse(xmlparseobject *self, PyObject *args)
  382. {
  383.     char *s;
  384.     int slen;
  385.     int isFinal = 0;
  386.     int rv;
  387.  
  388.     if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
  389.         return NULL;
  390.     rv = XML_Parse(self->itself, s, slen, isFinal);
  391.     if (PyErr_Occurred()) {    
  392.         return NULL;
  393.     }
  394.     else if (rv == 0) {
  395.         PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
  396.                      XML_ErrorString(XML_GetErrorCode(self->itself)),
  397.                      XML_GetErrorLineNumber(self->itself),
  398.                      XML_GetErrorColumnNumber(self->itself));
  399.         return NULL;
  400.     }
  401.     return PyInt_FromLong(rv);
  402. }
  403.  
  404. /* File reading copied from cPickle */
  405.  
  406. #define BUF_SIZE 2048
  407.  
  408. static int
  409. readinst(char *buf, int buf_size, PyObject *meth)
  410. {
  411.     PyObject *arg = NULL;
  412.     PyObject *bytes = NULL;
  413.     PyObject *str = NULL;
  414.     int len = -1;
  415.  
  416.     if ((bytes = PyInt_FromLong(buf_size)) == NULL)
  417.         goto finally;
  418.  
  419.     if ((arg = PyTuple_New(1)) == NULL)
  420.         goto finally;
  421.  
  422.     PyTuple_SET_ITEM(arg, 0, bytes);
  423.  
  424.     if ((str = PyObject_CallObject(meth, arg)) == NULL)
  425.         goto finally;
  426.  
  427.     /* XXX what to do if it returns a Unicode string? */
  428.     if (!PyString_Check(str)) {
  429.         PyErr_Format(PyExc_TypeError, 
  430.                      "read() did not return a string object (type=%.400s)",
  431.                      str->ob_type->tp_name);
  432.         goto finally;
  433.     }
  434.     len = PyString_GET_SIZE(str);
  435.     if (len > buf_size) {
  436.         PyErr_Format(PyExc_ValueError,
  437.                      "read() returned too much data: "
  438.                      "%i bytes requested, %i returned",
  439.                      buf_size, len);
  440.         Py_DECREF(str);
  441.         goto finally;
  442.     }
  443.     memcpy(buf, PyString_AsString(str), len);
  444. finally:
  445.     Py_XDECREF(arg);
  446.     Py_XDECREF(str);
  447.     return len;
  448. }
  449.  
  450. static char xmlparse_ParseFile__doc__[] = 
  451. "ParseFile(file)\n\
  452. Parse XML data from file-like object.";
  453.  
  454. static PyObject *
  455. xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
  456. {
  457.     int rv = 1;
  458.     PyObject *f;
  459.     FILE *fp;
  460.     PyObject *readmethod = NULL;
  461.  
  462.     if (!PyArg_ParseTuple(args, "O:ParseFile", &f))
  463.         return NULL;
  464.  
  465.     if (PyFile_Check(f)) {
  466.         fp = PyFile_AsFile(f);
  467.     }
  468.     else{
  469.         fp = NULL;
  470.         readmethod = PyObject_GetAttrString(f, "read");
  471.         if (readmethod == NULL) {
  472.             PyErr_Clear();
  473.             PyErr_SetString(PyExc_TypeError, 
  474.                             "argument must have 'read' attribute");
  475.             return 0;
  476.         }
  477.     }
  478.     for (;;) {
  479.         int bytes_read;
  480.         void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
  481.         if (buf == NULL)
  482.             return PyErr_NoMemory();
  483.  
  484.         if (fp) {
  485.             bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
  486.             if (bytes_read < 0) {
  487.                 PyErr_SetFromErrno(PyExc_IOError);
  488.                 return NULL;
  489.             }
  490.         }
  491.         else {
  492.             bytes_read = readinst(buf, BUF_SIZE, readmethod);
  493.             if (bytes_read < 0)
  494.                 return NULL;
  495.         }
  496.         rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
  497.         if (PyErr_Occurred())
  498.             return NULL;
  499.  
  500.         if (!rv || bytes_read == 0)
  501.             break;
  502.     }
  503.     return Py_BuildValue("i", rv);
  504. }
  505.  
  506. static char xmlparse_SetBase__doc__[] = 
  507. "SetBase(base_url)\n\
  508. Set the base URL for the parser.";
  509.  
  510. static PyObject *
  511. xmlparse_SetBase(xmlparseobject *self, PyObject *args)
  512. {
  513.     char *base;
  514.  
  515.     if (!PyArg_ParseTuple(args, "s:SetBase", &base))
  516.         return NULL;
  517.     if (!XML_SetBase(self->itself, base)) {
  518.     return PyErr_NoMemory();
  519.     }
  520.     Py_INCREF(Py_None);
  521.     return Py_None;
  522. }
  523.  
  524. static char xmlparse_GetBase__doc__[] = 
  525. "GetBase() -> url\n\
  526. Return base URL string for the parser.";
  527.  
  528. static PyObject *
  529. xmlparse_GetBase(xmlparseobject *self, PyObject *args)
  530. {
  531.     if (!PyArg_ParseTuple(args, ":GetBase"))
  532.         return NULL;
  533.  
  534.     return Py_BuildValue("z", XML_GetBase(self->itself));
  535. }
  536.  
  537. static char xmlparse_ExternalEntityParserCreate__doc__[] = 
  538. "ExternalEntityParserCreate(context, encoding)\n\
  539. Create a parser for parsing an external entity based on the\n\
  540. information passed to the ExternalEntityRefHandler.";
  541.  
  542. static PyObject *
  543. xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
  544. {
  545.     char *context;
  546.     char *encoding = NULL;
  547.     xmlparseobject *new_parser;
  548.     int i;
  549.  
  550.     if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
  551.               &encoding)) {
  552.         return NULL;
  553.     }
  554.  
  555. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  556.     new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype);
  557.     if (new_parser == NULL)
  558.         return NULL;
  559.  
  560.     new_parser->returns_unicode = 0;
  561. #else
  562.     /* Code for versions 1.6 and later */
  563.     new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
  564.     if (new_parser == NULL)
  565.         return NULL;
  566.  
  567.     new_parser->returns_unicode = 1;
  568. #endif
  569.     
  570.     new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
  571.                             encoding);    
  572.     if (!new_parser) {
  573.         Py_DECREF(new_parser);
  574.         return PyErr_NoMemory();
  575.     }
  576.  
  577.     XML_SetUserData(new_parser->itself, (void *)new_parser);
  578.  
  579.     /* allocate and clear handlers first */
  580.     for(i = 0; handler_info[i].name != NULL; i++)
  581.       /* do nothing */;
  582.  
  583.     new_parser->handlers = malloc(sizeof(PyObject *)*i);
  584.     clear_handlers(new_parser);
  585.  
  586.     /* then copy handlers from self */
  587.     for (i = 0; handler_info[i].name != NULL; i++) {
  588.       if (self->handlers[i]) {
  589.     Py_INCREF(self->handlers[i]);
  590.     new_parser->handlers[i] = self->handlers[i];
  591.         handler_info[i].setter(new_parser->itself, 
  592.                    handler_info[i].handler);
  593.       }
  594.     }
  595.       
  596.     return (PyObject *)new_parser;    
  597. }
  598.  
  599.  
  600.  
  601. static struct PyMethodDef xmlparse_methods[] = {
  602.     {"Parse",      (PyCFunction)xmlparse_Parse,
  603.            METH_VARARGS,    xmlparse_Parse__doc__},
  604.     {"ParseFile", (PyCFunction)xmlparse_ParseFile,
  605.            METH_VARARGS,    xmlparse_ParseFile__doc__},
  606.     {"SetBase",   (PyCFunction)xmlparse_SetBase,
  607.            METH_VARARGS,      xmlparse_SetBase__doc__},
  608.     {"GetBase",   (PyCFunction)xmlparse_GetBase,
  609.            METH_VARARGS,      xmlparse_GetBase__doc__},
  610.     {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
  611.            METH_VARARGS,      xmlparse_ExternalEntityParserCreate__doc__},
  612.     {NULL,        NULL}        /* sentinel */
  613. };
  614.  
  615. /* ---------- */
  616.  
  617.  
  618. static xmlparseobject *
  619. newxmlparseobject(char *encoding, char *namespace_separator)
  620. {
  621.     int i;
  622.     xmlparseobject *self;
  623.     
  624. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  625.     self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
  626.     if (self == NULL)
  627.         return NULL;
  628.  
  629.     self->returns_unicode = 0;
  630. #else
  631.     /* Code for versions 1.6 and later */
  632.     self = PyObject_New(xmlparseobject, &Xmlparsetype);
  633.     if (self == NULL)
  634.         return NULL;
  635.  
  636.     self->returns_unicode = 1;
  637. #endif
  638.     if (namespace_separator) {
  639.         self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
  640.     }
  641.     else{
  642.         self->itself = XML_ParserCreate(encoding);
  643.     }
  644.     if (self->itself == NULL) {
  645.         PyErr_SetString(PyExc_RuntimeError, 
  646.                         "XML_ParserCreate failed");
  647.         Py_DECREF(self);
  648.         return NULL;
  649.     }
  650.     XML_SetUserData(self->itself, (void *)self);
  651.  
  652.     for(i = 0; handler_info[i].name != NULL; i++)
  653.         /* do nothing */;
  654.  
  655.     self->handlers = malloc(sizeof(PyObject *)*i);
  656.     clear_handlers(self);
  657.  
  658.     return self;
  659. }
  660.  
  661.  
  662. static void
  663. xmlparse_dealloc(xmlparseobject *self)
  664. {
  665.     int i;
  666.     if (self->itself)
  667.         XML_ParserFree(self->itself);
  668.     self->itself = NULL;
  669.  
  670.     for (i=0; handler_info[i].name != NULL; i++) {
  671.         Py_XDECREF(self->handlers[i]);
  672.     }
  673. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  674.     /* Code for versions before 1.6 */
  675.     free(self);
  676. #else
  677.     /* Code for versions 1.6 and later */
  678.     PyObject_Del(self);
  679. #endif
  680. }
  681.  
  682. static int
  683. handlername2int(const char *name)
  684. {
  685.     int i;
  686.     for (i=0; handler_info[i].name != NULL; i++) {
  687.         if (strcmp(name, handler_info[i].name) == 0) {
  688.             return i;
  689.         }
  690.     }
  691.     return -1;
  692. }
  693.  
  694. static PyObject *
  695. xmlparse_getattr(xmlparseobject *self, char *name)
  696. {
  697.     int handlernum;
  698.     if (strcmp(name, "ErrorCode") == 0)
  699.         return Py_BuildValue("l",
  700.                              (long)XML_GetErrorCode(self->itself));
  701.     if (strcmp(name, "ErrorLineNumber") == 0)
  702.         return Py_BuildValue("l",
  703.                              (long)XML_GetErrorLineNumber(self->itself));
  704.     if (strcmp(name, "ErrorColumnNumber") == 0)
  705.         return Py_BuildValue("l",
  706.                              (long)XML_GetErrorColumnNumber(self->itself));
  707.     if (strcmp(name, "ErrorByteIndex") == 0)
  708.         return Py_BuildValue("l",
  709.                              XML_GetErrorByteIndex(self->itself));
  710.     if (strcmp(name, "returns_unicode") == 0)
  711.         return Py_BuildValue("i", self->returns_unicode);
  712.  
  713.     handlernum = handlername2int(name);
  714.  
  715.     if (handlernum != -1 && self->handlers[handlernum] != NULL) {
  716.         Py_INCREF(self->handlers[handlernum]);
  717.         return self->handlers[handlernum];
  718.     }
  719.     if (strcmp(name, "__members__") == 0) {
  720.         int i;
  721.         PyObject *rc = PyList_New(0);
  722.         for(i = 0; handler_info[i].name!=NULL; i++) {
  723.             PyList_Append(rc, 
  724.                           PyString_FromString(handler_info[i].name));
  725.         }
  726.         PyList_Append(rc, PyString_FromString("ErrorCode"));
  727.         PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
  728.         PyList_Append(rc, PyString_FromString("ErrorColumnNumber"));
  729.         PyList_Append(rc, PyString_FromString("ErrorByteIndex"));
  730.  
  731.         return rc;
  732.     }
  733.     return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
  734. }
  735.  
  736. static int
  737. sethandler(xmlparseobject *self, const char *name, PyObject* v)
  738. {
  739.     int handlernum = handlername2int(name);
  740.     if (handlernum != -1) {
  741.         Py_INCREF(v);
  742.         Py_XDECREF(self->handlers[handlernum]);
  743.         self->handlers[handlernum] = v;
  744.         handler_info[handlernum].setter(self->itself, 
  745.                                         handler_info[handlernum].handler);
  746.         return 1;
  747.     }
  748.     return 0;
  749. }
  750.  
  751. static int
  752. xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
  753. {
  754.     /* Set attribute 'name' to value 'v'. v==NULL means delete */
  755.     if (v==NULL) {
  756.         PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
  757.         return -1;
  758.     }
  759.     if (strcmp(name, "returns_unicode") == 0) {
  760.         PyObject *intobj = PyNumber_Int(v);
  761.         if (intobj == NULL) return -1;
  762.         if (PyInt_AsLong(intobj)) {
  763. #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
  764.             PyErr_SetString(PyExc_ValueError, 
  765.                             "Cannot return Unicode strings in Python 1.5");
  766.             return -1;
  767. #else
  768.             self->returns_unicode = 1;
  769. #endif
  770.         }
  771.         else
  772.             self->returns_unicode = 0;
  773.         Py_DECREF(intobj);
  774.         return 0;
  775.     }
  776.     if (sethandler(self, name, v)) {
  777.         return 0;
  778.     }
  779.     PyErr_SetString(PyExc_AttributeError, name);
  780.     return -1;
  781. }
  782.  
  783. static char Xmlparsetype__doc__[] = 
  784. "XML parser";
  785.  
  786. static PyTypeObject Xmlparsetype = {
  787.     PyObject_HEAD_INIT(NULL)
  788.     0,                /*ob_size*/
  789.     "xmlparser",            /*tp_name*/
  790.     sizeof(xmlparseobject),        /*tp_basicsize*/
  791.     0,                /*tp_itemsize*/
  792.     /* methods */
  793.     (destructor)xmlparse_dealloc,    /*tp_dealloc*/
  794.     (printfunc)0,        /*tp_print*/
  795.     (getattrfunc)xmlparse_getattr,    /*tp_getattr*/
  796.     (setattrfunc)xmlparse_setattr,    /*tp_setattr*/
  797.     (cmpfunc)0,        /*tp_compare*/
  798.     (reprfunc)0,        /*tp_repr*/
  799.     0,            /*tp_as_number*/
  800.     0,        /*tp_as_sequence*/
  801.     0,        /*tp_as_mapping*/
  802.     (hashfunc)0,        /*tp_hash*/
  803.     (ternaryfunc)0,        /*tp_call*/
  804.     (reprfunc)0,        /*tp_str*/
  805.  
  806.     /* Space for future expansion */
  807.     0L,0L,0L,0L,
  808.     Xmlparsetype__doc__ /* Documentation string */
  809. };
  810.  
  811. /* End of code for xmlparser objects */
  812. /* -------------------------------------------------------- */
  813.  
  814.  
  815. static char pyexpat_ParserCreate__doc__[] =
  816. "ParserCreate([encoding[, namespace_separator]]) -> parser\n\
  817. Return a new XML parser object.";
  818.  
  819. static PyObject *
  820. pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
  821. {
  822.     char *encoding = NULL;
  823.         char *namespace_separator = NULL;
  824.     static char *kwlist[] = {"encoding", "namespace_separator", NULL};
  825.  
  826.     if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
  827.                      &encoding, &namespace_separator))
  828.         return NULL;
  829.     return (PyObject *)newxmlparseobject(encoding, namespace_separator);
  830. }
  831.  
  832. static char pyexpat_ErrorString__doc__[] =
  833. "ErrorString(errno) -> string\n\
  834. Returns string error for given number.";
  835.  
  836. static PyObject *
  837. pyexpat_ErrorString(PyObject *self, PyObject *args)
  838. {
  839.     long code = 0;
  840.  
  841.     if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
  842.         return NULL;
  843.     return Py_BuildValue("z", XML_ErrorString((int)code));
  844. }
  845.  
  846. /* List of methods defined in the module */
  847.  
  848. static struct PyMethodDef pyexpat_methods[] = {
  849.     {"ParserCreate",    (PyCFunction)pyexpat_ParserCreate,
  850.      METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
  851.     {"ErrorString",    (PyCFunction)pyexpat_ErrorString,
  852.      METH_VARARGS,    pyexpat_ErrorString__doc__},
  853.  
  854.     {NULL,     (PyCFunction)NULL, 0, NULL}        /* sentinel */
  855. };
  856.  
  857. /* Module docstring */
  858.  
  859. static char pyexpat_module_documentation[] = 
  860. "Python wrapper for Expat parser.";
  861.  
  862. /* Initialization function for the module */
  863.  
  864. void initpyexpat(void);  /* avoid compiler warnings */
  865.  
  866. #if PY_VERSION_HEX < 0x2000000
  867.  
  868. /* 1.5 compatibility: PyModule_AddObject */
  869. static int
  870. PyModule_AddObject(PyObject *m, char *name, PyObject *o)
  871. {
  872.     PyObject *dict;
  873.         if (!PyModule_Check(m) || o == NULL)
  874.                 return -1;
  875.     dict = PyModule_GetDict(m);
  876.     if (dict == NULL)
  877.         return -1;
  878.         if (PyDict_SetItemString(dict, name, o))
  879.                 return -1;
  880.         Py_DECREF(o);
  881.         return 0;
  882. }
  883.  
  884. static int 
  885. PyModule_AddStringConstant(PyObject *m, char *name, char *value)
  886. {
  887.     return PyModule_AddObject(m, name, PyString_FromString(value));
  888. }
  889.  
  890. #endif
  891.  
  892. DL_EXPORT(void)
  893. initpyexpat(void)
  894. {
  895.     PyObject *m, *d;
  896.     char *rev = "$Revision: 2.27 $";
  897.     PyObject *errmod_name = PyString_FromString("pyexpat.errors");
  898.     PyObject *errors_module, *errors_dict;
  899.     PyObject *sys_modules;
  900.  
  901.     if (errmod_name == NULL)
  902.         return;
  903.  
  904.     Xmlparsetype.ob_type = &PyType_Type;
  905.  
  906.     /* Create the module and add the functions */
  907.     m = Py_InitModule4("pyexpat", pyexpat_methods,
  908.                        pyexpat_module_documentation,
  909.                        (PyObject*)NULL, PYTHON_API_VERSION);
  910.  
  911.     /* Add some symbolic constants to the module */
  912.     if (ErrorObject == NULL)
  913.         ErrorObject = PyErr_NewException("xml.parsers.expat.error",
  914.                                          NULL, NULL);
  915.     PyModule_AddObject(m, "error", ErrorObject);
  916.  
  917.     PyModule_AddObject(m, "__version__",
  918.                        PyString_FromStringAndSize(rev+11, strlen(rev+11)-2));
  919.  
  920.     /* XXX When Expat supports some way of figuring out how it was
  921.        compiled, this should check and set native_encoding 
  922.        appropriately. 
  923.     */
  924.     PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
  925.  
  926.     d = PyModule_GetDict(m);
  927.     errors_module = PyDict_GetItem(d, errmod_name);
  928.     if (errors_module == NULL) {
  929.         errors_module = PyModule_New("pyexpat.errors");
  930.         if (errors_module != NULL) {
  931.             sys_modules = PySys_GetObject("modules");
  932.             PyDict_SetItem(sys_modules, errmod_name, errors_module);
  933.             /* gives away the reference to errors_module */
  934.             PyModule_AddObject(m, "errors", errors_module);
  935.         }
  936.     }
  937.     Py_DECREF(errmod_name);
  938.     if (errors_module == NULL)
  939.         /* Don't code dump later! */
  940.         return;
  941.  
  942.     errors_dict = PyModule_GetDict(errors_module);
  943.  
  944. #define MYCONST(name) \
  945.     PyModule_AddStringConstant(errors_module, #name, \
  946.                                (char*)XML_ErrorString(name))
  947.  
  948.     MYCONST(XML_ERROR_NO_MEMORY);
  949.     MYCONST(XML_ERROR_SYNTAX);
  950.     MYCONST(XML_ERROR_NO_ELEMENTS);
  951.     MYCONST(XML_ERROR_INVALID_TOKEN);
  952.     MYCONST(XML_ERROR_UNCLOSED_TOKEN);
  953.     MYCONST(XML_ERROR_PARTIAL_CHAR);
  954.     MYCONST(XML_ERROR_TAG_MISMATCH);
  955.     MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
  956.     MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
  957.     MYCONST(XML_ERROR_PARAM_ENTITY_REF);
  958.     MYCONST(XML_ERROR_UNDEFINED_ENTITY);
  959.     MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
  960.     MYCONST(XML_ERROR_ASYNC_ENTITY);
  961.     MYCONST(XML_ERROR_BAD_CHAR_REF);
  962.     MYCONST(XML_ERROR_BINARY_ENTITY_REF);
  963.     MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
  964.     MYCONST(XML_ERROR_MISPLACED_XML_PI);
  965.     MYCONST(XML_ERROR_UNKNOWN_ENCODING);
  966.     MYCONST(XML_ERROR_INCORRECT_ENCODING);
  967. #undef MYCONST
  968. }
  969.  
  970. static void
  971. clear_handlers(xmlparseobject *self)
  972. {
  973.     int i = 0;
  974.  
  975.     for (; handler_info[i].name!=NULL; i++) {
  976.         self->handlers[i]=NULL;
  977.         handler_info[i].setter(self->itself, NULL);
  978.     }
  979. }
  980.  
  981. typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
  982.  
  983. static void
  984. pyxml_UpdatePairedHandlers(xmlparseobject *self, 
  985.                            int startHandler, 
  986.                            int endHandler,
  987.                            pairsetter setter)
  988. {
  989.     void *start_handler=NULL;
  990.     void *end_handler=NULL;
  991.  
  992.     if (self->handlers[startHandler]
  993.         && self->handlers[endHandler]!=Py_None) {
  994.         start_handler=handler_info[startHandler].handler;
  995.     }
  996.     if (self->handlers[EndElement]
  997.         && self->handlers[EndElement] !=Py_None) {
  998.         end_handler=handler_info[endHandler].handler;
  999.     }
  1000.     setter(self->itself, start_handler, end_handler);
  1001. }
  1002.  
  1003. static void
  1004. pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
  1005. {
  1006.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
  1007.                                StartElement, EndElement,
  1008.                                (pairsetter)XML_SetElementHandler);
  1009. }
  1010.  
  1011. static void
  1012. pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
  1013. {
  1014.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
  1015.                                StartElement, EndElement,
  1016.                                (pairsetter)XML_SetElementHandler);
  1017. }
  1018.  
  1019. static void
  1020. pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
  1021. {
  1022.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
  1023.                                StartNamespaceDecl, EndNamespaceDecl,
  1024.                                (pairsetter)XML_SetNamespaceDeclHandler);
  1025. }
  1026.  
  1027. static void
  1028. pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
  1029. {
  1030.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
  1031.                                StartNamespaceDecl, EndNamespaceDecl,
  1032.                                (pairsetter)XML_SetNamespaceDeclHandler);
  1033. }
  1034.  
  1035. static void
  1036. pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
  1037. {
  1038.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
  1039.                                StartCdataSection, EndCdataSection,
  1040.                                (pairsetter)XML_SetCdataSectionHandler);
  1041. }
  1042.  
  1043. static void
  1044. pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
  1045. {
  1046.     pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
  1047.                                StartCdataSection, EndCdataSection, 
  1048.                                (pairsetter)XML_SetCdataSectionHandler);
  1049. }
  1050.  
  1051. statichere struct HandlerInfo handler_info[] = {
  1052.     {"StartElementHandler", 
  1053.      pyxml_SetStartElementHandler, 
  1054.      (xmlhandler)my_StartElementHandler},
  1055.     {"EndElementHandler", 
  1056.      pyxml_SetEndElementHandler, 
  1057.      (xmlhandler)my_EndElementHandler},
  1058.     {"ProcessingInstructionHandler", 
  1059.      (xmlhandlersetter)XML_SetProcessingInstructionHandler,
  1060.      (xmlhandler)my_ProcessingInstructionHandler},
  1061.     {"CharacterDataHandler", 
  1062.      (xmlhandlersetter)XML_SetCharacterDataHandler,
  1063.      (xmlhandler)my_CharacterDataHandler},
  1064.     {"UnparsedEntityDeclHandler", 
  1065.      (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
  1066.      (xmlhandler)my_UnparsedEntityDeclHandler },
  1067.     {"NotationDeclHandler", 
  1068.      (xmlhandlersetter)XML_SetNotationDeclHandler,
  1069.      (xmlhandler)my_NotationDeclHandler },
  1070.     {"StartNamespaceDeclHandler", 
  1071.      pyxml_SetStartNamespaceDeclHandler,
  1072.      (xmlhandler)my_StartNamespaceDeclHandler },
  1073.     {"EndNamespaceDeclHandler", 
  1074.      pyxml_SetEndNamespaceDeclHandler,
  1075.      (xmlhandler)my_EndNamespaceDeclHandler },
  1076.     {"CommentHandler",
  1077.      (xmlhandlersetter)XML_SetCommentHandler,
  1078.      (xmlhandler)my_CommentHandler},
  1079.     {"StartCdataSectionHandler",
  1080.      pyxml_SetStartCdataSection,
  1081.      (xmlhandler)my_StartCdataSectionHandler},
  1082.     {"EndCdataSectionHandler",
  1083.      pyxml_SetEndCdataSection,
  1084.      (xmlhandler)my_EndCdataSectionHandler},
  1085.     {"DefaultHandler",
  1086.      (xmlhandlersetter)XML_SetDefaultHandler,
  1087.      (xmlhandler)my_DefaultHandler},
  1088.     {"DefaultHandlerExpand",
  1089.      (xmlhandlersetter)XML_SetDefaultHandlerExpand,
  1090.      (xmlhandler)my_DefaultHandlerExpandHandler},
  1091.     {"NotStandaloneHandler",
  1092.      (xmlhandlersetter)XML_SetNotStandaloneHandler,
  1093.      (xmlhandler)my_NotStandaloneHandler},
  1094.     {"ExternalEntityRefHandler",
  1095.      (xmlhandlersetter)XML_SetExternalEntityRefHandler,
  1096.      (xmlhandler)my_ExternalEntityRefHandler },
  1097.  
  1098.     {NULL, NULL, NULL} /* sentinel */
  1099. };
  1100.