(root)/
libxml2-2.12.3/
python/
types.c
       1  /*
       2   * types.c: converter functions between the internal representation
       3   *          and the Python objects
       4   *
       5   * See Copyright for the status of this software.
       6   *
       7   * daniel@veillard.com
       8   */
       9  #include "libxml_wrap.h"
      10  #include <libxml/xpathInternals.h>
      11  #include <string.h>
      12  
      13  #if PY_MAJOR_VERSION >= 3
      14  #define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
      15  #define PY_IMPORT_STRING PyUnicode_FromString
      16  #define PY_IMPORT_INT PyLong_FromLong
      17  #else
      18  #define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
      19  #define PY_IMPORT_STRING PyString_FromString
      20  #define PY_IMPORT_INT PyInt_FromLong
      21  #endif
      22  
      23  #if PY_MAJOR_VERSION >= 3
      24  #include <stdio.h>
      25  #include <stdint.h>
      26  
      27  #ifdef _WIN32
      28  
      29  #include <windows.h>
      30  #include <crtdbg.h>
      31  
      32  /* Taken from info on MSDN site, as we may not have the Windows WDK/DDK headers */
      33  typedef struct _IO_STATUS_BLOCK {
      34    union {
      35      NTSTATUS Status;
      36      PVOID    Pointer;
      37    } DUMMYUNIONNAME;
      38    ULONG_PTR Information;
      39  } IO_STATUS_BLOCK;
      40  
      41  typedef struct _FILE_ACCESS_INFORMATION {
      42    ACCESS_MASK AccessFlags;
      43  } FILE_ACCESS_INFORMATION;
      44  
      45  typedef NTSTATUS (*t_NtQueryInformationFile) (HANDLE           FileHandle,
      46                                                IO_STATUS_BLOCK *IoStatusBlock,
      47                                                PVOID            FileInformation,
      48                                                ULONG            Length,
      49                                                int              FileInformationClass); /* this is an Enum */
      50  
      51  #if (defined (_MSC_VER) && _MSC_VER >= 1400)
      52  /*
      53   * This is the (empty) invalid parameter handler
      54   * that is used for Visual C++ 2005 (and later) builds
      55   * so that we can use this instead of the system automatically
      56   * aborting the process.
      57   *
      58   * This is necessary as we use _get_oshandle() to check the validity
      59   * of the file descriptors as we close them, so when an invalid file
      60   * descriptor is passed into that function as we check on it, we get
      61   * -1 as the result, instead of the gspawn helper program aborting.
      62   *
      63   * Please see http://msdn.microsoft.com/zh-tw/library/ks2530z6%28v=vs.80%29.aspx
      64   * for an explanation on this.
      65   */
      66  void
      67  myInvalidParameterHandler(const wchar_t *expression,
      68                            const wchar_t *function,
      69                            const wchar_t *file,
      70                            unsigned int   line,
      71                            uintptr_t      pReserved)
      72  {
      73  }
      74  #endif
      75  #else
      76  #include <unistd.h>
      77  #include <fcntl.h>
      78  #endif
      79  
      80  FILE *
      81  libxml_PyFileGet(PyObject *f) {
      82      FILE *res;
      83      const char *mode;
      84      int fd = PyObject_AsFileDescriptor(f);
      85  
      86  #ifdef _WIN32
      87      intptr_t w_fh = -1;
      88      HMODULE hntdll = NULL;
      89      IO_STATUS_BLOCK status_block;
      90      FILE_ACCESS_INFORMATION ai;
      91      t_NtQueryInformationFile NtQueryInformationFile;
      92      BOOL is_read = FALSE;
      93      BOOL is_write = FALSE;
      94      BOOL is_append = FALSE;
      95  
      96  #if (defined (_MSC_VER) && _MSC_VER >= 1400)
      97      /* set up our empty invalid parameter handler */
      98      _invalid_parameter_handler oldHandler, newHandler;
      99      newHandler = myInvalidParameterHandler;
     100      oldHandler = _set_invalid_parameter_handler(newHandler);
     101  
     102      /* Disable the message box for assertions. */
     103      _CrtSetReportMode(_CRT_ASSERT, 0);
     104  #endif
     105  
     106      w_fh = _get_osfhandle(fd);
     107  
     108      if (w_fh == -1)
     109          return(NULL);
     110  
     111      hntdll = GetModuleHandleW(L"ntdll.dll");
     112  
     113      if (hntdll == NULL)
     114          return(NULL);
     115  XML_IGNORE_FPTR_CAST_WARNINGS
     116      NtQueryInformationFile = (t_NtQueryInformationFile)GetProcAddress(hntdll, "NtQueryInformationFile");
     117  XML_POP_WARNINGS
     118  
     119      if (NtQueryInformationFile != NULL &&
     120          (NtQueryInformationFile((HANDLE)w_fh,
     121                                 &status_block,
     122                                 &ai,
     123                                  sizeof(FILE_ACCESS_INFORMATION),
     124                                  8) == 0)) /* 8 means "FileAccessInformation" */
     125          {
     126              if (ai.AccessFlags & FILE_READ_DATA)
     127                  is_read = TRUE;
     128              if (ai.AccessFlags & FILE_WRITE_DATA)
     129                  is_write = TRUE;
     130              if (ai.AccessFlags & FILE_APPEND_DATA)
     131                  is_append = TRUE;
     132  
     133              if (is_write) {
     134                  if (is_read) {
     135                      if (is_append)
     136                          mode = "a+";
     137                      else
     138                          mode = "rw";
     139                  } else {
     140                      if (is_append)
     141                          mode = "a";
     142                      else
     143                          mode = "w";
     144                  }
     145              } else {
     146                  if (is_append)
     147                      mode = "r+";
     148                  else
     149                      mode = "r";
     150              }
     151          }
     152  
     153      FreeLibrary(hntdll);
     154  
     155      if (!is_write && !is_read) /* also happens if we did not load or run NtQueryInformationFile() successfully */
     156          return(NULL);
     157  #else
     158      int flags;
     159  
     160      /*
     161       * macOS returns O_RDWR for standard streams, but fails to write to
     162       * stdout or stderr when opened with fdopen(dup_fd, "rw").
     163       */
     164      switch (fd) {
     165          case STDIN_FILENO:
     166              mode = "r";
     167              break;
     168          case STDOUT_FILENO:
     169          case STDERR_FILENO:
     170              mode = "w";
     171              break;
     172          default:
     173              /*
     174               * Get the flags on the fd to understand how it was opened
     175               */
     176              flags = fcntl(fd, F_GETFL, 0);
     177              switch (flags & O_ACCMODE) {
     178                  case O_RDWR:
     179                      if (flags & O_APPEND)
     180                          mode = "a+";
     181                      else
     182                          mode = "rw";
     183                      break;
     184                  case O_RDONLY:
     185                      if (flags & O_APPEND)
     186                          mode = "r+";
     187                      else
     188                          mode = "r";
     189                      break;
     190                  case O_WRONLY:
     191                      if (flags & O_APPEND)
     192                          mode = "a";
     193                      else
     194                          mode = "w";
     195                      break;
     196                  default:
     197                      return(NULL);
     198              }
     199      }
     200  #endif
     201  
     202      /*
     203       * the FILE struct gets a new fd, so that it can be closed
     204       * independently of the file descriptor given. The risk though is
     205       * lack of sync. So at the python level sync must be implemented
     206       * before and after a conversion took place. No way around it
     207       * in the Python3 infrastructure !
     208       * The duplicated fd and FILE * will be released in the subsequent
     209       * call to libxml_PyFileRelease() which must be generated accordingly
     210       */
     211      fd = dup(fd);
     212      if (fd == -1)
     213          return(NULL);
     214      res = fdopen(fd, mode);
     215      if (res == NULL) {
     216          close(fd);
     217  	return(NULL);
     218      }
     219      return(res);
     220  }
     221  
     222  void libxml_PyFileRelease(FILE *f) {
     223      if (f != NULL)
     224          fclose(f);
     225  }
     226  #endif
     227  
     228  PyObject *
     229  libxml_intWrap(int val)
     230  {
     231      PyObject *ret;
     232  
     233      ret = PY_IMPORT_INT((long) val);
     234      return (ret);
     235  }
     236  
     237  PyObject *
     238  libxml_longWrap(long val)
     239  {
     240      PyObject *ret;
     241  
     242      ret = PyLong_FromLong(val);
     243      return (ret);
     244  }
     245  
     246  PyObject *
     247  libxml_doubleWrap(double val)
     248  {
     249      PyObject *ret;
     250  
     251      ret = PyFloat_FromDouble((double) val);
     252      return (ret);
     253  }
     254  
     255  PyObject *
     256  libxml_charPtrWrap(char *str)
     257  {
     258      PyObject *ret;
     259  
     260      if (str == NULL) {
     261          Py_INCREF(Py_None);
     262          return (Py_None);
     263      }
     264      ret = PY_IMPORT_STRING(str);
     265      xmlFree(str);
     266      return (ret);
     267  }
     268  
     269  PyObject *
     270  libxml_charPtrConstWrap(const char *str)
     271  {
     272      PyObject *ret;
     273  
     274      if (str == NULL) {
     275          Py_INCREF(Py_None);
     276          return (Py_None);
     277      }
     278      ret = PY_IMPORT_STRING(str);
     279      return (ret);
     280  }
     281  
     282  PyObject *
     283  libxml_xmlCharPtrWrap(xmlChar * str)
     284  {
     285      PyObject *ret;
     286  
     287      if (str == NULL) {
     288          Py_INCREF(Py_None);
     289          return (Py_None);
     290      }
     291      ret = PY_IMPORT_STRING((char *) str);
     292      xmlFree(str);
     293      return (ret);
     294  }
     295  
     296  PyObject *
     297  libxml_xmlCharPtrConstWrap(const xmlChar * str)
     298  {
     299      PyObject *ret;
     300  
     301      if (str == NULL) {
     302          Py_INCREF(Py_None);
     303          return (Py_None);
     304      }
     305      ret = PY_IMPORT_STRING((char *) str);
     306      return (ret);
     307  }
     308  
     309  PyObject *
     310  libxml_constcharPtrWrap(const char *str)
     311  {
     312      PyObject *ret;
     313  
     314      if (str == NULL) {
     315          Py_INCREF(Py_None);
     316          return (Py_None);
     317      }
     318      ret = PY_IMPORT_STRING(str);
     319      return (ret);
     320  }
     321  
     322  PyObject *
     323  libxml_constxmlCharPtrWrap(const xmlChar * str)
     324  {
     325      PyObject *ret;
     326  
     327      if (str == NULL) {
     328          Py_INCREF(Py_None);
     329          return (Py_None);
     330      }
     331      ret = PY_IMPORT_STRING((char *) str);
     332      return (ret);
     333  }
     334  
     335  PyObject *
     336  libxml_xmlDocPtrWrap(xmlDocPtr doc)
     337  {
     338      PyObject *ret;
     339  
     340      if (doc == NULL) {
     341          Py_INCREF(Py_None);
     342          return (Py_None);
     343      }
     344      /* TODO: look at deallocation */
     345      ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL);
     346      return (ret);
     347  }
     348  
     349  PyObject *
     350  libxml_xmlNodePtrWrap(xmlNodePtr node)
     351  {
     352      PyObject *ret;
     353  
     354      if (node == NULL) {
     355          Py_INCREF(Py_None);
     356          return (Py_None);
     357      }
     358      ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL);
     359      return (ret);
     360  }
     361  
     362  PyObject *
     363  libxml_xmlURIPtrWrap(xmlURIPtr uri)
     364  {
     365      PyObject *ret;
     366  
     367      if (uri == NULL) {
     368          Py_INCREF(Py_None);
     369          return (Py_None);
     370      }
     371      ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL);
     372      return (ret);
     373  }
     374  
     375  PyObject *
     376  libxml_xmlNsPtrWrap(xmlNsPtr ns)
     377  {
     378      PyObject *ret;
     379  
     380      if (ns == NULL) {
     381          Py_INCREF(Py_None);
     382          return (Py_None);
     383      }
     384      ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL);
     385      return (ret);
     386  }
     387  
     388  PyObject *
     389  libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
     390  {
     391      PyObject *ret;
     392  
     393      if (attr == NULL) {
     394          Py_INCREF(Py_None);
     395          return (Py_None);
     396      }
     397      ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL);
     398      return (ret);
     399  }
     400  
     401  PyObject *
     402  libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
     403  {
     404      PyObject *ret;
     405  
     406      if (attr == NULL) {
     407          Py_INCREF(Py_None);
     408          return (Py_None);
     409      }
     410      ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL);
     411      return (ret);
     412  }
     413  
     414  PyObject *
     415  libxml_xmlElementPtrWrap(xmlElementPtr elem)
     416  {
     417      PyObject *ret;
     418  
     419      if (elem == NULL) {
     420          Py_INCREF(Py_None);
     421          return (Py_None);
     422      }
     423      ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL);
     424      return (ret);
     425  }
     426  
     427  PyObject *
     428  libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
     429  {
     430      PyObject *ret;
     431  
     432      if (ctxt == NULL) {
     433          Py_INCREF(Py_None);
     434          return (Py_None);
     435      }
     436      ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
     437      return (ret);
     438  }
     439  
     440  PyObject *
     441  libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
     442  {
     443      PyObject *ret;
     444  
     445      if (ctxt == NULL) {
     446          Py_INCREF(Py_None);
     447          return (Py_None);
     448      }
     449      ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
     450      return (ret);
     451  }
     452  
     453  PyObject *
     454  libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
     455  {
     456      PyObject *ret;
     457  
     458      if (ctxt == NULL) {
     459          Py_INCREF(Py_None);
     460          return (Py_None);
     461      }
     462  
     463      ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
     464      return (ret);
     465  }
     466  
     467  /**
     468   * libxml_xmlXPathDestructNsNode:
     469   * cap: xmlNsPtr namespace node capsule object
     470   *
     471   * This function is called if and when a namespace node returned in
     472   * an XPath node set is to be destroyed. That's the only kind of
     473   * object returned in node set not directly linked to the original
     474   * xmlDoc document, see xmlXPathNodeSetDupNs.
     475   */
     476  #if PY_VERSION_HEX < 0x02070000
     477  static void
     478  libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
     479  #else
     480  static void
     481  libxml_xmlXPathDestructNsNode(PyObject *cap)
     482  #endif
     483  {
     484  #if PY_VERSION_HEX < 0x02070000
     485      xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
     486  #else
     487      xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
     488  #endif
     489  }
     490  
     491  PyObject *
     492  libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
     493  {
     494      PyObject *ret;
     495  
     496      if (obj == NULL) {
     497          Py_INCREF(Py_None);
     498          return (Py_None);
     499      }
     500      switch (obj->type) {
     501          case XPATH_XSLT_TREE: {
     502              if ((obj->nodesetval == NULL) ||
     503  		(obj->nodesetval->nodeNr == 0) ||
     504  		(obj->nodesetval->nodeTab == NULL)) {
     505                  ret = PyList_New(0);
     506  	    } else {
     507  		int i, len = 0;
     508  		xmlNodePtr node;
     509  
     510  		node = obj->nodesetval->nodeTab[0]->children;
     511  		while (node != NULL) {
     512  		    len++;
     513  		    node = node->next;
     514  		}
     515  		ret = PyList_New(len);
     516  		node = obj->nodesetval->nodeTab[0]->children;
     517  		for (i = 0;i < len;i++) {
     518                      PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
     519  		    node = node->next;
     520  		}
     521  	    }
     522  	    /*
     523  	     * Return now, do not free the object passed down
     524  	     */
     525  	    return (ret);
     526  	}
     527          case XPATH_NODESET:
     528              if ((obj->nodesetval == NULL)
     529                  || (obj->nodesetval->nodeNr == 0)) {
     530                  ret = PyList_New(0);
     531  	    } else {
     532                  int i;
     533                  xmlNodePtr node;
     534  
     535                  ret = PyList_New(obj->nodesetval->nodeNr);
     536                  for (i = 0; i < obj->nodesetval->nodeNr; i++) {
     537                      node = obj->nodesetval->nodeTab[i];
     538                      if (node->type == XML_NAMESPACE_DECL) {
     539  		        PyObject *ns = PyCapsule_New((void *) node,
     540                                       (char *) "xmlNsPtr",
     541  				     libxml_xmlXPathDestructNsNode);
     542  			PyList_SetItem(ret, i, ns);
     543  			/* make sure the xmlNsPtr is not destroyed now */
     544  			obj->nodesetval->nodeTab[i] = NULL;
     545  		    } else {
     546  			PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
     547  		    }
     548                  }
     549              }
     550              break;
     551          case XPATH_BOOLEAN:
     552              ret = PY_IMPORT_INT((long) obj->boolval);
     553              break;
     554          case XPATH_NUMBER:
     555              ret = PyFloat_FromDouble(obj->floatval);
     556              break;
     557          case XPATH_STRING:
     558  	    ret = PY_IMPORT_STRING((char *) obj->stringval);
     559              break;
     560  #ifdef LIBXML_XPTR_LOCS_ENABLED
     561          case XPATH_POINT:
     562          {
     563              PyObject *node;
     564              PyObject *indexIntoNode;
     565              PyObject *tuple;
     566  
     567              node = libxml_xmlNodePtrWrap(obj->user);
     568              indexIntoNode = PY_IMPORT_INT((long) obj->index);
     569  
     570              tuple = PyTuple_New(2);
     571              PyTuple_SetItem(tuple, 0, node);
     572              PyTuple_SetItem(tuple, 1, indexIntoNode);
     573  
     574              ret = tuple;
     575              break;
     576          }
     577          case XPATH_RANGE:
     578          {
     579              unsigned short bCollapsedRange;
     580  
     581              bCollapsedRange = ( (obj->user2 == NULL) ||
     582  		                ((obj->user2 == obj->user) && (obj->index == obj->index2)) );
     583              if ( bCollapsedRange ) {
     584                  PyObject *node;
     585                  PyObject *indexIntoNode;
     586                  PyObject *tuple;
     587                  PyObject *list;
     588  
     589                  list = PyList_New(1);
     590  
     591                  node = libxml_xmlNodePtrWrap(obj->user);
     592                  indexIntoNode = PY_IMPORT_INT((long) obj->index);
     593  
     594                  tuple = PyTuple_New(2);
     595                  PyTuple_SetItem(tuple, 0, node);
     596                  PyTuple_SetItem(tuple, 1, indexIntoNode);
     597  
     598                  PyList_SetItem(list, 0, tuple);
     599  
     600                  ret = list;
     601              } else {
     602                  PyObject *node;
     603                  PyObject *indexIntoNode;
     604                  PyObject *tuple;
     605                  PyObject *list;
     606  
     607                  list = PyList_New(2);
     608  
     609                  node = libxml_xmlNodePtrWrap(obj->user);
     610                  indexIntoNode = PY_IMPORT_INT((long) obj->index);
     611  
     612                  tuple = PyTuple_New(2);
     613                  PyTuple_SetItem(tuple, 0, node);
     614                  PyTuple_SetItem(tuple, 1, indexIntoNode);
     615  
     616                  PyList_SetItem(list, 0, tuple);
     617  
     618                  node = libxml_xmlNodePtrWrap(obj->user2);
     619                  indexIntoNode = PY_IMPORT_INT((long) obj->index2);
     620  
     621                  tuple = PyTuple_New(2);
     622                  PyTuple_SetItem(tuple, 0, node);
     623                  PyTuple_SetItem(tuple, 1, indexIntoNode);
     624  
     625                  PyList_SetItem(list, 1, tuple);
     626  
     627                  ret = list;
     628              }
     629              break;
     630          }
     631          case XPATH_LOCATIONSET:
     632          {
     633              xmlLocationSetPtr set;
     634  
     635              set = obj->user;
     636              if ( set && set->locNr > 0 ) {
     637                  int i;
     638                  PyObject *list;
     639  
     640                  list = PyList_New(set->locNr);
     641  
     642                  for (i=0; i<set->locNr; i++) {
     643                      xmlXPathObjectPtr setobj;
     644                      PyObject *pyobj;
     645  
     646                      setobj = set->locTab[i]; /*xmlXPathObjectPtr setobj*/
     647  
     648                      pyobj = libxml_xmlXPathObjectPtrWrap(setobj);
     649                      /* xmlXPathFreeObject(setobj) is called */
     650                      set->locTab[i] = NULL;
     651  
     652                      PyList_SetItem(list, i, pyobj);
     653                  }
     654                  set->locNr = 0;
     655                  ret = list;
     656              } else {
     657                  Py_INCREF(Py_None);
     658                  ret = Py_None;
     659              }
     660              break;
     661          }
     662  #endif /* LIBXML_XPTR_LOCS_ENABLED */
     663          default:
     664              Py_INCREF(Py_None);
     665              ret = Py_None;
     666      }
     667      xmlXPathFreeObject(obj);
     668      return (ret);
     669  }
     670  
     671  xmlXPathObjectPtr
     672  libxml_xmlXPathObjectPtrConvert(PyObject *obj)
     673  {
     674      xmlXPathObjectPtr ret = NULL;
     675  
     676      if (obj == NULL) {
     677          return (NULL);
     678      }
     679      if (PyFloat_Check (obj)) {
     680          ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
     681      } else if (PyLong_Check(obj)) {
     682  #ifdef PyLong_AS_LONG
     683          ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
     684  #else
     685          ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
     686  #endif
     687  #ifdef PyBool_Check
     688      } else if (PyBool_Check (obj)) {
     689  
     690          if (obj == Py_True) {
     691            ret = xmlXPathNewBoolean(1);
     692          }
     693          else {
     694            ret = xmlXPathNewBoolean(0);
     695          }
     696  #endif
     697      } else if (PyBytes_Check (obj)) {
     698          xmlChar *str;
     699  
     700          str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
     701                           PyBytes_GET_SIZE(obj));
     702          ret = xmlXPathWrapString(str);
     703  #ifdef PyUnicode_Check
     704      } else if (PyUnicode_Check (obj)) {
     705  #if PY_VERSION_HEX >= 0x03030000
     706          xmlChar *str;
     707  	const char *tmp;
     708  	Py_ssize_t size;
     709  
     710  	/* tmp doesn't need to be deallocated */
     711          tmp = PyUnicode_AsUTF8AndSize(obj, &size);
     712          str = xmlStrndup((const xmlChar *) tmp, (int) size);
     713          ret = xmlXPathWrapString(str);
     714  #else
     715          xmlChar *str = NULL;
     716          PyObject *b;
     717  
     718  	b = PyUnicode_AsUTF8String(obj);
     719  	if (b != NULL) {
     720  	    str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
     721  			     PyBytes_GET_SIZE(b));
     722  	    Py_DECREF(b);
     723  	}
     724  	ret = xmlXPathWrapString(str);
     725  #endif
     726  #endif
     727      } else if (PyList_Check (obj)) {
     728          int i;
     729          PyObject *node;
     730          xmlNodePtr cur;
     731          xmlNodeSetPtr set;
     732  
     733          set = xmlXPathNodeSetCreate(NULL);
     734  
     735          for (i = 0; i < PyList_Size(obj); i++) {
     736              node = PyList_GetItem(obj, i);
     737              if ((node == NULL) || (node->ob_type == NULL))
     738                  continue;
     739  
     740              cur = NULL;
     741              if (PyCapsule_CheckExact(node)) {
     742                  cur = PyxmlNode_Get(node);
     743              } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
     744  	               (PyObject_HasAttrString(node, (char *) "get_doc"))) {
     745  		PyObject *wrapper;
     746  
     747  		wrapper = PyObject_GetAttrString(node, (char *) "_o");
     748  		if (wrapper != NULL)
     749  		    cur = PyxmlNode_Get(wrapper);
     750              } else {
     751              }
     752              if (cur != NULL) {
     753                  xmlXPathNodeSetAdd(set, cur);
     754              }
     755          }
     756          ret = xmlXPathWrapNodeSet(set);
     757      } else {
     758      }
     759      return (ret);
     760  }
     761  
     762  PyObject *
     763  libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
     764  {
     765  	PyObject *ret;
     766  
     767  	if (valid == NULL) {
     768  		Py_INCREF(Py_None);
     769  		return (Py_None);
     770  	}
     771  
     772  	ret = 
     773  		PyCapsule_New((void *) valid,
     774  									 (char *) "xmlValidCtxtPtr", NULL);
     775  
     776  	return (ret);
     777  }
     778  
     779  PyObject *
     780  libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
     781  {
     782      PyObject *ret;
     783  
     784      if (catal == NULL) {
     785          Py_INCREF(Py_None);
     786          return (Py_None);
     787      }
     788      ret =
     789          PyCapsule_New((void *) catal,
     790                                       (char *) "xmlCatalogPtr", NULL);
     791      return (ret);
     792  }
     793  
     794  PyObject *
     795  libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
     796  {
     797      PyObject *ret;
     798  
     799      if (buffer == NULL) {
     800          Py_INCREF(Py_None);
     801          return (Py_None);
     802      }
     803      ret =
     804          PyCapsule_New((void *) buffer,
     805                                       (char *) "xmlOutputBufferPtr", NULL);
     806      return (ret);
     807  }
     808  
     809  PyObject *
     810  libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
     811  {
     812      PyObject *ret;
     813  
     814      if (buffer == NULL) {
     815          Py_INCREF(Py_None);
     816          return (Py_None);
     817      }
     818      ret =
     819          PyCapsule_New((void *) buffer,
     820                                       (char *) "xmlParserInputBufferPtr", NULL);
     821      return (ret);
     822  }
     823  
     824  #ifdef LIBXML_REGEXP_ENABLED
     825  PyObject *
     826  libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
     827  {
     828      PyObject *ret;
     829  
     830      if (regexp == NULL) {
     831          Py_INCREF(Py_None);
     832          return (Py_None);
     833      }
     834      ret =
     835          PyCapsule_New((void *) regexp,
     836                                       (char *) "xmlRegexpPtr", NULL);
     837      return (ret);
     838  }
     839  #endif /* LIBXML_REGEXP_ENABLED */
     840  
     841  #ifdef LIBXML_READER_ENABLED
     842  PyObject *
     843  libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
     844  {
     845      PyObject *ret;
     846  
     847      if (reader == NULL) {
     848          Py_INCREF(Py_None);
     849          return (Py_None);
     850      }
     851      ret =
     852          PyCapsule_New((void *) reader,
     853                                       (char *) "xmlTextReaderPtr", NULL);
     854      return (ret);
     855  }
     856  
     857  PyObject *
     858  libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
     859  {
     860      PyObject *ret;
     861  
     862      if (locator == NULL) {
     863          Py_INCREF(Py_None);
     864          return (Py_None);
     865      }
     866      ret =
     867          PyCapsule_New((void *) locator,
     868                                       (char *) "xmlTextReaderLocatorPtr", NULL);
     869      return (ret);
     870  }
     871  #endif /* LIBXML_READER_ENABLED */
     872  
     873  #ifdef LIBXML_SCHEMAS_ENABLED
     874  PyObject *
     875  libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
     876  {
     877      PyObject *ret;
     878  
     879      if (ctxt == NULL) {
     880          Py_INCREF(Py_None);
     881          return (Py_None);
     882      }
     883      ret =
     884          PyCapsule_New((void *) ctxt,
     885                                       (char *) "xmlRelaxNGPtr", NULL);
     886      return (ret);
     887  }
     888  
     889  PyObject *
     890  libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
     891  {
     892      PyObject *ret;
     893  
     894      if (ctxt == NULL) {
     895          Py_INCREF(Py_None);
     896          return (Py_None);
     897      }
     898      ret =
     899          PyCapsule_New((void *) ctxt,
     900                                       (char *) "xmlRelaxNGParserCtxtPtr", NULL);
     901      return (ret);
     902  }
     903  PyObject *
     904  libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
     905  {
     906      PyObject *ret;
     907  
     908      if (valid == NULL) {
     909          Py_INCREF(Py_None);
     910          return (Py_None);
     911      }
     912      ret =
     913          PyCapsule_New((void *) valid,
     914                                       (char *) "xmlRelaxNGValidCtxtPtr", NULL);
     915      return (ret);
     916  }
     917  
     918  PyObject *
     919  libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
     920  {
     921  	PyObject *ret;
     922  
     923  	if (ctxt == NULL) {
     924  		Py_INCREF(Py_None);
     925  		return (Py_None);
     926  	}
     927  	ret =
     928  		PyCapsule_New((void *) ctxt,
     929  									 (char *) "xmlSchemaPtr", NULL);
     930  	return (ret);
     931  }
     932  
     933  PyObject *
     934  libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
     935  {
     936  	PyObject *ret;
     937  
     938  	if (ctxt == NULL) {
     939  		Py_INCREF(Py_None);
     940  		return (Py_None);
     941  	}
     942  	ret = 
     943  		PyCapsule_New((void *) ctxt,
     944  									 (char *) "xmlSchemaParserCtxtPtr", NULL);
     945  
     946  	return (ret);
     947  }
     948  
     949  PyObject *
     950  libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
     951  {
     952  	PyObject *ret;
     953  	
     954  	if (valid == NULL) {
     955  		Py_INCREF(Py_None);
     956  		return (Py_None);
     957  	}
     958  
     959  	ret = 
     960  		PyCapsule_New((void *) valid,
     961  									 (char *) "xmlSchemaValidCtxtPtr", NULL);
     962  
     963  	return (ret);
     964  }
     965  #endif /* LIBXML_SCHEMAS_ENABLED */
     966  
     967  static void
     968  libxml_xmlDestructError(PyObject *cap) {
     969      xmlErrorPtr err = (xmlErrorPtr) PyCapsule_GetPointer(cap, "xmlErrorPtr");
     970      xmlResetError(err);
     971      xmlFree(err);
     972  }
     973  
     974  PyObject *
     975  libxml_xmlErrorPtrWrap(const xmlError *error)
     976  {
     977      PyObject *ret;
     978      xmlErrorPtr copy;
     979  
     980      if (error == NULL) {
     981          Py_INCREF(Py_None);
     982          return (Py_None);
     983      }
     984      copy = xmlMalloc(sizeof(*copy));
     985      if (copy == NULL) {
     986          Py_INCREF(Py_None);
     987          return (Py_None);
     988      }
     989      memset(copy, 0, sizeof(*copy));
     990      xmlCopyError(error, copy);
     991      ret = PyCapsule_New(copy, "xmlErrorPtr", libxml_xmlDestructError);
     992      return (ret);
     993  }