summaryrefslogtreecommitdiffstats
path: root/python/sip/siplib
diff options
context:
space:
mode:
Diffstat (limited to 'python/sip/siplib')
-rw-r--r--python/sip/siplib/bool.cpp19
-rw-r--r--python/sip/siplib/objmap.c264
-rw-r--r--python/sip/siplib/qtlib.c1254
-rw-r--r--python/sip/siplib/sip.h1302
-rw-r--r--python/sip/siplib/sipint.h121
-rw-r--r--python/sip/siplib/siplib.c7902
-rw-r--r--python/sip/siplib/siplib.sbf16
-rw-r--r--python/sip/siplib/threads.c223
8 files changed, 0 insertions, 11101 deletions
diff --git a/python/sip/siplib/bool.cpp b/python/sip/siplib/bool.cpp
deleted file mode 100644
index c21a0c79..00000000
--- a/python/sip/siplib/bool.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// This contains all the C++ code that is needed by the sip module.
-//
-// Copyright (c) 2007
-// Riverbank Computing Limited <info@riverbankcomputing.co.uk>
-//
-// This file is part of SIP.
-//
-// This copy of SIP is licensed for use under the terms of the SIP License
-// Agreement. See the file LICENSE for more details.
-//
-// SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-
-// Set a C++ bool for the main C implementation of the module.
-extern "C" void sipSetBool(void *ptr, int val)
-{
- *reinterpret_cast<bool *>(ptr) = val;
-}
diff --git a/python/sip/siplib/objmap.c b/python/sip/siplib/objmap.c
deleted file mode 100644
index efc7bc2a..00000000
--- a/python/sip/siplib/objmap.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * This module implements a hash table class for mapping C/C++ addresses to the
- * corresponding wrapped Python object.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#include <string.h>
-
-#include "sip.h"
-#include "sipint.h"
-
-
-#define hash_1(k,s) (((unsigned long)(k)) % (s))
-#define hash_2(k,s) ((s) - 2 - (hash_1((k),(s)) % ((s) - 2)))
-
-
-/* Prime numbers to use as hash table sizes. */
-static unsigned long hash_primes[] = {
- 521, 1031, 2053, 4099,
- 8209, 16411, 32771, 65537, 131101, 262147,
- 524309, 1048583, 2097169, 4194319, 8388617, 16777259,
- 33554467, 67108879, 134217757, 268435459, 536870923, 1073741827,
- 2147483659U,0
-};
-
-
-static sipHashEntry *newHashTable(unsigned long);
-static sipHashEntry *findHashEntry(sipObjectMap *,void *);
-static void reorganiseMap(sipObjectMap *om);
-
-
-/*
- * Initialise an object map.
- */
-void sipOMInit(sipObjectMap *om)
-{
- om -> primeIdx = 0;
- om -> unused = om -> size = hash_primes[om -> primeIdx];
- om -> stale = 0;
- om -> hash_array = newHashTable(om -> size);
-}
-
-
-/*
- * Finalise an object map.
- */
-void sipOMFinalise(sipObjectMap *om)
-{
- sip_api_free(om -> hash_array);
-}
-
-
-/*
- * Allocate and initialise a new hash table.
- */
-static sipHashEntry *newHashTable(unsigned long size)
-{
- size_t nbytes;
- sipHashEntry *hashtab;
-
- nbytes = sizeof (sipHashEntry) * size;
-
- if ((hashtab = (sipHashEntry *)sip_api_malloc(nbytes)) != NULL)
- memset(hashtab,0,nbytes);
-
- return hashtab;
-}
-
-
-/*
- * Return a pointer to the hash entry that is used, or should be used, for the
- * given C/C++ address.
- */
-static sipHashEntry *findHashEntry(sipObjectMap *om,void *key)
-{
- unsigned long hash, inc;
- void *hek;
-
- hash = hash_1(key,om -> size);
- inc = hash_2(key,om -> size);
-
- while ((hek = om -> hash_array[hash].key) != NULL && hek != key)
- hash = (hash + inc) % om -> size;
-
- return &om -> hash_array[hash];
-}
-
-
-/*
- * Return the wrapped Python object of a specific type for a C/C++ address or
- * NULL if it wasn't found.
- */
-sipWrapper *sipOMFindObject(sipObjectMap *om,void *key, sipWrapperType *type)
-{
- sipHashEntry *he = findHashEntry(om, key);
- sipWrapper *w;
-
- /* Go through each wrapped object at this address. */
- for (w = he->first; w != NULL; w = w->next)
- {
- /*
- * If this wrapped object is of the given type, or a sub-type
- * of it, or vice versa, then we assume it is the same C++
- * object.
- */
- if (PyObject_TypeCheck(w, (PyTypeObject *)type) ||
- PyType_IsSubtype((PyTypeObject *)type, w->ob_type))
- return w;
- }
-
- return NULL;
-}
-
-
-/*
- * Add a C/C++ address and the corresponding wrapped Python object to the map.
- */
-void sipOMAddObject(sipObjectMap *om,sipWrapper *val)
-{
- sipHashEntry *he = findHashEntry(om,val -> u.cppPtr);
-
- /*
- * If the bucket is in use then we appear to have several objects at
- * the same address.
- */
- if (he -> first != NULL)
- {
- /*
- * This can happen for three reasons. A variable of one class
- * can be declared at the start of another class. Therefore
- * there are two objects, of different classes, with the same
- * address. The second reason is that the old C/C++ object has
- * been deleted by C/C++ but we didn't get to find out for some
- * reason, and a new C/C++ instance has been created at the
- * same address. The third reason is if we are in the process
- * of deleting a Python object but the C++ object gets wrapped
- * again because the C++ dtor called a method that has been
- * re-implemented in Python. The absence of the SIP_SHARE_MAP
- * flag tells us that a new C++ instance has just been created
- * and so we know the second reason is the correct one so we
- * mark the old pointers as invalid and reuse the entry.
- * Otherwise we just add this one to the existing list of
- * objects at this address.
- */
- if (!(val -> flags & SIP_SHARE_MAP))
- {
- sipWrapper *w;
-
- for (w = he -> first; w != NULL; w = w -> next)
- w -> u.cppPtr = NULL;
-
- he -> first = NULL;
- }
-
- val -> next = he -> first;
- he -> first = val;
-
- return;
- }
-
- /* See if the bucket was unused or stale. */
- if (he -> key == NULL)
- {
- he -> key = val -> u.cppPtr;
- om -> unused--;
- }
- else
- om -> stale--;
-
- /* Add the rest of the new value. */
- he -> first = val;
- val -> next = NULL;
-
- reorganiseMap(om);
-}
-
-
-/*
- * Reorganise a map if it is running short of space.
- */
-static void reorganiseMap(sipObjectMap *om)
-{
- unsigned long old_size, i;
- sipHashEntry *ohe, *old_tab;
-
- /* Don't bother if it still has more than 12% available. */
- if (om -> unused > om -> size >> 3)
- return;
-
- /*
- * If reorganising (ie. making the stale buckets unused) using the same
- * sized table would make 25% available then do that. Otherwise use a
- * bigger table (if possible).
- */
- if (om -> unused + om -> stale < om -> size >> 2 && hash_primes[om -> primeIdx + 1] != 0)
- om -> primeIdx++;
-
- old_size = om -> size;
- old_tab = om -> hash_array;
-
- om -> unused = om -> size = hash_primes[om -> primeIdx];
- om -> stale = 0;
- om -> hash_array = newHashTable(om -> size);
-
- /* Transfer the entries from the old table to the new one. */
- ohe = old_tab;
-
- for (i = 0; i < old_size; ++i)
- {
- if (ohe -> key != NULL && ohe -> first != NULL)
- {
- *findHashEntry(om,ohe -> key) = *ohe;
- om -> unused--;
- }
-
- ++ohe;
- }
-
- sip_api_free(old_tab);
-}
-
-
-/*
- * Remove a C/C++ object from the table. Return 0 if it was removed
- * successfully.
- */
-int sipOMRemoveObject(sipObjectMap *om,sipWrapper *val)
-{
- sipHashEntry *he = findHashEntry(om,val -> u.cppPtr);
- sipWrapper **wp;
-
- for (wp = &he -> first; *wp != NULL; wp = &(*wp) -> next)
- if (*wp == val)
- {
- *wp = val -> next;
-
- /*
- * If the bucket is now empty then count it as stale.
- * Note that we do not NULL the key and count it as
- * unused because that might throw out the search for
- * another entry that wanted to go here, found it
- * already occupied, and was put somewhere else. In
- * other words, searches must be repeatable until we
- * reorganise the table.
- */
- if (he -> first == NULL)
- om -> stale++;
-
- return 0;
- }
-
- return -1;
-}
diff --git a/python/sip/siplib/qtlib.c b/python/sip/siplib/qtlib.c
deleted file mode 100644
index f3ba4301..00000000
--- a/python/sip/siplib/qtlib.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/*
- * The SIP library code that implements the interface to the optional module
- * supplied Qt support.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#include <Python.h>
-#include <string.h>
-
-#include "sip.h"
-#include "sipint.h"
-
-
-/* This is how Qt "types" signals and slots. */
-#define isQtSlot(s) (*(s) == '1')
-#define isQtSignal(s) (*(s) == '2')
-
-
-static PyObject *py_sender = NULL; /* The last Python signal sender. */
-
-
-static int isSameSlot(sipSlot *,PyObject *,const char *);
-static int emitQtSig(sipWrapper *,const char *,PyObject *);
-static int emitToSlotList(sipSlotList *rxlist, PyObject *sigargs);
-static int addSlotToPySigList(sipWrapper *,const char *,PyObject *,const char *);
-static void removeSlotFromPySigList(sipWrapper *,const char *,PyObject *,const char *);
-static PyObject *getWeakRef(PyObject *obj);
-static sipPySig *findPySignal(sipWrapper *,const char *);
-static char *sipStrdup(const char *);
-static int saveSlot(sipSlot *sp, PyObject *rxObj, const char *slot);
-static void *createUniversalSlot(sipWrapper *txSelf, const char *sig, PyObject *rxObj, const char *slot, const char **member);
-static void *findSignal(void *txrx, const char **sig);
-static void *newSignal(void *txrx, const char **sig);
-static void freeSlot(sipSlot *slot);
-
-
-/*
- * Return the most recent signal sender.
- */
-PyObject *sip_api_get_sender()
-{
- PyObject *sender;
- const void *qt_sender;
-
- /*
- * If there is a Qt sender then it is more recent than the last Python
- * sender, so use it instead.
- */
- if ((qt_sender = sipQtSupport->qt_get_sender()) != NULL)
- sender = sip_api_convert_from_instance((void *)qt_sender, sipQObjectClass, NULL);
- else
- {
- if ((sender = py_sender) == NULL)
- sender = Py_None;
-
- Py_INCREF(sender);
- }
-
- return sender;
-}
-
-
-/*
- * Release the resources held by a connection.
- */
-void sip_api_free_connection(sipSlotConnection *conn)
-{
- freeSlot(&conn->sc_slot);
-}
-
-
-/*
- * Compare two connections and return TRUE if they are the same.
- */
-int sip_api_same_connection(sipSlotConnection *conn, void *tx, const char *sig,
- PyObject *rxObj, const char *slot)
-{
- return (conn->sc_transmitter == tx &&
- sipQtSupport->qt_same_name(conn->sc_signature->sg_signature, sig) &&
- isSameSlot(&conn->sc_slot, rxObj, slot));
-}
-
-
-/*
- * Parse the signal arguments for a connection.
- */
-sipSignature *sip_api_parse_signature(const char *sig)
-{
- static sipSignature *psig_list = NULL;
- sipSignature *psig;
- const char *sp, *ep;
-
- /*
- * First see if it has already been parsed. Note that both sides of a
- * connection will probably be parsed twice because the function names will
- * be different even though the signatures will probably be the same. We
- * could be more clever, the most saving is when repeatedly emitting a
- * signal for which this is sufficient.
- */
- for (psig = psig_list; psig != NULL; psig = psig->sg_next)
- if (sipQtSupport->qt_same_name(psig->sg_signature, sig))
- return psig;
-
- /* Create a new one including space for the copy of the signature. */
- if ((psig = (sipSignature *)sip_api_malloc(sizeof (sipSignature) + strlen(sig) + 1)) == NULL)
- return NULL;
-
- psig->sg_signature = (char *)&psig[1];
- psig->sg_nrargs = 0;
- psig->sg_args = 0;
-
- /* Find the start and end of the arguments. */
- sp = strchr(sig, '(');
- ep = strrchr(sig, ')');
-
- /* If the signal isn't well formed we assume Qt will pick it up. */
- if (sp && ep && sp < ep)
- {
- /*
- * Copy the signature arguments while counting them and
- * removing non-significant spaces. Each argument is left as a
- * '\0' terminated string.
- */
- char *dp = psig->sg_signature;
- int depth = 0, nrcommas = 0, argstart = TRUE;
-
- for (;;)
- {
- char ch = *++sp;
-
- if (strchr(",*&)<>", ch))
- {
- /* Backup over any previous trailing space. */
- if (dp > psig->sg_signature && dp[-1] == ' ')
- --dp;
-
- if (sp == ep)
- {
- *dp = '\0';
- break;
- }
-
- if (ch == ',' && depth == 0)
- {
- *dp++ = '\0';
- ++nrcommas;
- argstart = TRUE;
- }
- else
- {
- *dp++ = ch;
-
- /*
- * Make sure commas in template
- * arguments are ignored.
- */
- if (ch == '<')
- ++depth;
- else if (ch == '>')
- --depth;
- }
- }
- else if (ch == ' ')
- {
- /* Ignore leading and multiple spaces. */
- if (!argstart && dp[-1] != ' ')
- *dp++ = ch;
- }
- else
- {
- *dp++ = ch;
- argstart = FALSE;
- }
- }
-
- /* Handle the arguments now they are in a normal form. */
- if (*psig->sg_signature)
- {
- char *arg = psig->sg_signature;
- int a;
-
- /* Allocate the space. */
- psig->sg_nrargs = nrcommas + 1;
-
- if ((psig->sg_args = (sipSigArg *)sip_api_malloc(sizeof (sipSigArg) * psig->sg_nrargs)) == NULL)
- {
- sip_api_free(psig);
- return NULL;
- }
-
- for (a = 0; a < psig->sg_nrargs; ++a)
- {
- size_t btlen = 0;
- int unsup, isref = FALSE, indir = 0;
- sipSigArgType sat = unknown_sat;
-
- /* Find the start of the significant part of the type. */
- dp = arg;
-
- if (strncmp(dp, "const ", 6) == 0)
- dp += 6;
-
- /*
- * Find the length of the base type, the number of indirections
- * and if it is a reference.
- */
- for (ep = dp; *ep; ++ep)
- if (*ep == '&')
- isref = TRUE;
- else if (*ep == '*')
- ++indir;
- else
- ++btlen;
-
- /*
- * Assume that anything other than a base type is unsupported.
- */
- unsup = (isref || indir);
-
- /* Parse the base type. */
- switch (btlen)
- {
- case 3:
- if (strncmp(dp, "int", 3) == 0)
- sat = int_sat;
- break;
-
- case 4:
- if (strncmp(dp, "bool", 4) == 0)
- sat = bool_sat;
- else if (strncmp(dp, "long", 4) == 0)
- sat = long_sat;
- else if (strncmp(dp, "char", 4) == 0)
- {
- sat = (indir ? string_sat : char_sat);
- unsup = (isref || indir > 1);
- }
- else if (strncmp(dp, "void", 4) == 0)
- {
- sat = void_sat;
- unsup = (isref || indir != 1);
- }
- break;
-
- case 5:
- if (strncmp(dp, "float", 5) == 0)
- sat = float_sat;
- else if (strncmp(dp, "short", 5) == 0)
- sat = short_sat;
- break;
-
- case 6:
- if (strncmp(dp, "double", 6) == 0)
- sat = double_sat;
- break;
-
- case 7:
- if (strncmp(dp, "__int64", 7) == 0)
- sat = longlong_sat;
- else if (strncmp(dp, "wchar_t", 7) == 0)
- {
- sat = (indir ? wstring_sat : wchar_sat);
- unsup = (isref || indir > 1);
- }
- break;
-
- case 8:
- if (strncmp(dp, "unsigned", 8) == 0)
- sat = uint_sat;
- else if (strncmp(dp, "TQVariant", 8) == 0)
- {
- if (indir == 0)
- {
- sat = qvariant_sat;
- unsup = FALSE;
- }
- else if (indir == 1)
- {
- sat = qvariantp_sat;
- unsup = FALSE;
- }
- }
- break;
-
- case 9:
- if (strncmp(dp, "long long", 9) == 0)
- sat = longlong_sat;
- break;
-
- case 11:
- if (strncmp(dp, "signed char", 11) == 0)
- {
- sat = (indir ? sstring_sat : schar_sat);
- unsup = (isref || indir > 1);
- }
- break;
-
- case 12:
- if (strncmp(dp, "unsigned int", 12) == 0)
- sat = uint_sat;
- break;
-
- case 13:
- if (strncmp(dp, "unsigned long", 13) == 0)
- sat = ulong_sat;
- else if (strncmp(dp, "unsigned char", 13) == 0)
- {
- sat = (indir ? ustring_sat : uchar_sat);
- unsup = (isref || indir > 1);
- }
- else if (strncmp(dp, "PyQt_PyObject", 13) == 0 && indir == 0)
- {
- sat = pyobject_sat;
- unsup = FALSE;
- }
- break;
-
- case 14:
- if (strncmp(dp, "unsigned short", 14) == 0)
- sat = ushort_sat;
- break;
-
- case 16:
- if (strncmp(dp, "unsigned __int64", 16) == 0)
- sat = ulonglong_sat;
- break;
-
- case 18:
- if (strncmp(dp, "unsigned long long", 18) == 0)
- sat = ulonglong_sat;
- break;
- }
-
- if (sat == unknown_sat)
- sipFindSigArgType(dp, btlen, &psig->sg_args[a], indir);
- else
- {
- if (unsup)
- sat = unknown_sat;
-
- psig->sg_args[a].atype = sat;
- }
-
- /* Move to the start of the next argument. */
- arg += strlen(arg) + 1;
- }
- }
- }
-
- /* Make a deep copy of the signal. */
- strcpy(psig->sg_signature, sig);
-
- /* Add it to the list so it can be re-used. */
- psig->sg_next = psig_list;
- psig_list = psig;
-
- return psig;
-}
-
-
-/*
- * Find an existing signal.
- */
-static void *findSignal(void *txrx, const char **sig)
-{
- sipSignature *psig;
-
- /*
- * Handle the trivial case where the Qt implementation doesn't support
- * universal signals.
- */
- if (sipQtSupport->qt_is_qt_signal == NULL)
- return txrx;
-
- /* See if this a shortcircuited Python signal. */
- if (strchr(*sig, '(') == NULL)
- return sipQtSupport->qt_find_universal_signal_shortcut(txrx, *sig, sig);
-
- /* See if the existing object can be used itself. */
- if (sipQtSupport->qt_is_qt_signal(txrx, *sig))
- return txrx;
-
- if ((psig = sip_api_parse_signature(*sig)) == NULL)
- return NULL;
-
- /* Find an ordinary universal signal. */
- return sipQtSupport->qt_find_universal_signal(txrx, psig);
-}
-
-
-/*
- * Return a usable signal, creating a new universal signal if needed.
- */
-static void *newSignal(void *txrx, const char **sig)
-{
- sipSignature *psig;
-
- /*
- * Handle the trivial case where the Qt implementation doesn't support
- * universal signals.
- */
- if (sipQtSupport->qt_is_qt_signal == NULL)
- return txrx;
-
- /* See if this a shortcircuited Python signal. */
- if (strchr(*sig, '(') == NULL)
- return sipQtSupport->qt_create_universal_signal_shortcut(txrx, *sig, sig);
-
- /* See if the existing object can be used itself. */
- if (sipQtSupport->qt_is_qt_signal(txrx, *sig))
- return txrx;
-
- if ((psig = sip_api_parse_signature(*sig)) == NULL)
- return NULL;
-
- /* Create an ordinary universal signal. */
- return sipQtSupport->qt_create_universal_signal(txrx, psig);
-}
-
-
-/*
- * Create a universal slot. Returns a pointer to it or 0 if there was an
- * error.
- */
-static void *createUniversalSlot(sipWrapper *txSelf, const char *sig,
- PyObject *rxObj, const char *slot,
- const char **member)
-{
- sipSlotConnection conn;
- void *us;
-
- /* Initialise the connection. */
- conn.sc_transmitter = (txSelf ? sipGetAddress(txSelf) : 0);
-
- /* Save the real slot. */
- if (saveSlot(&conn.sc_slot, rxObj, slot) < 0)
- return 0;
-
- /* Parse the signature and create the universal slot. */
- if ((conn.sc_signature = sip_api_parse_signature(sig)) == NULL || (us = sipQtSupport->qt_create_universal_slot(txSelf, &conn, member)) == NULL)
- {
- sip_api_free_connection(&conn);
- return 0;
- }
-
- return us;
-}
-
-
-/*
- * Emit a Python or Qt signal.
- */
-int sip_api_emit_signal(PyObject *self,const char *sig,PyObject *sigargs)
-{
- sipPySig *ps;
- void *tx;
- sipWrapper *w = (sipWrapper *)self;
-
- /*
- * Don't do anything if signals are blocked. Qt signals would be blocked
- * anyway, but this blocks Python signals as well.
- */
- if ((tx = sip_api_get_cpp_ptr(w, sipQObjectClass)) == NULL || sipQtSupport->qt_signals_blocked(tx))
- return 0;
-
- if (isQtSignal(sig))
- {
- sipSignature *psig;
-
- /* Handle Qt implementations that emit using generated code. */
- if (!sipQtSupport->qt_emit_signal)
- return emitQtSig(w, sig, sigargs);
-
- /* See if the signal is a shortcut. */
- if (strchr(sig, '(') == NULL)
- return sipQtSupport->qt_emit_signal_shortcut(tx, sig, sigargs);
-
- if ((psig = sip_api_parse_signature(sig)) == NULL)
- return -1;
-
- if (psig->sg_nrargs != PyTuple_GET_SIZE(sigargs))
- PyErr_Format(PyExc_TypeError, "Signal has %d arguments, but %d given", psig->sg_nrargs, PyTuple_GET_SIZE(sigargs));
-
- return sipQtSupport->qt_emit_signal(tx, psig, sigargs);
- }
-
- if ((ps = findPySignal(w,sig)) != NULL)
- {
- int rc;
-
- /* Forget the last Qt sender and remember this one. */
- sipQtSupport->qt_forget_sender();
- py_sender = self;
-
- rc = emitToSlotList(ps -> rxlist,sigargs);
-
- /* Forget this as a sender. */
- py_sender = NULL;
-
- return rc;
- }
-
- return 0;
-}
-
-
-/*
- * Search the Python signal list for a signal.
- */
-static sipPySig *findPySignal(sipWrapper *w,const char *sig)
-{
- sipPySig *ps;
-
- for (ps = w -> pySigList; ps != NULL; ps = ps -> next)
- if (sipQtSupport->qt_same_name(ps -> name,sig))
- return ps;
-
- return NULL;
-}
-
-
-/*
- * Search a signal table for a signal. If found, call the emitter function
- * with the signal arguments. Return 0 if the signal was emitted or <0 if
- * there was an error.
- */
-static int emitQtSig(sipWrapper *w,const char *sig,PyObject *sigargs)
-{
- sipQtSignal *tab;
-
- /* Search the table. */
- for (tab = ((sipWrapperType *)(w -> ob_type)) -> type -> td_emit; tab -> st_name != NULL; ++tab)
- {
- const char *sp, *tp;
- int found;
-
- /* Compare only the base name. */
- sp = &sig[1];
- tp = tab -> st_name;
-
- found = TRUE;
-
- while (*sp != '\0' && *sp != '(' && *tp != '\0')
- if (*sp++ != *tp++)
- {
- found = FALSE;
- break;
- }
-
- if (found)
- return (*tab -> st_emitfunc)(w,sigargs);
- }
-
- /* It wasn't found if we got this far. */
- PyErr_Format(PyExc_NameError,"Invalid signal %s",&sig[1]);
-
- return -1;
-}
-
-
-/*
- * Send a signal to a single slot (Qt or Python).
- */
-int sip_api_emit_to_slot(sipSlot *slot, PyObject *sigargs)
-{
- PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *newmeth, *sref;
-
- /* Keep some compilers quiet. */
- oxtype = oxvalue = oxtb = NULL;
-
- /* Fan out Qt signals. */
- if (slot -> name != NULL && slot -> name[0] != '\0')
- return sip_api_emit_signal(slot -> pyobj,slot -> name,sigargs);
-
- /* Get the object to call, resolving any weak references. */
- if (slot -> weakSlot == NULL)
- sref = NULL;
- else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
- return -1;
- else
- Py_INCREF(sref);
-
- if (sref == Py_None)
- {
- /*
- * If the real object has gone then we pretend everything is Ok. This
- * mimics the Qt behaviour of not caring if a receiving object has been
- * deleted.
- */
- Py_DECREF(sref);
- return 0;
- }
-
- if (slot -> pyobj == NULL)
- {
- PyObject *self = (sref != NULL ? sref : slot->meth.mself);
-
- /* See if any underlying C++ instance has gone. */
- if (self != NULL && sip_api_wrapper_check(self) && ((sipWrapper *)self)->u.cppPtr == NULL)
- {
- Py_XDECREF(sref);
- return 0;
- }
-
- if ((sfunc = PyMethod_New(slot->meth.mfunc, self, slot->meth.mclass)) == NULL)
- {
- Py_XDECREF(sref);
- return -1;
- }
-
- /* Make sure we garbage collect the new method. */
- newmeth = sfunc;
- }
- else if (slot -> name != NULL)
- {
- char *mname = slot -> name + 1;
- PyObject *self = (sref != NULL ? sref : slot->pyobj);
-
- /* See if any underlying C++ instance has gone. */
- if (self != NULL && sip_api_wrapper_check(self) && ((sipWrapper *)self)->u.cppPtr == NULL)
- {
- Py_XDECREF(sref);
- return 0;
- }
-
- if ((sfunc = PyObject_GetAttrString(self, mname)) == NULL || !PyCFunction_Check(sfunc))
- {
- /*
- * Note that in earlier versions of SIP this error would be
- * detected when the slot was connected.
- */
- PyErr_Format(PyExc_NameError,"Invalid slot %s",mname);
-
- Py_XDECREF(sref);
- return -1;
- }
-
- /* Make sure we garbage collect the new method. */
- newmeth = sfunc;
- }
- else if (slot->pyobj == Py_None)
- {
- /*
- * This was a lambda function that has been freed by the cyclic garbage
- * collector so ignore it.
- */
- Py_XDECREF(sref);
- return 0;
- }
- else
- {
- sfunc = slot -> pyobj;
- newmeth = NULL;
- }
-
- /*
- * We make repeated attempts to call a slot. If we work out that it failed
- * because of an immediate type error we try again with one less argument.
- * We keep going until we run out of arguments to drop. This emulates the
- * Qt ability of the slot to accept fewer arguments than a signal provides.
- */
- sa = sigargs;
- Py_INCREF(sa);
-
- for (;;)
- {
- PyObject *nsa, *xtype, *xvalue, *xtb, *resobj;
-
- if ((resobj = PyEval_CallObject(sfunc,sa)) != NULL)
- {
- Py_DECREF(resobj);
-
- Py_XDECREF(newmeth);
- Py_XDECREF(sref);
-
- /* Remove any previous exception. */
-
- if (sa != sigargs)
- {
- Py_XDECREF(oxtype);
- Py_XDECREF(oxvalue);
- Py_XDECREF(oxtb);
- PyErr_Clear();
- }
-
- Py_DECREF(sa);
-
- return 0;
- }
-
- /* Get the exception. */
- PyErr_Fetch(&xtype,&xvalue,&xtb);
-
- /*
- * See if it is unacceptable. An acceptable failure is a type error
- * with no traceback - so long as we can still reduce the number of
- * arguments and try again.
- */
- if (!PyErr_GivenExceptionMatches(xtype,PyExc_TypeError) ||
- xtb != NULL ||
- PyTuple_GET_SIZE(sa) == 0)
- {
- /*
- * If there is a traceback then we must have called the slot and
- * the exception was later on - so report the exception as is.
- */
- if (xtb != NULL)
- {
- if (sa != sigargs)
- {
- Py_XDECREF(oxtype);
- Py_XDECREF(oxvalue);
- Py_XDECREF(oxtb);
- }
-
- PyErr_Restore(xtype,xvalue,xtb);
- }
- else if (sa == sigargs)
- PyErr_Restore(xtype,xvalue,xtb);
- else
- {
- /*
- * Discard the latest exception and restore the original one.
- */
- Py_XDECREF(xtype);
- Py_XDECREF(xvalue);
- Py_XDECREF(xtb);
-
- PyErr_Restore(oxtype,oxvalue,oxtb);
- }
-
- break;
- }
-
- /* If this is the first attempt, save the exception. */
- if (sa == sigargs)
- {
- oxtype = xtype;
- oxvalue = xvalue;
- oxtb = xtb;
- }
- else
- {
- Py_XDECREF(xtype);
- Py_XDECREF(xvalue);
- Py_XDECREF(xtb);
- }
-
- /* Create the new argument tuple. */
- if ((nsa = PyTuple_GetSlice(sa,0,PyTuple_GET_SIZE(sa) - 1)) == NULL)
- {
- /* Tidy up. */
- Py_XDECREF(oxtype);
- Py_XDECREF(oxvalue);
- Py_XDECREF(oxtb);
-
- break;
- }
-
- Py_DECREF(sa);
- sa = nsa;
- }
-
- Py_XDECREF(newmeth);
- Py_XDECREF(sref);
-
- Py_DECREF(sa);
-
- return -1;
-}
-
-
-/*
- * Send a signal to the slots (Qt or Python) in a Python list.
- */
-static int emitToSlotList(sipSlotList *rxlist,PyObject *sigargs)
-{
- int rc;
-
- /* Apply the arguments to each slot method. */
- rc = 0;
-
- while (rxlist != NULL && rc >= 0)
- {
- sipSlotList *next;
-
- /*
- * We get the next in the list before calling the slot in case the list
- * gets changed by the slot - usually because the slot disconnects
- * itself.
- */
- next = rxlist -> next;
- rc = sip_api_emit_to_slot(&rxlist -> rx, sigargs);
- rxlist = next;
- }
-
- return rc;
-}
-
-
-/*
- * Add a slot to a transmitter's Python signal list. The signal is a Python
- * signal, the slot may be either a Qt signal, a Qt slot, a Python signal or a
- * Python slot.
- */
-static int addSlotToPySigList(sipWrapper *txSelf,const char *sig,
- PyObject *rxObj,const char *slot)
-{
- sipPySig *ps;
- sipSlotList *psrx;
-
- /* Create a new one if necessary. */
- if ((ps = findPySignal(txSelf,sig)) == NULL)
- {
- if ((ps = (sipPySig *)sip_api_malloc(sizeof (sipPySig))) == NULL)
- return -1;
-
- if ((ps -> name = sipStrdup(sig)) == NULL)
- {
- sip_api_free(ps);
- return -1;
- }
-
- ps -> rxlist = NULL;
- ps -> next = txSelf -> pySigList;
-
- txSelf -> pySigList = ps;
- }
-
- /* Create the new receiver. */
- if ((psrx = (sipSlotList *)sip_api_malloc(sizeof (sipSlotList))) == NULL)
- return -1;
-
- if (saveSlot(&psrx->rx, rxObj, slot) < 0)
- {
- sip_api_free(psrx);
- return -1;
- }
-
- psrx -> next = ps -> rxlist;
- ps -> rxlist = psrx;
-
- return 0;
-}
-
-
-/*
- * Compare two slots to see if they are the same.
- */
-static int isSameSlot(sipSlot *slot1,PyObject *rxobj2,const char *slot2)
-{
- /* See if they are signals or Qt slots, ie. they have a name. */
- if (slot1 -> name != NULL)
- return (slot2 != NULL &&
- sipQtSupport->qt_same_name(slot1 -> name,slot2) &&
- slot1 -> pyobj == rxobj2);
-
- /* Both must be Python slots. */
- if (slot2 != NULL)
- return 0;
-
- /* See if they are Python methods. */
- if (slot1 -> pyobj == NULL)
- return (PyMethod_Check(rxobj2) &&
- slot1 -> meth.mfunc == PyMethod_GET_FUNCTION(rxobj2) &&
- slot1 -> meth.mself == PyMethod_GET_SELF(rxobj2) &&
- slot1 -> meth.mclass == PyMethod_GET_CLASS(rxobj2));
-
- if (PyMethod_Check(rxobj2))
- return 0;
-
- /* The objects must be the same. */
- return (slot1 -> pyobj == rxobj2);
-}
-
-
-/*
- * Convert a valid Python signal or slot to an existing universal slot.
- */
-void *sipGetRx(sipWrapper *txSelf,const char *sigargs,PyObject *rxObj,
- const char *slot,const char **memberp)
-{
- if (slot != NULL)
- if (isQtSlot(slot) || isQtSignal(slot))
- {
- void *rx;
-
- *memberp = slot;
-
- if ((rx = sip_api_get_cpp_ptr((sipWrapper *)rxObj, sipQObjectClass)) == NULL)
- return NULL;
-
- if (isQtSignal(slot))
- rx = findSignal(rx, memberp);
-
- return rx;
- }
-
- /*
- * The slot was either a Python callable or PyQt3 Python signal so there
- * should be a universal slot.
- */
- return sipQtSupport->qt_find_slot(sipGetAddress(txSelf), sigargs, rxObj, slot, memberp);
-}
-
-
-/*
- * Convert a Python receiver (either a Python signal or slot or a Qt signal or
- * slot) to a Qt receiver. It is only ever called when the signal is a Qt
- * signal. Return NULL is there was an error.
- */
-void *sip_api_convert_rx(sipWrapper *txSelf,const char *sig,PyObject *rxObj,
- const char *slot,const char **memberp)
-{
- if (slot == NULL)
- return createUniversalSlot(txSelf, sig, rxObj, NULL, memberp);
-
- if (isQtSlot(slot) || isQtSignal(slot))
- {
- void *rx;
-
- *memberp = slot;
-
- if ((rx = sip_api_get_cpp_ptr((sipWrapper *)rxObj, sipQObjectClass)) == NULL)
- return NULL;
-
- if (isQtSignal(slot))
- rx = newSignal(rx, memberp);
-
- return rx;
- }
-
- /* The slot is a Python signal so we need a universal slot to catch it. */
- return createUniversalSlot(txSelf, sig, rxObj, slot, memberp);
-}
-
-
-/*
- * Connect a Qt signal or a Python signal to a Qt slot, a Qt signal, a Python
- * slot or a Python signal. This is all possible combinations.
- */
-PyObject *sip_api_connect_rx(PyObject *txObj,const char *sig,PyObject *rxObj,
- const char *slot, int type)
-{
- sipWrapper *txSelf = (sipWrapper *)txObj;
-
- /* Handle Qt signals. */
- if (isQtSignal(sig))
- {
- void *tx, *rx;
- const char *member, *real_sig;
- int res;
-
- if ((tx = sip_api_get_cpp_ptr(txSelf, sipQObjectClass)) == NULL)
- return NULL;
-
- real_sig = sig;
-
- if ((tx = newSignal(tx, &real_sig)) == NULL)
- return NULL;
-
- if ((rx = sip_api_convert_rx(txSelf, sig, rxObj, slot, &member)) == NULL)
- return NULL;
-
- res = sipQtSupport->qt_connect(tx, real_sig, rx, member, type);
-
- return PyBool_FromLong(res);
- }
-
- /* Handle Python signals. */
- if (addSlotToPySigList(txSelf, sig, rxObj, slot) < 0)
- return NULL;
-
- Py_INCREF(Py_True);
- return Py_True;
-}
-
-
-/*
- * Disconnect a signal to a signal or a Qt slot.
- */
-PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig,
- PyObject *rxObj,const char *slot)
-{
- sipWrapper *txSelf = (sipWrapper *)txObj;
-
- /* Handle Qt signals. */
- if (isQtSignal(sig))
- {
- void *tx, *rx;
- const char *member;
- int res;
-
- if ((tx = sip_api_get_cpp_ptr(txSelf, sipQObjectClass)) == NULL)
- return NULL;
-
- if ((rx = sipGetRx(txSelf, sig, rxObj, slot, &member)) == NULL)
- {
- Py_INCREF(Py_False);
- return Py_False;
- }
-
- /* Handle Python signals. */
- tx = findSignal(tx, &sig);
-
- res = sipQtSupport->qt_disconnect(tx, sig, rx, member);
-
- /*
- * Delete it if it is a universal slot as this will be it's only
- * connection. If the slot is actually a universal signal then it
- * should leave it in place.
- */
- sipQtSupport->qt_destroy_universal_slot(rx);
-
- return PyBool_FromLong(res);
- }
-
- /* Handle Python signals. */
- removeSlotFromPySigList(txSelf,sig,rxObj,slot);
-
- Py_INCREF(Py_True);
- return Py_True;
-}
-
-
-/*
- * Remove a slot from a transmitter's Python signal list.
- */
-static void removeSlotFromPySigList(sipWrapper *txSelf,const char *sig,
- PyObject *rxObj,const char *slot)
-{
- sipPySig *ps;
-
- if ((ps = findPySignal(txSelf,sig)) != NULL)
- {
- sipSlotList **psrxp;
-
- for (psrxp = &ps -> rxlist; *psrxp != NULL; psrxp = &(*psrxp) -> next)
- {
- sipSlotList *psrx = *psrxp;
-
- if (isSameSlot(&psrx -> rx,rxObj,slot))
- {
- *psrxp = psrx -> next;
- sipFreeSlotList(psrx);
- break;
- }
- }
- }
-}
-
-
-/*
- * Free a sipSlot structure.
- */
-static void freeSlot(sipSlot *slot)
-{
- if (slot->name != NULL)
- sip_api_free(slot->name);
- else
- {
- PyObject *lam = slot->pyobj;
-
- if (lam != NULL && (lam == Py_None || sipLambdaSlot(lam)))
- Py_DECREF(lam);
- }
-
- /* Remove any weak reference. */
- Py_XDECREF(slot->weakSlot);
-}
-
-
-/*
- * Free a sipSlotList structure on the heap.
- */
-void sipFreeSlotList(sipSlotList *rx)
-{
- freeSlot(&rx->rx);
- sip_api_free(rx);
-}
-
-
-/*
- * Implement strdup() using sip_api_malloc().
- */
-static char *sipStrdup(const char *s)
-{
- char *d;
-
- if ((d = (char *)sip_api_malloc(strlen(s) + 1)) != NULL)
- strcpy(d,s);
-
- return d;
-}
-
-
-/*
- * Initialise a slot, returning 0 if there was no error. If the signal was a
- * Qt signal, then the slot may be a Python signal or a Python slot. If the
- * signal was a Python signal, then the slot may be anything.
- */
-static int saveSlot(sipSlot *sp, PyObject *rxObj, const char *slot)
-{
- sp -> weakSlot = NULL;
-
- if (slot == NULL)
- {
- sp -> name = NULL;
-
- if (PyMethod_Check(rxObj))
- {
- /*
- * Python creates methods on the fly. We could increment the
- * reference count to keep it alive, but that would keep "self"
- * alive as well and would probably be a circular reference.
- * Instead we remember the component parts and hope they are still
- * valid when we re-create the method when we need it.
- */
- sipSaveMethod(&sp -> meth,rxObj);
-
- /* Notice if the class instance disappears. */
- sp -> weakSlot = getWeakRef(sp -> meth.mself);
-
- /* This acts a flag to say that the slot is a method. */
- sp -> pyobj = NULL;
- }
- else
- {
- PyObject *self;
-
- /*
- * We know that it is another type of callable, ie. a
- * function/builtin.
- */
-
- if (PyCFunction_Check(rxObj) &&
- (self = PyCFunction_GET_SELF(rxObj)) != NULL &&
- sip_api_wrapper_check(self))
- {
- /*
- * It is a wrapped C++ class method. We can't keep a copy
- * because they are generated on the fly and we can't take a
- * reference as that may keep the instance (ie. self) alive.
- * We therefore treat it as if the user had specified the slot
- * at "obj, TQT_SLOT('meth()')" rather than "obj.meth" (see below).
- */
-
- const char *meth;
-
- /* Get the method name. */
- meth = ((PyCFunctionObject *)rxObj) -> m_ml -> ml_name;
-
- if ((sp -> name = (char *)sip_api_malloc(strlen(meth) + 2)) == NULL)
- return -1;
-
- /*
- * Copy the name and set the marker that it needs converting to
- * a built-in method.
- */
- sp -> name[0] = '\0';
- strcpy(&sp -> name[1],meth);
-
- sp -> pyobj = self;
- sp -> weakSlot = getWeakRef(self);
- }
- else
- {
- /*
- * A bit of a hack to allow lamba functions to be used as
- * slots.
- */
- if (sipLambdaSlot(rxObj))
- Py_INCREF(rxObj);
-
- /*
- * It's unlikely that we will succeed in getting a weak
- * reference to the slot, but there is no harm in trying (and
- * future versions of Python may support references to more
- * object types).
- */
- sp -> pyobj = rxObj;
- sp -> weakSlot = getWeakRef(rxObj);
- }
- }
- }
- else if ((sp -> name = sipStrdup(slot)) == NULL)
- return -1;
- else if (isQtSlot(slot))
- {
- /*
- * The user has decided to connect a Python signal to a Qt slot and
- * specified the slot as "obj, TQT_SLOT('meth()')" rather than "obj.meth".
- */
-
- char *tail;
-
- /* Remove any arguments. */
- if ((tail = strchr(sp -> name,'(')) != NULL)
- *tail = '\0';
-
- /*
- * A bit of a hack to indicate that this needs converting to a built-in
- * method.
- */
- sp -> name[0] = '\0';
-
- /* Notice if the class instance disappears. */
- sp -> weakSlot = getWeakRef(rxObj);
-
- sp -> pyobj = rxObj;
- }
- else
- /* It's a Qt signal. */
- sp -> pyobj = rxObj;
-
- return 0;
-}
-
-
-/*
- * Return a weak reference to the given object.
- */
-static PyObject *getWeakRef(PyObject *obj)
-{
- PyObject *wr;
-
- if ((wr = PyWeakref_NewRef(obj,NULL)) == NULL)
- PyErr_Clear();
-
- return wr;
-}
-
-
-/*
- * See if an object is a lambda function.
- */
-int sipLambdaSlot(PyObject *slotObj)
-{
- if (!PyFunction_Check(slotObj))
- return FALSE;
-
- return (strcmp(PyString_AsString(((PyFunctionObject *)slotObj)->func_name), "<lambda>") == 0);
-}
diff --git a/python/sip/siplib/sip.h b/python/sip/siplib/sip.h
deleted file mode 100644
index 92bcda4e..00000000
--- a/python/sip/siplib/sip.h
+++ /dev/null
@@ -1,1302 +0,0 @@
-/*
- * The SIP module interface.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#ifndef _SIP_H
-#define _SIP_H
-
-
-/*
- * This gets round a problem with Qt's moc and Python v2.3. Strictly speaking
- * it's a Qt problem but later versions of Python include a fix for it so we
- * might as well too.
- */
-#undef slots
-
-
-#include <Python.h>
-
-/*
- * There is a mis-feature somewhere with the Borland compiler. This works
- * around it.
- */
-#if defined(__BORLANDC__)
-#include <rpc.h>
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Sanity check on the Python version. */
-#if PY_VERSION_HEX < 0x02030000
-#error "This version of SIP requires Python v2.3 or later"
-#endif
-
-
-/*
- * Define the SIP version number.
- */
-#define SIP_VERSION 0x040600
-#define SIP_VERSION_STR "4.6"
-
-
-/*
- * Define the current API version number. SIP must handle modules with the
- * same major number and with the same or earlier minor number. Whenever data
- * structure elements are added they must be appended and the minor number
- * incremented. Whenever data structure elements are removed or the order
- * changed then the major number must be incremented and the minor number set
- * to 0.
- *
- * History:
- *
- * 3.4 Added qt_find_connection() to the Qt support API.
- * Added sip_api_string_as_char(), sip_api_unicode_as_wchar(),
- * sip_api_unicode_as_wstring(), sip_api_find_class(),
- * sip_api_find_named_enum() and sip_api_parse_signature().
- * Added the 'A', 'w' and 'x' format characters to sip_api_parse_args(),
- * sip_api_parse_result(), sip_api_build_result() and
- * sip_api_call_method().
- *
- * 3.3 Added sip_api_register_int_types().
- *
- * 3.2 Added sip_api_export_symbol() and sip_api_import_symbol().
- *
- * 3.1 Added sip_api_add_mapped_type_instance().
- *
- * 3.0 Moved the Qt support out of the sip module and into PyQt. This is
- * such a dramatic change that there is no point in attempting to maintain
- * backwards compatibility.
- *
- * 2.0 Added the td_flags field to the sipTypeDef structure.
- * Added the first_child, sibling_next, sibling_prev and parent fields to
- * the sipWrapper structure.
- * Added the td_traverse and td_clear fields to the sipTypeDef structure.
- * Added the em_api_minor field to the sipExportedModuleDef structure.
- * Added sip_api_bad_operator_arg().
- * Added sip_api_wrapper_check().
- *
- * 1.1 Added support for __pos__ and __abs__.
- *
- * 1.0 Removed all deprecated parts of the API.
- * Removed the td_proxy field from the sipTypeDef structure.
- * Removed the create proxy function from the 'q' and 'y' format
- * characters to sip_api_parse_args().
- * Removed sip_api_emit_to_slot().
- * Reworked the enum related structures.
- *
- * 0.2 Added the 'H' format character to sip_api_parse_args().
- *
- * 0.1 Added sip_api_add_class_instance().
- * Added the 't' format character to sip_api_parse_args().
- * Deprecated the 'J' and 'K' format characters to sip_api_parse_result().
- *
- * 0.0 Original version.
- */
-#define SIP_API_MAJOR_NR 3
-#define SIP_API_MINOR_NR 4
-
-
-/* Some compatibility stuff to help with handwritten code for SIP v3. */
-#if !defined(ANY)
-#define ANY void
-#endif
-
-
-/* Some Python compatibility stuff. */
-#if PY_VERSION_HEX >= 0x02050000
-#define SIP_SSIZE_T Py_ssize_t
-#else
-#define SIP_SSIZE_T int
-#endif
-
-
-/*
- * The mask that can be passed to sipTrace().
- */
-#define SIP_TRACE_CATCHERS 0x0001
-#define SIP_TRACE_CTORS 0x0002
-#define SIP_TRACE_DTORS 0x0004
-#define SIP_TRACE_INITS 0x0008
-#define SIP_TRACE_DEALLOCS 0x0010
-#define SIP_TRACE_METHODS 0x0020
-
-
-/*
- * Hide some thread dependent stuff.
- */
-#ifdef WITH_THREAD
-typedef PyGILState_STATE sip_gilstate_t;
-#define SIP_RELEASE_GIL(gs) PyGILState_Release(gs);
-#define SIP_BLOCK_THREADS {PyGILState_STATE sipGIL = PyGILState_Ensure();
-#define SIP_UNBLOCK_THREADS PyGILState_Release(sipGIL);}
-#else
-typedef int sip_gilstate_t;
-#define SIP_RELEASE_GIL(gs)
-#define SIP_BLOCK_THREADS
-#define SIP_UNBLOCK_THREADS
-#endif
-
-
-/*
- * The metatype of a wrapper type.
- */
-typedef struct _sipWrapperType {
- /*
- * The super-metatype. This must be first in the structure so that it can
- * be cast to a PyTypeObject *.
- */
- PyHeapTypeObject super;
-
- /* The additional type information. */
- struct _sipTypeDef *type;
-
- /* The list of init extenders. */
- struct _sipInitExtenderDef *iextend;
-
- /* The optional PyQt defined Q_OBJECT information. */
- void *qt_qobject;
-} sipWrapperType;
-
-
-/*
- * The type of a C/C++ wrapper object.
- */
-typedef struct _sipWrapper {
- PyObject_HEAD
-
- /* For the user to use. */
- PyObject *user;
-
- union {
- /* C/C++ object pointer. */
- void *cppPtr;
-
- /* Access function. */
- void *(*afPtr)();
- } u;
-
- /* Object flags. */
- int flags;
-
- /* The instance dictionary. */
- PyObject *dict;
-
- /* Python signal list (complex). */
- struct _sipPySig *pySigList;
-
- /* Next object at this address. */
- struct _sipWrapper *next;
-
- /* First child object. */
- struct _sipWrapper *first_child;
-
- /* Next sibling. */
- struct _sipWrapper *sibling_next;
-
- /* Previous sibling. */
- struct _sipWrapper *sibling_prev;
-
- /* Owning object. */
- struct _sipWrapper *parent;
-} sipWrapper;
-
-
-/*
- * Some convenient function pointers.
- */
-typedef void *(*sipInitFunc)(sipWrapper *, PyObject *, sipWrapper **, int *);
-typedef int (*sipTraverseFunc)(void *, visitproc, void *);
-typedef int (*sipClearFunc)(void *);
-typedef SIP_SSIZE_T (*sipBufferFunc)(PyObject *, void *, SIP_SSIZE_T, void **);
-typedef SIP_SSIZE_T (*sipSegCountFunc)(PyObject *, void *, SIP_SSIZE_T *);
-typedef void (*sipDeallocFunc)(sipWrapper *);
-typedef void *(*sipCastFunc)(void *, sipWrapperType *);
-typedef sipWrapperType *(*sipSubClassConvertFunc)(void **);
-typedef void *(*sipForceConvertToFunc)(PyObject *, int *);
-typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *);
-typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *);
-typedef int (*sipVirtHandlerFunc)(void *, PyObject *, ...);
-typedef int (*sipEmitFunc)(sipWrapper *, PyObject *);
-typedef void (*sipReleaseFunc)(void *, int);
-
-
-/*
- * The information describing an encoded class ID.
- */
-typedef struct _sipEncodedClassDef {
- /* The class number. */
- unsigned sc_class:16;
-
- /* The module number (255 for this one). */
- unsigned sc_module:8;
-
- /* A context specific flag. */
- unsigned sc_flag:1;
-} sipEncodedClassDef;
-
-
-/*
- * The information describing an enum member.
- */
-typedef struct _sipEnumMemberDef {
- /* The member name. */
- const char *em_name;
-
- /* The member value. */
- int em_val;
-
- /* The member enum, -ve if anonymous. */
- int em_enum;
-} sipEnumMemberDef;
-
-
-/*
- * The information describing a named enum.
- */
-typedef struct _sipEnumDef {
- /* The Python name of the enum. */
- const char *e_name;
-
- /* The C/C++ name of the enum, NULL if the same as the Python name. */
- const char *e_cname;
-
- /* The scoping type. */
- int e_scope;
-
- /* The Python slots. */
- struct _sipPySlotDef *e_pyslots;
-} sipEnumDef;
-
-
-/*
- * The information describing static instances.
- */
-typedef struct _sipInstancesDef {
- /* The classes. */
- struct _sipClassInstanceDef *id_class;
-
- /* The void *. */
- struct _sipVoidPtrInstanceDef *id_voidp;
-
- /* The chars. */
- struct _sipCharInstanceDef *id_char;
-
- /* The strings. */
- struct _sipStringInstanceDef *id_string;
-
- /* The ints. */
- struct _sipIntInstanceDef *id_int;
-
- /* The longs. */
- struct _sipLongInstanceDef *id_long;
-
- /* The unsigned longs. */
- struct _sipUnsignedLongInstanceDef *id_ulong;
-
- /* The long longs. */
- struct _sipLongLongInstanceDef *id_llong;
-
- /* The unsigned long longs. */
- struct _sipUnsignedLongLongInstanceDef *id_ullong;
-
- /* The doubles. */
- struct _sipDoubleInstanceDef *id_double;
-
- /* The enums. */
- struct _sipEnumInstanceDef *id_enum;
-} sipInstancesDef;
-
-
-/*
- * The information describing a type initialiser extender.
- */
-typedef struct _sipInitExtenderDef {
- /* The extender function. */
- sipInitFunc ie_extender;
-
- /* The class being extended. */
- sipEncodedClassDef ie_class;
-
- /* The next extender for this class. */
- struct _sipInitExtenderDef *ie_next;
-} sipInitExtenderDef;
-
-
-/*
- * The information describing a sub-class convertor.
- */
-typedef struct _sipSubClassConvertorDef {
- /* The convertor. */
- sipSubClassConvertFunc scc_convertor;
-
- /* The encoded base type. */
- sipEncodedClassDef scc_base;
-
- /* The base type. */
- sipWrapperType *scc_basetype;
-} sipSubClassConvertorDef;
-
-
-/*
- * The different Python slot types.
- */
-typedef enum {
- str_slot, /* __str__ */
- int_slot, /* __int__ */
- long_slot, /* __long__ */
- float_slot, /* __float__ */
- len_slot, /* __len__ */
- contains_slot, /* __contains__ */
- add_slot, /* __add__ for number */
- concat_slot, /* __add__ for sequence types */
- sub_slot, /* __sub__ */
- mul_slot, /* __mul__ for number types */
- repeat_slot, /* __mul__ for sequence types */
- div_slot, /* __div__ */
- mod_slot, /* __mod__ */
- and_slot, /* __and__ */
- or_slot, /* __or__ */
- xor_slot, /* __xor__ */
- lshift_slot, /* __lshift__ */
- rshift_slot, /* __rshift__ */
- iadd_slot, /* __iadd__ for number types */
- iconcat_slot, /* __iadd__ for sequence types */
- isub_slot, /* __isub__ */
- imul_slot, /* __imul__ for number types */
- irepeat_slot, /* __imul__ for sequence types */
- idiv_slot, /* __idiv__ */
- imod_slot, /* __imod__ */
- iand_slot, /* __iand__ */
- ior_slot, /* __ior__ */
- ixor_slot, /* __ixor__ */
- ilshift_slot, /* __ilshift__ */
- irshift_slot, /* __irshift__ */
- invert_slot, /* __invert__ */
- call_slot, /* __call__ */
- getitem_slot, /* __getitem__ */
- setitem_slot, /* __setitem__ */
- delitem_slot, /* __delitem__ */
- lt_slot, /* __lt__ */
- le_slot, /* __le__ */
- eq_slot, /* __eq__ */
- ne_slot, /* __ne__ */
- gt_slot, /* __gt__ */
- ge_slot, /* __ge__ */
- cmp_slot, /* __cmp__ */
- nonzero_slot, /* __nonzero__ */
- neg_slot, /* __neg__ */
- repr_slot, /* __repr__ */
- hash_slot, /* __hash__ */
- pos_slot, /* __pos__ */
- abs_slot /* __abs__ */
-} sipPySlotType;
-
-
-/*
- * The information describing a Python slot function.
- */
-typedef struct _sipPySlotDef {
- /* The function. */
- void *psd_func;
-
- /* The type. */
- sipPySlotType psd_type;
-} sipPySlotDef;
-
-
-/*
- * The information describing a Python slot extender.
- */
-typedef struct _sipPySlotExtenderDef {
- /* The function. */
- void *pse_func;
-
- /* The type. */
- sipPySlotType pse_type;
-
- /* The encoded class. */
- sipEncodedClassDef pse_class;
-} sipPySlotExtenderDef;
-
-
-/*
- * This enumerates the different dynamic signal argument types.
- */
-typedef enum {
- unknown_sat,
- char_sat,
- uchar_sat,
- string_sat,
- ustring_sat,
- short_sat,
- ushort_sat,
- int_sat,
- uint_sat,
- long_sat,
- ulong_sat,
- longlong_sat,
- ulonglong_sat,
- float_sat,
- double_sat,
- enum_sat,
- bool_sat,
- void_sat,
- class_sat,
- classp_sat,
- mtype_sat,
- mtypep_sat,
- qvariant_sat,
- qvariantp_sat,
- pyobject_sat,
- schar_sat,
- sstring_sat,
- wchar_sat,
- wstring_sat
-} sipSigArgType;
-
-
-/*
- * The information describing a typedef.
- */
-typedef struct _sipTypedefDef {
- /* The typedef name. */
- const char *tdd_name;
-
- /* The typedef type. */
- sipSigArgType tdd_type;
-
- /* The type name for enum_sat, class_sat and mtype_sat. */
- const char *tdd_type_name;
-
- /* The defining module, NULL if the current one. */
- const char *tdd_mod_name;
-} sipTypedefDef;
-
-
-/*
- * The information describing a type.
- */
-typedef struct _sipTypeDef {
- /* The module. */
- struct _sipExportedModuleDef *td_module;
-
- /* Type flags, see the sipType*() macros. */
- int td_flags;
-
- /* The Python name of the type. */
- const char *td_name;
-
- /* The C/C++ name of the type, NULL if the same as the Python name. */
- const char *td_cname;
-
- /* The scoping type. */
- sipEncodedClassDef td_scope;
-
- /* The super-types. */
- sipEncodedClassDef *td_supers;
-
- /* The table of Python slots. */
- sipPySlotDef *td_pyslots;
-
- /* The number of lazy methods. */
- int td_nrmethods;
-
- /* The table of lazy methods. */
- PyMethodDef *td_methods;
-
- /* The number of lazy enum members. */
- int td_nrenummembers;
-
- /* The table of lazy enum members. */
- sipEnumMemberDef *td_enummembers;
-
- /* The variable table. */
- PyMethodDef *td_variables;
-
- /* The initialisation function. */
- sipInitFunc td_init;
-
- /* The traverse function. */
- sipTraverseFunc td_traverse;
-
- /* The clear function. */
- sipClearFunc td_clear;
-
- /* The read buffer function. */
- sipBufferFunc td_readbuffer;
-
- /* The write buffer function. */
- sipBufferFunc td_writebuffer;
-
- /* The segment count function. */
- sipSegCountFunc td_segcount;
-
- /* The char buffer function. */
- sipBufferFunc td_charbuffer;
-
- /* The deallocation function. */
- sipDeallocFunc td_dealloc;
-
- /* The cast function, 0 if a C struct. */
- sipCastFunc td_cast;
-
- /* The release function. */
- sipReleaseFunc td_release;
-
- /* The force convert to function, 0 if a C++ namespace. */
- sipForceConvertToFunc td_fcto;
-
- /* The convert to function. */
- sipConvertToFunc td_cto;
-
- /* Emit table for Qt signals. */
- struct _sipQtSignal *td_emit;
-
- /* The static instances. */
- sipInstancesDef td_instances;
-
- /* The next namespace extender. */
- struct _sipTypeDef *td_nsextender;
-} sipTypeDef;
-
-
-/*
- * The information describing an external type.
- */
-typedef struct _sipExternalTypeDef {
- /* The index into the type table. */
- int et_nr;
-
- /* The name of the type. */
- const char *et_name;
-} sipExternalTypeDef;
-
-
-/*
- * The information describing a mapped class.
- */
-typedef struct _sipMappedType {
- /* The corresponding C++ definition. */
- const char *mt_name;
-
- /* The release function. */
- sipReleaseFunc mt_release;
-
- /* The force convert to function. */
- sipForceConvertToFunc mt_fcto;
-
- /* The convert to function. */
- sipConvertToFunc mt_cto;
-
- /* The convert from function. */
- sipConvertFromFunc mt_cfrom;
-} sipMappedType;
-
-
-/*
- * Defines an entry in the module specific list of delayed dtor calls.
- */
-typedef struct _sipDelayedDtor {
- /* The C/C++ instance. */
- void *dd_ptr;
-
- /* The class name. */
- const char *dd_name;
-
- /* Non-zero if dd_ptr is a derived class instance. */
- int dd_isderived;
-
- /* Next in the list. */
- struct _sipDelayedDtor *dd_next;
-} sipDelayedDtor;
-
-
-/*
- * The information describing an imported module.
- */
-typedef struct _sipImportedModuleDef {
- /* The module name. */
- const char *im_name;
-
- /* The required version. */
- int im_version;
-
- /* The imported module. */
- struct _sipExportedModuleDef *im_module;
-} sipImportedModuleDef;
-
-
-/*
- * The main client module structure.
- */
-typedef struct _sipExportedModuleDef {
- /* The next in the list. */
- struct _sipExportedModuleDef *em_next;
-
- /* The SIP API minor version number. */
- unsigned em_api_minor;
-
- /* The module name. */
- const char *em_name;
-
- /* The module name as an object. */
- PyObject *em_nameobj;
-
- /* The module version. */
- int em_version;
-
- /* The imported modules. */
- sipImportedModuleDef *em_imports;
-
- /* The optional Qt support API. */
- struct _sipQtAPI *em_qt_api;
-
- /* The number of types. */
- int em_nrtypes;
-
- /* The table of type types. */
- struct _sipWrapperType **em_types;
-
- /* The table of external types. */
- sipExternalTypeDef *em_external;
-
- /* The table of mapped types. */
- sipMappedType **em_mappedtypes;
-
- /* The number of enums. */
- int em_nrenums;
-
- /* The table of enum types. */
- PyTypeObject **em_enums;
-
- /* The table of enum type data. */
- sipEnumDef *em_enumdefs;
-
- /* The number of members in global enums. */
- int em_nrenummembers;
-
- /* The table of members in global enums. */
- sipEnumMemberDef *em_enummembers;
-
- /* The table of typedefs. */
- sipTypedefDef *em_typedefs;
-
- /* The table of virtual handlers. */
- sipVirtHandlerFunc *em_virthandlers;
-
- /* The sub-class convertors. */
- sipSubClassConvertorDef *em_convertors;
-
- /* The static instances. */
- sipInstancesDef em_instances;
-
- /* The license. */
- struct _sipLicenseDef *em_license;
-
- /* The table of exception types. */
- PyObject **em_exceptions;
-
- /* The table of Python slot extenders. */
- sipPySlotExtenderDef *em_slotextend;
-
- /* The table of initialiser extenders. */
- sipInitExtenderDef *em_initextend;
-
- /* The delayed dtor handler. */
- void (*em_delayeddtors)(const sipDelayedDtor *);
-
- /* The list of delayed dtors. */
- sipDelayedDtor *em_ddlist;
-} sipExportedModuleDef;
-
-
-/*
- * The information describing a license to be added to a dictionary.
- */
-typedef struct _sipLicenseDef {
- /* The type of license. */
- const char *lc_type;
-
- /* The licensee. */
- const char *lc_licensee;
-
- /* The timestamp. */
- const char *lc_timestamp;
-
- /* The signature. */
- const char *lc_signature;
-} sipLicenseDef;
-
-
-/*
- * The information describing a void pointer instance to be added to a
- * dictionary.
- */
-typedef struct _sipVoidPtrInstanceDef {
- /* The void pointer name. */
- const char *vi_name;
-
- /* The void pointer value. */
- void *vi_val;
-} sipVoidPtrInstanceDef;
-
-
-/*
- * The information describing a char instance to be added to a dictionary.
- */
-typedef struct _sipCharInstanceDef {
- /* The char name. */
- const char *ci_name;
-
- /* The char value. */
- char ci_val;
-} sipCharInstanceDef;
-
-
-/*
- * The information describing a string instance to be added to a dictionary.
- */
-typedef struct _sipStringInstanceDef {
- /* The string name. */
- const char *si_name;
-
- /* The string value. */
- const char *si_val;
-} sipStringInstanceDef;
-
-
-/*
- * The information describing an int instance to be added to a dictionary.
- */
-typedef struct _sipIntInstanceDef {
- /* The int name. */
- const char *ii_name;
-
- /* The int value. */
- int ii_val;
-} sipIntInstanceDef;
-
-
-/*
- * The information describing a long instance to be added to a dictionary.
- */
-typedef struct _sipLongInstanceDef {
- /* The long name. */
- const char *li_name;
-
- /* The long value. */
- long li_val;
-} sipLongInstanceDef;
-
-
-/*
- * The information describing an unsigned long instance to be added to a
- * dictionary.
- */
-typedef struct _sipUnsignedLongInstanceDef {
- /* The unsigned long name. */
- const char *uli_name;
-
- /* The unsigned long value. */
- unsigned long uli_val;
-} sipUnsignedLongInstanceDef;
-
-
-/*
- * The information describing a long long instance to be added to a dictionary.
- */
-typedef struct _sipLongLongInstanceDef {
- /* The long long name. */
- const char *lli_name;
-
- /* The long long value. */
-#if defined(HAVE_LONG_LONG)
- PY_LONG_LONG lli_val;
-#else
- long lli_val;
-#endif
-} sipLongLongInstanceDef;
-
-
-/*
- * The information describing an unsigned long long instance to be added to a
- * dictionary.
- */
-typedef struct _sipUnsignedLongLongInstanceDef {
- /* The unsigned long long name. */
- const char *ulli_name;
-
- /* The unsigned long long value. */
-#if defined(HAVE_LONG_LONG)
- unsigned PY_LONG_LONG ulli_val;
-#else
- unsigned long ulli_val;
-#endif
-} sipUnsignedLongLongInstanceDef;
-
-
-/*
- * The information describing a double instance to be added to a dictionary.
- */
-typedef struct _sipDoubleInstanceDef {
- /* The double name. */
- const char *di_name;
-
- /* The double value. */
- double di_val;
-} sipDoubleInstanceDef;
-
-
-/*
- * The information describing a class instance to be added to a dictionary.
- */
-typedef struct _sipClassInstanceDef {
- /* The class instance name. */
- const char *ci_name;
-
- /* The actual instance. */
- void *ci_ptr;
-
- /* A pointer to the Python type. */
- struct _sipWrapperType **ci_type;
-
- /* The wrapping flags. */
- int ci_flags;
-} sipClassInstanceDef;
-
-
-/*
- * The information describing an enum instance to be added to a dictionary.
- */
-typedef struct _sipEnumInstanceDef {
- /* The enum instance name. */
- const char *ei_name;
-
- /* The enum value. */
- int ei_val;
-
- /* A pointer to the Python type. */
- PyTypeObject **ei_type;
-} sipEnumInstanceDef;
-
-
-/*
- * Define a mapping between a wrapped type identified by a string and the
- * corresponding Python type.
- */
-typedef struct _sipStringTypeClassMap {
- /* The type as a string. */
- const char *typeString;
-
- /* A pointer to the Python type. */
- struct _sipWrapperType **pyType;
-} sipStringTypeClassMap;
-
-
-/*
- * Define a mapping between a wrapped type identified by an integer and the
- * corresponding Python type.
- */
-typedef struct _sipIntTypeClassMap {
- /* The type as an integer. */
- int typeInt;
-
- /* A pointer to the Python type. */
- struct _sipWrapperType **pyType;
-} sipIntTypeClassMap;
-
-
-/*
- * A Python method's component parts. This allows us to re-create the method
- * without changing the reference counts of the components.
- */
-typedef struct _sipPyMethod {
- /* The function. */
- PyObject *mfunc;
-
- /* Self if it is a bound method. */
- PyObject *mself;
-
- /* The class. */
- PyObject *mclass;
-} sipPyMethod;
-
-
-/*
- * Cache a reference to a Python member function.
- */
-typedef struct _sipMethodCache {
- /* Method cache flags. */
- int mcflags;
-
- /* The method. */
- sipPyMethod pyMethod;
-} sipMethodCache;
-
-
-/*
- * A slot (in the Qt, rather than Python, sense).
- */
-typedef struct _sipSlot {
- /* Name if a Qt or Python signal. */
- char *name;
-
- /* Signal or Qt slot object. */
- PyObject *pyobj;
-
- /* Python slot method, pyobj is NULL. */
- sipPyMethod meth;
-
- /* A weak reference to the slot. */
- PyObject *weakSlot;
-} sipSlot;
-
-
-/*
- * An entry in a linked list of slots.
- */
-typedef struct _sipSlotList {
- /* The receiver. */
- sipSlot rx;
-
- /* Next in the list. */
- struct _sipSlotList *next;
-} sipSlotList;
-
-
-/*
- * A Python signal.
- */
-typedef struct _sipPySig {
- /* The name of the signal. */
- char *name;
-
- /* The list of receivers. */
- sipSlotList *rxlist;
-
- /* Next in the list. */
- struct _sipPySig *next;
-} sipPySig;
-
-
-/*
- * This defines a single dynamic signal argument type.
- */
-typedef struct _sipSigArg {
- /* The type. */
- sipSigArgType atype;
-
- union {
- /* The Python type for classes. */
- sipWrapperType *wt;
-
- /* The data for mapped types. */
- sipMappedType *mt;
-
- /* The Python type for named enums. */
- PyTypeObject *et;
- } u;
-} sipSigArg;
-
-
-/*
- * A parsed signal signature.
- */
-typedef struct _sipSignature {
- /* The number of arguments. */
- int sg_nrargs;
-
- /* The parsed arguments (heap). */
- sipSigArg *sg_args;
-
- /* The unparsed signature (heap). */
- char *sg_signature;
-
- /* The next in the list. */
- struct _sipSignature *sg_next;
-} sipSignature;
-
-
-/*
- * A connection to a universal slot.
- */
-typedef struct _sipSlotConnection {
- /* The transmitter TQObject. */
- void *sc_transmitter;
-
- /* The parsed signature. */
- const sipSignature *sc_signature;
-
- /* The slot. */
- sipSlot sc_slot;
-} sipSlotConnection;
-
-
-/*
- * Maps the name of a Qt signal to a wrapper function to emit it.
- */
-typedef struct _sipQtSignal {
- /* The signal name. */
- char *st_name;
-
- /* The emitter function. */
- sipEmitFunc st_emitfunc;
-} sipQtSignal;
-
-
-/*
- * The API exported by the SIP module, ie. pointers to all the data and
- * functions that can be used by generated code.
- */
-typedef struct _sipAPIDef {
- /*
- * This must be the first entry and it's signature must not change so that
- * version number mismatches can be detected and reported.
- */
- int (*api_export_module)(sipExportedModuleDef *client, unsigned api_major,
- unsigned api_minor, PyObject *mod_dict);
-
- /*
- * The following are part of the public API.
- */
- void (*api_bad_catcher_result)(PyObject *method);
- void (*api_bad_length_for_slice)(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen);
- PyObject *(*api_build_result)(int *isErr, const char *fmt, ...);
- PyObject *(*api_call_method)(int *isErr, PyObject *method, const char *fmt,
- ...);
- PyObject *(*api_class_name)(PyObject *self);
- PyObject *(*api_connect_rx)(PyObject *txObj, const char *sig,
- PyObject *rxObj, const char *slot, int type);
- SIP_SSIZE_T (*api_convert_from_sequence_index)(SIP_SSIZE_T idx,
- SIP_SSIZE_T len);
- int (*api_can_convert_to_instance)(PyObject *pyObj, sipWrapperType *type,
- int flags);
- int (*api_can_convert_to_mapped_type)(PyObject *pyObj,
- const sipMappedType *mt, int flags);
- void *(*api_convert_to_instance)(PyObject *pyObj, sipWrapperType *type,
- PyObject *transferObj, int flags, int *statep, int *iserrp);
- void *(*api_convert_to_mapped_type)(PyObject *pyObj,
- const sipMappedType *mt, PyObject *transferObj, int flags,
- int *statep, int *iserrp);
- void *(*api_force_convert_to_instance)(PyObject *pyObj,
- sipWrapperType *type, PyObject *transferObj, int flags,
- int *statep, int *iserrp);
- void *(*api_force_convert_to_mapped_type)(PyObject *pyObj,
- const sipMappedType *mt, PyObject *transferObj, int flags,
- int *statep, int *iserrp);
- void (*api_release_instance)(void *cpp, sipWrapperType *type, int state);
- void (*api_release_mapped_type)(void *cpp, const sipMappedType *mt,
- int state);
- PyObject *(*api_convert_from_instance)(void *cpp, sipWrapperType *type,
- PyObject *transferObj);
- PyObject *(*api_convert_from_new_instance)(void *cpp, sipWrapperType *type,
- PyObject *transferObj);
- PyObject *(*api_convert_from_mapped_type)(void *cpp,
- const sipMappedType *mt, PyObject *transferObj);
- void *(*api_convert_to_cpp)(PyObject *sipSelf, sipWrapperType *type,
- int *iserrp);
- int (*api_get_state)(PyObject *transferObj);
- const sipMappedType *(*api_find_mapped_type)(const char *type);
- PyObject *(*api_disconnect_rx)(PyObject *txObj, const char *sig,
- PyObject *rxObj, const char *slot);
- int (*api_emit_signal)(PyObject *self, const char *sig, PyObject *sigargs);
- void (*api_free)(void *mem);
- PyObject *(*api_get_sender)();
- PyObject *(*api_get_wrapper)(void *cppPtr, sipWrapperType *type);
- void *(*api_malloc)(size_t nbytes);
- sipWrapperType *(*api_map_int_to_class)(int typeInt,
- const sipIntTypeClassMap *map, int maplen);
- sipWrapperType *(*api_map_string_to_class)(const char *typeString,
- const sipStringTypeClassMap *map, int maplen);
- int (*api_parse_result)(int *isErr, PyObject *method, PyObject *res,
- const char *fmt, ...);
- void (*api_trace)(unsigned mask, const char *fmt, ...);
- void (*api_transfer)(PyObject *self, int toCpp);
- void (*api_transfer_back)(PyObject *self);
- void (*api_transfer_to)(PyObject *self, PyObject *owner);
- int (*api_wrapper_check)(PyObject *o);
- unsigned long (*api_long_as_unsigned_long)(PyObject *o);
- PyObject *(*api_convert_from_named_enum)(int eval, PyTypeObject *et);
-
- /*
- * The following may be used by Qt support code but no other handwritten
- * code.
- */
- PyObject *(*api_convert_from_void_ptr)(void *val);
- void (*api_free_connection)(sipSlotConnection *conn);
- int (*api_emit_to_slot)(sipSlot *slot, PyObject *sigargs);
- int (*api_same_connection)(sipSlotConnection *conn, void *tx,
- const char *sig, PyObject *rxObj, const char *slot);
- void *(*api_convert_rx)(sipWrapper *txSelf, const char *sigargs,
- PyObject *rxObj, const char *slot, const char **memberp);
-
- /*
- * The following are not part of the public API.
- */
- int (*api_parse_args)(int *argsParsedp, PyObject *sipArgs,
- const char *fmt, ...);
- int (*api_parse_pair)(int *argsParsedp, PyObject *arg0, PyObject *arg1,
- const char *fmt, ...);
- void (*api_common_ctor)(sipMethodCache *cache, int nrmeths);
- void (*api_common_dtor)(sipWrapper *sipSelf);
- void *(*api_convert_to_void_ptr)(PyObject *obj);
- void (*api_no_function)(int argsParsed, const char *func);
- void (*api_no_method)(int argsParsed, const char *classname,
- const char *method);
- void (*api_abstract_method)(const char *classname, const char *method);
- void (*api_bad_class)(const char *classname);
- void (*api_bad_set_type)(const char *classname, const char *var);
- void *(*api_get_cpp_ptr)(sipWrapper *w, sipWrapperType *type);
- void *(*api_get_complex_cpp_ptr)(sipWrapper *w);
- PyObject *(*api_is_py_method)(sip_gilstate_t *gil, sipMethodCache *pymc,
- sipWrapper *sipSelf, char *cname, char *mname);
- void (*api_call_hook)(const char *hookname);
- void (*api_start_thread)(void);
- void (*api_end_thread)(void);
- void (*api_raise_unknown_exception)(void);
- void (*api_raise_class_exception)(sipWrapperType *type, void *ptr);
- void (*api_raise_sub_class_exception)(sipWrapperType *type, void *ptr);
- int (*api_add_class_instance)(PyObject *dict, const char *name,
- void *cppPtr, sipWrapperType *wt);
- int (*api_add_enum_instance)(PyObject *dict, const char *name, int value,
- PyTypeObject *type);
- void (*api_bad_operator_arg)(PyObject *self, PyObject *arg,
- sipPySlotType st);
- PyObject *(*api_pyslot_extend)(sipExportedModuleDef *mod, sipPySlotType st,
- sipWrapperType *type, PyObject *arg0, PyObject *arg1);
- void (*api_add_delayed_dtor)(sipWrapper *w);
- int (*api_add_mapped_type_instance)(PyObject *dict, const char *name,
- void *cppPtr, const sipMappedType *mt);
-
- /*
- * The following are part of the public API.
- */
- int (*api_export_symbol)(const char *name, void *sym);
- void *(*api_import_symbol)(const char *name);
-
- /*
- * The following may be used by Qt support code but no other handwritten
- * code.
- */
- int (*api_register_int_types)(PyObject *args);
- sipSignature *(*api_parse_signature)(const char *sig);
-
- /*
- * The following are part of the public API.
- */
- sipWrapperType *(*api_find_class)(const char *type);
- PyTypeObject *(*api_find_named_enum)(const char *type);
-
- /*
- * The following are not part of the public API.
- */
- char (*api_string_as_char)(PyObject *obj);
-#if defined(HAVE_WCHAR_H)
- wchar_t (*api_unicode_as_wchar)(PyObject *obj);
- wchar_t *(*api_unicode_as_wstring)(PyObject *obj);
-#else
- int (*api_unicode_as_wchar)(PyObject *obj);
- int *(*api_unicode_as_wstring)(PyObject *obj);
-#endif
-} sipAPIDef;
-
-
-/*
- * The API implementing the optional Qt support.
- */
-typedef struct _sipQtAPI {
- struct _sipWrapperType **qt_qobject;
- int (*qt_is_qt_signal)(void *, const char *);
- void *(*qt_create_universal_signal_shortcut)(void *, const char *,
- const char **);
- void *(*qt_create_universal_signal)(void *, const struct _sipSignature *);
- void *(*qt_find_universal_signal_shortcut)(void *, const char *,
- const char **);
- void *(*qt_find_universal_signal)(void *, const struct _sipSignature *);
- int (*qt_emit_signal_shortcut)(void *, const char *, PyObject *);
- int (*qt_emit_signal)(void *, const struct _sipSignature *, PyObject *);
- void *(*qt_create_universal_slot)(struct _sipWrapper *,
- struct _sipSlotConnection *, const char **);
- void (*qt_destroy_universal_slot)(void *);
- void *(*qt_find_slot)(void *, const char *, PyObject *, const char *,
- const char **);
- int (*qt_connect)(void *, const char *, void *, const char *, int);
- int (*qt_disconnect)(void *, const char *, void *, const char *);
- int (*qt_signals_blocked)(void *);
- const void *(*qt_get_sender)();
- void (*qt_forget_sender)();
- int (*qt_same_name)(const char *, const char *);
- sipSlotConnection *(*qt_find_connection)(void *, void **);
-} sipQtAPI;
-
-
-/*
- * These are flags that can be passed to sipCanConvertToInstance(),
- * sipConvertToInstance() and sipForceConvertToInstance().
- */
-#define SIP_NOT_NONE 0x01 /* Disallow None. */
-#define SIP_NO_CONVERTORS 0x02 /* Disable any type convertors. */
-
-
-/*
- * These are the state flags returned by %ConvertToTypeCode. Note that these
- * share the same "namespace" as the flags below.
- */
-#define SIP_TEMPORARY 0x0001 /* A temporary instance. */
-#define SIP_DERIVED_CLASS 0x0002 /* The instance is derived. */
-
-
-/*
- * Useful macros, not part of the public API.
- */
-#define SIP_PY_OWNED 0x0004 /* Owned by Python. */
-#define SIP_INDIRECT 0x0008 /* If there is a level of indirection. */
-#define SIP_ACCFUNC 0x0010 /* If there is an access function. */
-#define SIP_NOT_IN_MAP 0x0020 /* If Python object not in the map. */
-#define SIP_SHARE_MAP 0x0040 /* If the map slot might be occupied. */
-#define SIP_CPP_HAS_REF 0x0080 /* If C/C++ has a reference. */
-
-#define sipIsPyOwned(w) ((w)->flags & SIP_PY_OWNED)
-#define sipSetPyOwned(w) ((w)->flags |= SIP_PY_OWNED)
-#define sipResetPyOwned(w) ((w)->flags &= ~SIP_PY_OWNED)
-#define sipIsDerived(w) ((w)->flags & SIP_DERIVED_CLASS)
-#define sipIsIndirect(w) ((w)->flags & SIP_INDIRECT)
-#define sipIsAccessFunc(w) ((w)->flags & SIP_ACCFUNC)
-#define sipNotInMap(w) ((w)->flags & SIP_NOT_IN_MAP)
-#define sipCppHasRef(w) ((w)->flags & SIP_CPP_HAS_REF)
-#define sipSetCppHasRef(w) ((w)->flags |= SIP_CPP_HAS_REF)
-#define sipResetCppHasRef(w) ((w)->flags &= ~SIP_CPP_HAS_REF)
-
-
-#define SIP_TYPE_ABSTRACT 0x0001 /* If the type is abstract. */
-#define SIP_TYPE_SCC 0x0002 /* If the type is subject to sub-class convertors. */
-#define SIP_TYPE_FLAGS_SHIFT 8 /* The user type flags shift. */
-#define SIP_TYPE_FLAGS_MASK 0x0f00 /* The user type flags mask. */
-
-#define sipTypeIsAbstract(wt) ((wt)->type->td_flags & SIP_TYPE_ABSTRACT)
-#define sipTypeHasSCC(wt) ((wt)->type->td_flags & SIP_TYPE_SCC)
-#define sipTypeFlags(wt) (((wt)->type->td_flags & SIP_TYPE_FLAGS_MASK) >> SIP_TYPE_FLAGS_SHIFT)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/python/sip/siplib/sipint.h b/python/sip/siplib/sipint.h
deleted file mode 100644
index 0a8f2459..00000000
--- a/python/sip/siplib/sipint.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * This file defines the SIP library internal interfaces.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#ifndef _SIPINT_H
-#define _SIPINT_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef TRUE
-#define TRUE 1
-
-#undef FALSE
-#define FALSE 0
-
-
-/*
- * This defines a single entry in an object map's hash table.
- */
-typedef struct
-{
- void *key; /* The C/C++ address. */
- sipWrapper *first; /* The first object at this address. */
-} sipHashEntry;
-
-
-/*
- * This defines the interface to a hash table class for mapping C/C++ addresses
- * to the corresponding wrapped Python object.
- */
-typedef struct
-{
- int primeIdx; /* Index into table sizes. */
- unsigned long size; /* Size of hash table. */
- unsigned long unused; /* Nr. unused in hash table. */
- unsigned long stale; /* Nr. stale in hash table. */
- sipHashEntry *hash_array; /* Current hash table. */
-} sipObjectMap;
-
-
-extern PyInterpreterState *sipInterpreter; /* The interpreter. */
-
-
-extern sipQtAPI *sipQtSupport; /* The Qt support API. */
-extern sipWrapperType *sipQObjectClass; /* The Python TQObject class. */
-
-void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs,
- PyObject *rxObj, const char *slot,
- const char **memberp);
-void *sipGetRx(sipWrapper *txSelf,const char *sigargs,PyObject *rxObj,
- const char *slot,const char **memberp);
-int sip_api_emit_signal(PyObject *self,const char *sig,PyObject *sigargs);
-PyObject *sip_api_get_sender();
-PyObject *sip_api_connect_rx(PyObject *txObj,const char *sig,
- PyObject *rxObj,const char *slot, int type);
-PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig,
- PyObject *rxObj,const char *slot);
-sipSignature *sip_api_parse_signature(const char *sig);
-
-
-/*
- * These are part of the SIP API but are also used within the SIP module.
- */
-void *sip_api_malloc(size_t nbytes);
-void sip_api_free(void *mem);
-void *sip_api_get_cpp_ptr(sipWrapper *w,sipWrapperType *type);
-PyObject *sip_api_convert_from_instance(void *cppPtr, sipWrapperType *type,
- PyObject *transferObj);
-void sip_api_start_thread(void);
-void sip_api_end_thread(void);
-PyObject *sip_api_convert_from_void_ptr(void *val);
-PyObject *sip_api_convert_from_named_enum(int eval, PyTypeObject *et);
-int sip_api_wrapper_check(PyObject *o);
-void sip_api_free_connection(sipSlotConnection *conn);
-int sip_api_emit_to_slot(sipSlot *slot, PyObject *sigargs);
-int sip_api_same_connection(sipSlotConnection *conn, void *tx, const char *sig,
- PyObject *rxObj, const char *slot);
-
-
-/*
- * These are not part of the SIP API but are used within the SIP module.
- */
-void sipFreeSlotList(sipSlotList *rx);
-void sipSaveMethod(sipPyMethod *pm,PyObject *meth);
-void *sipGetPending(sipWrapper **op, int *fp);
-PyObject *sipWrapSimpleInstance(void *cppPtr, sipWrapperType *type,
- sipWrapper *owner, int initflags);
-int sipLambdaSlot(PyObject *slotObj);
-
-void sipOMInit(sipObjectMap *om);
-void sipOMFinalise(sipObjectMap *om);
-sipWrapper *sipOMFindObject(sipObjectMap *om,void *key,sipWrapperType *type);
-void sipOMAddObject(sipObjectMap *om,sipWrapper *val);
-int sipOMRemoveObject(sipObjectMap *om,sipWrapper *val);
-
-void sipSetBool(void *ptr,int val);
-
-void *sipGetAddress(sipWrapper *w);
-void sipFindSigArgType(const char *name, size_t len, sipSigArg *at, int indir);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/python/sip/siplib/siplib.c b/python/sip/siplib/siplib.c
deleted file mode 100644
index a715e830..00000000
--- a/python/sip/siplib/siplib.c
+++ /dev/null
@@ -1,7902 +0,0 @@
-/*
- * SIP library code.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#include <Python.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "sip.h"
-#include "sipint.h"
-
-
-/*
- * These are the functions that make up the public and private SIP API.
- */
-static void sip_api_bad_catcher_result(PyObject *method);
-static void sip_api_bad_length_for_slice(SIP_SSIZE_T seqlen,
- SIP_SSIZE_T slicelen);
-static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...);
-static PyObject *sip_api_call_method(int *isErr, PyObject *method,
- const char *fmt, ...);
-static PyObject *sip_api_class_name(PyObject *self);
-static SIP_SSIZE_T sip_api_convert_from_sequence_index(SIP_SSIZE_T idx,
- SIP_SSIZE_T len);
-static int sip_api_can_convert_to_instance(PyObject *pyObj,
- sipWrapperType *type, int flags);
-static int sip_api_can_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt, int flags);
-static void *sip_api_convert_to_instance(PyObject *pyObj, sipWrapperType *type,
- PyObject *transferObj, int flags, int *statep, int *iserrp);
-static void *sip_api_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt, PyObject *transferObj, int flags, int *statep,
- int *iserrp);
-static void *sip_api_force_convert_to_instance(PyObject *pyObj,
- sipWrapperType *type, PyObject *transferObj, int flags, int *statep,
- int *iserrp);
-static void *sip_api_force_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt, PyObject *transferObj, int flags, int *statep,
- int *iserrp);
-static void sip_api_release_instance(void *cpp, sipWrapperType *type,
- int state);
-static void sip_api_release_mapped_type(void *cpp, const sipMappedType *mt,
- int state);
-static PyObject *sip_api_convert_from_new_instance(void *cpp,
- sipWrapperType *type, PyObject *transferObj);
-static PyObject *sip_api_convert_from_mapped_type(void *cpp,
- const sipMappedType *mt, PyObject *transferObj);
-static void *sip_api_convert_to_cpp(PyObject *sipSelf, sipWrapperType *type,
- int *iserrp);
-static int sip_api_get_state(PyObject *transferObj);
-static const sipMappedType *sip_api_find_mapped_type(const char *type);
-static PyObject *sip_api_get_wrapper(void *cppPtr, sipWrapperType *type);
-static sipWrapperType *sip_api_map_int_to_class(int typeInt,
- const sipIntTypeClassMap *map, int maplen);
-static sipWrapperType *sip_api_map_string_to_class(const char *typeString,
- const sipStringTypeClassMap *map, int maplen);
-static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res,
- const char *fmt, ...);
-static void sip_api_trace(unsigned mask,const char *fmt,...);
-static void sip_api_transfer(PyObject *self, int toCpp);
-static void sip_api_transfer_back(PyObject *self);
-static void sip_api_transfer_to(PyObject *self, PyObject *owner);
-static int sip_api_export_module(sipExportedModuleDef *client,
- unsigned api_major, unsigned api_minor, PyObject *mod_dict);
-static int sip_api_parse_args(int *argsParsedp, PyObject *sipArgs,
- const char *fmt, ...);
-static int sip_api_parse_pair(int *argsParsedp, PyObject *sipArg0,
- PyObject *sipArg1, const char *fmt, ...);
-static void sip_api_common_ctor(sipMethodCache *cache, int nrmeths);
-static void sip_api_common_dtor(sipWrapper *sipSelf);
-static void *sip_api_convert_to_void_ptr(PyObject *obj);
-static void sip_api_no_function(int argsParsed, const char *func);
-static void sip_api_no_method(int argsParsed, const char *classname,
- const char *method);
-static void sip_api_abstract_method(const char *classname, const char *method);
-static void sip_api_bad_class(const char *classname);
-static void sip_api_bad_set_type(const char *classname, const char *var);
-static void *sip_api_get_complex_cpp_ptr(sipWrapper *w);
-static PyObject *sip_api_is_py_method(sip_gilstate_t *gil,
- sipMethodCache *pymc, sipWrapper *sipSelf, char *cname, char *mname);
-static void sip_api_call_hook(const char *hookname);
-static void sip_api_raise_unknown_exception(void);
-static void sip_api_raise_class_exception(sipWrapperType *type, void *ptr);
-static void sip_api_raise_sub_class_exception(sipWrapperType *type, void *ptr);
-static int sip_api_add_class_instance(PyObject *dict, const char *name,
- void *cppPtr, sipWrapperType *wt);
-static int sip_api_add_mapped_type_instance(PyObject *dict, const char *name,
- void *cppPtr, const sipMappedType *mt);
-static int sip_api_add_enum_instance(PyObject *dict, const char *name,
- int value, PyTypeObject *type);
-static void sip_api_bad_operator_arg(PyObject *self, PyObject *arg,
- sipPySlotType st);
-static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod,
- sipPySlotType st, sipWrapperType *type, PyObject *arg0,
- PyObject *arg1);
-static void sip_api_add_delayed_dtor(sipWrapper *w);
-static unsigned long sip_api_long_as_unsigned_long(PyObject *o);
-static int sip_api_export_symbol(const char *name, void *sym);
-static void *sip_api_import_symbol(const char *name);
-static int sip_api_register_int_types(PyObject *args);
-static sipWrapperType *sip_api_find_class(const char *type);
-static PyTypeObject *sip_api_find_named_enum(const char *type);
-static char sip_api_string_as_char(PyObject *obj);
-#if defined(HAVE_WCHAR_H)
-static wchar_t sip_api_unicode_as_wchar(PyObject *obj);
-static wchar_t *sip_api_unicode_as_wstring(PyObject *obj);
-#else
-static int sip_api_unicode_as_wchar(PyObject *obj);
-static int *sip_api_unicode_as_wstring(PyObject *obj);
-#endif
-
-
-/*
- * The data structure that represents the SIP API.
- */
-static const sipAPIDef sip_api = {
- /* This must be first. */
- sip_api_export_module,
- /*
- * The following are part of the public API.
- */
- sip_api_bad_catcher_result,
- sip_api_bad_length_for_slice,
- sip_api_build_result,
- sip_api_call_method,
- sip_api_class_name,
- sip_api_connect_rx,
- sip_api_convert_from_sequence_index,
- sip_api_can_convert_to_instance,
- sip_api_can_convert_to_mapped_type,
- sip_api_convert_to_instance,
- sip_api_convert_to_mapped_type,
- sip_api_force_convert_to_instance,
- sip_api_force_convert_to_mapped_type,
- sip_api_release_instance,
- sip_api_release_mapped_type,
- sip_api_convert_from_instance,
- sip_api_convert_from_new_instance,
- sip_api_convert_from_mapped_type,
- sip_api_convert_to_cpp,
- sip_api_get_state,
- sip_api_find_mapped_type,
- sip_api_disconnect_rx,
- sip_api_emit_signal,
- sip_api_free,
- sip_api_get_sender,
- sip_api_get_wrapper,
- sip_api_malloc,
- sip_api_map_int_to_class,
- sip_api_map_string_to_class,
- sip_api_parse_result,
- sip_api_trace,
- sip_api_transfer,
- sip_api_transfer_back,
- sip_api_transfer_to,
- sip_api_wrapper_check,
- sip_api_long_as_unsigned_long,
- /*
- * The following may be used by Qt support code but by no other handwritten
- * code.
- */
- sip_api_convert_from_named_enum,
- sip_api_convert_from_void_ptr,
- sip_api_free_connection,
- sip_api_emit_to_slot,
- sip_api_same_connection,
- sip_api_convert_rx,
- /*
- * The following are not part of the public API.
- */
- sip_api_parse_args,
- sip_api_parse_pair,
- sip_api_common_ctor,
- sip_api_common_dtor,
- sip_api_convert_to_void_ptr,
- sip_api_no_function,
- sip_api_no_method,
- sip_api_abstract_method,
- sip_api_bad_class,
- sip_api_bad_set_type,
- sip_api_get_cpp_ptr,
- sip_api_get_complex_cpp_ptr,
- sip_api_is_py_method,
- sip_api_call_hook,
- sip_api_start_thread,
- sip_api_end_thread,
- sip_api_raise_unknown_exception,
- sip_api_raise_class_exception,
- sip_api_raise_sub_class_exception,
- sip_api_add_class_instance,
- sip_api_add_enum_instance,
- sip_api_bad_operator_arg,
- sip_api_pyslot_extend,
- sip_api_add_delayed_dtor,
- sip_api_add_mapped_type_instance,
- /*
- * The following are part of the public API.
- */
- sip_api_export_symbol,
- sip_api_import_symbol,
- /*
- * The following may be used by Qt support code but by no other handwritten
- * code.
- */
- sip_api_register_int_types,
- sip_api_parse_signature,
- /*
- * The following are part of the public API.
- */
- sip_api_find_class,
- sip_api_find_named_enum,
- /*
- * The following are not part of the public API.
- */
- sip_api_string_as_char,
- sip_api_unicode_as_wchar,
- sip_api_unicode_as_wstring,
-};
-
-
-#define PARSE_OK 0x00000000 /* Parse is Ok so far. */
-#define PARSE_MANY 0x10000000 /* Too many arguments. */
-#define PARSE_FEW 0x20000000 /* Too few arguments. */
-#define PARSE_TYPE 0x30000000 /* Argument with a bad type. */
-#define PARSE_UNBOUND 0x40000000 /* Unbound method. */
-#define PARSE_FORMAT 0x50000000 /* Bad format character. */
-#define PARSE_RAISED 0x60000000 /* Exception already raised. */
-#define PARSE_STICKY 0x80000000 /* The error sticks. */
-#define PARSE_MASK 0xf0000000
-
-/*
- * Note that some of the following flags safely share values because they
- * cannot be used at the same time.
- */
-#define FORMAT_DEREF 0x01 /* The pointer will be dereferenced. */
-#define FORMAT_FACTORY 0x02 /* Implement /Factory/ in a VH. */
-#define FORMAT_TRANSFER 0x02 /* Implement /Transfer/. */
-#define FORMAT_NO_STATE 0x04 /* Don't return the C/C++ state. */
-#define FORMAT_TRANSFER_BACK 0x04 /* Implement /TransferBack/. */
-#define FORMAT_GET_WRAPPER 0x08 /* Implement /GetWrapper/. */
-#define FORMAT_NO_CONVERTORS 0x10 /* Suppress any convertors. */
-#define FORMAT_TRANSFER_THIS 0x20 /* Support for /TransferThis/. */
-
-#define SIP_MC_FOUND 0x01 /* If we have looked for the method. */
-#define SIP_MC_ISMETH 0x02 /* If we looked and there was one. */
-
-#define sipFoundMethod(m) ((m)->mcflags & SIP_MC_FOUND)
-#define sipSetFoundMethod(m) ((m)->mcflags |= SIP_MC_FOUND)
-#define sipIsMethod(m) ((m)->mcflags & SIP_MC_ISMETH)
-#define sipSetIsMethod(m) ((m)->mcflags |= SIP_MC_ISMETH)
-
-
-/*
- * An entry in a linked list of name/symbol pairs.
- */
-typedef struct _sipSymbol {
- const char *name; /* The name. */
- void *symbol; /* The symbol. */
- struct _sipSymbol *next; /* The next in the list. */
-} sipSymbol;
-
-
-/*
- * An entry in a linked list of Python objects.
- */
-typedef struct _sipPyObject {
- PyObject *object; /* The Python object. */
- struct _sipPyObject *next; /* The next in the list. */
-} sipPyObject;
-
-
-static PyTypeObject sipWrapperType_Type;
-static sipWrapperType sipWrapper_Type;
-static PyTypeObject sipVoidPtr_Type;
-
-PyInterpreterState *sipInterpreter = NULL;
-sipQtAPI *sipQtSupport = NULL;
-sipWrapperType *sipQObjectClass;
-sipPyObject *sipRegisteredIntTypes = NULL;
-sipSymbol *sipSymbolList = NULL;
-
-
-/*
- * Various strings as Python objects created as and when needed.
- */
-static PyObject *licenseName = NULL;
-static PyObject *licenseeName = NULL;
-static PyObject *typeName = NULL;
-static PyObject *timestampName = NULL;
-static PyObject *signatureName = NULL;
-
-static sipObjectMap cppPyMap; /* The C/C++ to Python map. */
-static sipExportedModuleDef *clientList = NULL; /* List of registered clients. */
-static unsigned traceMask = 0; /* The current trace mask. */
-
-static sipTypeDef *currentType = NULL; /* The type being created. */
-
-
-static void addSlots(sipWrapperType *wt, sipTypeDef *td);
-static void initSlots(PyTypeObject *to, PyNumberMethods *nb,
- PySequenceMethods *sq, PyMappingMethods *mp, sipPySlotDef *slots,
- int force);
-static void *findSlot(PyObject *self, sipPySlotType st);
-static void *findSlotInType(sipTypeDef *td, sipPySlotType st);
-static int objobjargprocSlot(PyObject *self, PyObject *arg1, PyObject *arg2,
- sipPySlotType st);
-static int ssizeobjargprocSlot(PyObject *self, SIP_SSIZE_T arg1,
- PyObject *arg2, sipPySlotType st);
-static PyObject *buildObject(PyObject *tup, const char *fmt, va_list va);
-static int parsePass1(sipWrapper **selfp, int *selfargp, int *argsParsedp,
- PyObject *sipArgs, const char *fmt, va_list va);
-static int parsePass2(sipWrapper *self, int selfarg, int nrargs,
- PyObject *sipArgs, const char *fmt, va_list va);
-static int getSelfFromArgs(sipWrapperType *type, PyObject *args, int argnr,
- sipWrapper **selfp);
-static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm);
-static PyObject *handleGetLazyAttr(PyObject *nameobj, sipWrapperType *wt,
- sipWrapper *w);
-static int handleSetLazyAttr(PyObject *nameobj, PyObject *valobj,
- sipWrapperType *wt, sipWrapper *w);
-static int getNonStaticVariables(sipWrapperType *wt, sipWrapper *w,
- PyObject **ndict);
-static void findLazyAttr(sipWrapperType *wt, char *name, PyMethodDef **pmdp,
- sipEnumMemberDef **enmp, PyMethodDef **vmdp, sipTypeDef **in);
-static int compareMethodName(const void *key, const void *el);
-static int compareEnumMemberName(const void *key, const void *el);
-static int checkPointer(void *ptr);
-static void *cast_cpp_ptr(void *ptr, sipWrapperType *src_type,
- sipWrapperType *dst_type);
-static void badArgs(int argsParsed, const char *classname, const char *method);
-static void finalise(void);
-static sipWrapperType *createType(sipExportedModuleDef *client,
- sipTypeDef *type, PyObject *mod_dict);
-static PyTypeObject *createEnum(sipExportedModuleDef *client, sipEnumDef *ed,
- PyObject *mod_dict);
-static const char *getBaseName(const char *name);
-static PyObject *getBaseNameObject(const char *name);
-static PyObject *createTypeDict(PyObject *mname);
-static sipExportedModuleDef *getClassModule(sipEncodedClassDef *enc,
- sipExportedModuleDef *em);
-static sipWrapperType *getClassType(sipEncodedClassDef *enc,
- sipExportedModuleDef *em);
-static sipWrapperType *convertSubClass(sipWrapperType *type, void **cppPtr);
-static void *getPtrTypeDef(sipWrapper *self, sipTypeDef **td);
-static int addInstances(PyObject *dict, sipInstancesDef *id);
-static int addVoidPtrInstances(PyObject *dict, sipVoidPtrInstanceDef *vi);
-static int addCharInstances(PyObject *dict, sipCharInstanceDef *ci);
-static int addStringInstances(PyObject *dict, sipStringInstanceDef *si);
-static int addIntInstances(PyObject *dict, sipIntInstanceDef *ii);
-static int addLongInstances(PyObject *dict, sipLongInstanceDef *li);
-static int addUnsignedLongInstances(PyObject *dict,
- sipUnsignedLongInstanceDef *uli);
-static int addLongLongInstances(PyObject *dict, sipLongLongInstanceDef *lli);
-static int addUnsignedLongLongInstances(PyObject *dict,
- sipUnsignedLongLongInstanceDef *ulli);
-static int addDoubleInstances(PyObject *dict, sipDoubleInstanceDef *di);
-static int addEnumInstances(PyObject *dict, sipEnumInstanceDef *ei);
-static int addSingleEnumInstance(PyObject *dict, const char *name, int value,
- PyTypeObject *type);
-static int addClassInstances(PyObject *dict, sipClassInstanceDef *ci);
-static int addSingleClassInstance(PyObject *dict, const char *name,
- void *cppPtr, sipWrapperType *wt, int initflags);
-static int addLicense(PyObject *dict, sipLicenseDef *lc);
-static PyObject *cast(PyObject *self, PyObject *args);
-static PyObject *callDtor(PyObject *self, PyObject *args);
-static PyObject *isDeleted(PyObject *self, PyObject *args);
-static PyObject *setDeleted(PyObject *self, PyObject *args);
-static PyObject *setTraceMask(PyObject *self, PyObject *args);
-static PyObject *wrapInstance(PyObject *self, PyObject *args);
-static PyObject *unwrapInstance(PyObject *self, PyObject *args);
-static PyObject *transfer(PyObject *self, PyObject *args);
-static PyObject *transferBack(PyObject *self, PyObject *args);
-static PyObject *transferTo(PyObject *self, PyObject *args);
-static int sipWrapperType_Check(PyObject *op);
-static void addToParent(sipWrapper *self, sipWrapper *owner);
-static void removeFromParent(sipWrapper *self);
-static sipWrapperType *findClass(sipExportedModuleDef *emd, const char *name,
- size_t len);
-static int findClassArg(sipExportedModuleDef *emd, const char *name,
- size_t len, sipSigArg *at, int indir);
-static int findMtypeArg(sipMappedType **mttab, const char *name, size_t len,
- sipSigArg *at, int indir);
-static PyTypeObject *findEnum(sipExportedModuleDef *emd, const char *name,
- size_t len);
-static int findEnumArg(sipExportedModuleDef *emd, const char *name, size_t len,
- sipSigArg *at, int indir);
-static int sameScopedName(const char *pyname, const char *name, size_t len);
-static int nameEq(const char *with, const char *name, size_t len);
-static int isExactWrappedType(sipWrapperType *wt);
-static void release(void *addr, sipTypeDef *td, int state);
-static void callPyDtor(sipWrapper *self);
-static int qt_and_sip_api_3_4(void);
-static int visitSlot(sipSlot *slot, visitproc visit, void *arg);
-static void clearAnyLambda(sipSlot *slot);
-static int parseCharArray(PyObject *obj, char **ap, int *aszp);
-static int parseChar(PyObject *obj, char *ap);
-static int parseCharString(PyObject *obj, char **ap);
-#if defined(HAVE_WCHAR_H)
-static int parseWCharArray(PyObject *obj, wchar_t **ap, int *aszp);
-static int parseWChar(PyObject *obj, wchar_t *ap);
-static int parseWCharString(PyObject *obj, wchar_t **ap);
-#else
-static void raiseNoWChar();
-#endif
-
-
-/*
- * The Python module initialisation function.
- */
-#if defined(SIP_STATIC_MODULE)
-void initsip(void)
-#else
-PyMODINIT_FUNC initsip(void)
-#endif
-{
- static PyMethodDef methods[] = {
- {"cast", cast, METH_VARARGS, NULL},
- {"delete", callDtor, METH_VARARGS, NULL},
- {"isdeleted", isDeleted, METH_VARARGS, NULL},
- {"setdeleted", setDeleted, METH_VARARGS, NULL},
- {"settracemask", setTraceMask, METH_VARARGS, NULL},
- {"transfer", transfer, METH_VARARGS, NULL},
- {"transferback", transferBack, METH_VARARGS, NULL},
- {"transferto", transferTo, METH_VARARGS, NULL},
- {"wrapinstance", wrapInstance, METH_VARARGS, NULL},
- {"unwrapinstance", unwrapInstance, METH_VARARGS, NULL},
- {NULL, NULL, 0, NULL}
- };
-
- int rc;
- PyObject *mod, *mod_dict, *obj;
-
-#ifdef WITH_THREAD
- PyEval_InitThreads();
-#endif
-
- /* Initialise the types. */
- sipWrapperType_Type.tp_base = &PyType_Type;
-
- if (PyType_Ready(&sipWrapperType_Type) < 0)
- Py_FatalError("sip: Failed to initialise sip.wrappertype type");
-
- if (PyType_Ready((PyTypeObject *)&sipWrapper_Type) < 0)
- Py_FatalError("sip: Failed to initialise sip.wrapper type");
-
- if (PyType_Ready(&sipVoidPtr_Type) < 0)
- Py_FatalError("sip: Failed to initialise sip.voidptr type");
-
- mod = Py_InitModule("sip", methods);
- mod_dict = PyModule_GetDict(mod);
-
- /* Publish the SIP API. */
- if ((obj = PyCObject_FromVoidPtr((void *)&sip_api, NULL)) == NULL)
- Py_FatalError("sip: Failed to create _C_API object");
-
- rc = PyDict_SetItemString(mod_dict, "_C_API", obj);
- Py_DECREF(obj);
-
- if (rc < 0)
- Py_FatalError("sip: Failed to add _C_API object to module dictionary");
-
- /* Add the SIP version number, but don't worry about errors. */
- if ((obj = PyInt_FromLong(SIP_VERSION)) != NULL)
- {
- PyDict_SetItemString(mod_dict, "SIP_VERSION", obj);
- Py_DECREF(obj);
- }
-
- if ((obj = PyString_FromString(SIP_VERSION_STR)) != NULL)
- {
- PyDict_SetItemString(mod_dict, "SIP_VERSION_STR", obj);
- Py_DECREF(obj);
- }
-
- /* Add the type objects, but don't worry about errors. */
- PyDict_SetItemString(mod_dict, "wrappertype", (PyObject *)&sipWrapperType_Type);
- PyDict_SetItemString(mod_dict, "wrapper", (PyObject *)&sipWrapper_Type);
- PyDict_SetItemString(mod_dict, "voidptr", (PyObject *)&sipVoidPtr_Type);
-
- /* Initialise the module if it hasn't already been done. */
- if (sipInterpreter == NULL)
- {
- Py_AtExit(finalise);
-
- /* Initialise the object map. */
- sipOMInit(&cppPyMap);
-
- sipQtSupport = NULL;
-
- /*
- * Get the current interpreter. This will be shared between all
- * threads.
- */
- sipInterpreter = PyThreadState_Get()->interp;
- }
-}
-
-
-/*
- * Display a printf() style message to stderr according to the current trace
- * mask.
- */
-static void sip_api_trace(unsigned mask, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap,fmt);
-
- if (mask & traceMask)
- vfprintf(stderr, fmt, ap);
-
- va_end(ap);
-}
-
-
-/*
- * Set the trace mask.
- */
-static PyObject *setTraceMask(PyObject *self, PyObject *args)
-{
- unsigned new_mask;
-
- if (PyArg_ParseTuple(args, "I:settracemask", &new_mask))
- {
- traceMask = new_mask;
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return NULL;
-}
-
-
-/*
- * Transfer the ownership of an instance to C/C++.
- */
-static PyObject *transferTo(PyObject *self, PyObject *args)
-{
- PyObject *w, *owner;
-
- if (PyArg_ParseTuple(args, "O!O:transferto", &sipWrapper_Type, &w, &owner))
- {
- if (owner == Py_None)
- owner = NULL;
- else if (!sip_api_wrapper_check(owner))
- {
- PyErr_Format(PyExc_TypeError, "transferto() argument 2 must be sip.wrapper, not %s", owner->ob_type->tp_name);
- return NULL;
- }
-
- sip_api_transfer_to(w, owner);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return NULL;
-}
-
-
-/*
- * Transfer the ownership of an instance to Python.
- */
-static PyObject *transferBack(PyObject *self, PyObject *args)
-{
- PyObject *w;
-
- if (PyArg_ParseTuple(args, "O!:transferback", &sipWrapper_Type, &w))
- {
- sip_api_transfer_back(w);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return NULL;
-}
-
-
-/*
- * Transfer the ownership of an instance. This is deprecated.
- */
-static PyObject *transfer(PyObject *self, PyObject *args)
-{
- PyObject *w;
- int toCpp;
-
- if (PyArg_ParseTuple(args, "O!i:transfer", &sipWrapper_Type, &w, &toCpp))
- {
- if (toCpp)
- sip_api_transfer_to(w, NULL);
- else
- sip_api_transfer_back(w);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return NULL;
-}
-
-
-/*
- * Cast an instance to one of it's sub or super-classes by returning a new
- * Python object with the superclass type wrapping the same C++ instance.
- */
-static PyObject *cast(PyObject *self, PyObject *args)
-{
- sipWrapper *w;
- sipWrapperType *wt, *type;
- void *addr;
- PyTypeObject *ft, *tt;
-
- if (!PyArg_ParseTuple(args, "O!O!:cast", &sipWrapper_Type, &w, &sipWrapperType_Type, &wt))
- return NULL;
-
- ft = ((PyObject *)w)->ob_type;
- tt = (PyTypeObject *)wt;
-
- if (ft == tt || PyType_IsSubtype(tt, ft))
- type = NULL;
- else if (PyType_IsSubtype(ft, tt))
- type = wt;
- else
- {
- PyErr_SetString(PyExc_TypeError, "argument 1 of sip.cast() must be an instance of a sub or super-type of argument 2");
- return NULL;
- }
-
- if ((addr = sip_api_get_cpp_ptr(w, type)) == NULL)
- return NULL;
-
- /*
- * We don't put this new object into the map so that the original object is
- * always found. It would also totally confuse the map logic.
- */
- return sipWrapSimpleInstance(addr, wt, NULL, (w->flags | SIP_NOT_IN_MAP) & ~SIP_PY_OWNED);
-}
-
-
-/*
- * Call an instance's dtor.
- */
-static PyObject *callDtor(PyObject *self, PyObject *args)
-{
- sipWrapper *w;
- void *addr;
- sipTypeDef *td;
-
- if (!PyArg_ParseTuple(args, "O!:delete", &sipWrapper_Type, &w))
- return NULL;
-
- addr = getPtrTypeDef(w, &td);
-
- if (checkPointer(addr) < 0)
- return NULL;
-
- /*
- * Transfer ownership to C++ so we don't try to release it again when the
- * Python object is garbage collected.
- */
- removeFromParent(w);
- sipResetPyOwned(w);
-
- release(addr, td, w->flags);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-/*
- * Check if an instance still exists without raising an exception.
- */
-static PyObject *isDeleted(PyObject *self, PyObject *args)
-{
- sipWrapper *w;
- PyObject *res;
-
- if (!PyArg_ParseTuple(args, "O!:isdeleted", &sipWrapper_Type, &w))
- return NULL;
-
- res = (sipGetAddress(w) == NULL ? Py_True : Py_False);
-
- Py_INCREF(res);
- return res;
-}
-
-
-/*
- * Mark an instance as having been deleted.
- */
-static PyObject *setDeleted(PyObject *self, PyObject *args)
-{
- sipWrapper *w;
-
- if (!PyArg_ParseTuple(args, "O!:setdeleted", &sipWrapper_Type, &w))
- return NULL;
-
- /*
- * Transfer ownership to C++ so we don't try to release it when the Python
- * object is garbage collected.
- */
- removeFromParent(w);
- sipResetPyOwned(w);
-
- w->u.cppPtr = NULL;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-/*
- * Unwrap an instance.
- */
-static PyObject *unwrapInstance(PyObject *self, PyObject *args)
-{
- sipWrapper *w;
-
- if (PyArg_ParseTuple(args, "O!:unwrapinstance", &sipWrapper_Type, &w))
- {
- void *addr;
-
- /*
- * We just get the pointer but don't try and cast it (which isn't
- * needed and wouldn't work with the way casts are currently
- * implemented if we are unwrapping something derived from a wrapped
- * class).
- */
- if ((addr = sip_api_get_cpp_ptr(w, NULL)) == NULL)
- return NULL;
-
- return PyLong_FromVoidPtr(addr);
- }
-
- return NULL;
-}
-
-
-/*
- * Wrap an instance.
- */
-static PyObject *wrapInstance(PyObject *self, PyObject *args)
-{
- unsigned long addr;
- sipWrapperType *wt;
-
- if (PyArg_ParseTuple(args, "kO!:wrapinstance", &addr, &sipWrapperType_Type, &wt))
- return sip_api_convert_from_instance((void *)addr, wt, NULL);
-
- return NULL;
-}
-
-
-/*
- * Register a client module. A negative value is returned and an exception
- * raised if there was an error. Not normally needed by handwritten code.
- */
-static int sip_api_export_module(sipExportedModuleDef *client,
- unsigned api_major, unsigned api_minor, PyObject *mod_dict)
-{
- sipExportedModuleDef *em;
- sipImportedModuleDef *im;
- sipSubClassConvertorDef *scc;
- sipWrapperType **mw;
- sipEnumMemberDef *emd;
- sipInitExtenderDef *ie;
- int i;
-
- /* Check that we can support it. */
-
- if (api_major != SIP_API_MAJOR_NR || api_minor > SIP_API_MINOR_NR)
- {
-#if SIP_API_MINOR_NR > 0
- PyErr_Format(PyExc_RuntimeError, "the sip module supports API v%d.0 to v%d.%d but the %s module requires API v%d.%d", SIP_API_MAJOR_NR, SIP_API_MAJOR_NR, SIP_API_MINOR_NR, client->em_name, api_major,api_minor);
-#else
- PyErr_Format(PyExc_RuntimeError, "the sip module supports API v%d.0 but the %s module requires API v%d.%d", SIP_API_MAJOR_NR, client->em_name, api_major,api_minor);
-#endif
-
- return -1;
- }
-
- /* Convert the module name to an object. */
- if ((client->em_nameobj = PyString_FromString(client->em_name)) == NULL)
- return -1;
-
- for (em = clientList; em != NULL; em = em->em_next)
- {
- /* SIP clients must have unique names. */
- if (strcmp(em->em_name, client->em_name) == 0)
- {
- PyErr_Format(PyExc_RuntimeError, "the sip module has already registered a module called %s", client->em_name);
-
- return -1;
- }
-
- /* Only one module can claim to wrap TQObject. */
- if (em->em_qt_api != NULL && client->em_qt_api != NULL)
- {
- PyErr_Format(PyExc_RuntimeError, "the %s and %s modules both wrap the TQObject class", client->em_name, em->em_name);
-
- return -1;
- }
- }
-
- /* Import any required modules. */
- if ((im = client->em_imports) != NULL)
- {
- while (im->im_name != NULL)
- {
- PyObject *mod;
-
- if ((mod = PyImport_ImportModule(im->im_name)) == NULL)
- return -1;
-
- for (em = clientList; em != NULL; em = em->em_next)
- if (strcmp(em->em_name, im->im_name) == 0)
- break;
-
- if (em == NULL)
- {
- PyErr_Format(PyExc_RuntimeError, "the %s module failed to register with the sip module", im->im_name);
-
- return -1;
- }
-
- /* Check the versions are compatible. */
- if (im->im_version >= 0 || em->em_version >= 0)
- if (im->im_version != em->em_version)
- {
- PyErr_Format(PyExc_RuntimeError, "the %s module is version %d but the %s module requires version %d", em->em_name, em->em_version, client->em_name, im->im_version);
-
- return -1;
- }
-
- /* Save the imported module. */
- im->im_module = em;
-
- ++im;
- }
- }
-
- /* Create the module's classes. */
- if ((mw = client->em_types) != NULL)
- for (i = 0; i < client->em_nrtypes; ++i, ++mw)
- {
- sipTypeDef *td = (sipTypeDef *)*mw;
-
- /* Skip external classes. */
- if (td == NULL)
- continue;
-
- /* See if this is a namespace extender. */
- if (td->td_name == NULL)
- {
- sipTypeDef **last;
- sipWrapperType *wt = getClassType(&td->td_scope, client);
-
- /* Append this type to the real one. */
- last = &wt->type->td_nsextender;
-
- while (*last != NULL)
- last = &(*last)->td_nsextender;
-
- *last = td;
-
- /*
- * Set this so that the extender's original
- * module can be found.
- */
- td->td_module = client;
-
- /*
- * Save the real namespace type so that it is
- * the correct scope for any enums or classes
- * defined in this module.
- */
- *mw = wt;
- }
- else if ((*mw = createType(client, td, mod_dict)) == NULL)
- return -1;
- }
-
- /* Set any Qt support API. */
- if (client->em_qt_api != NULL)
- {
- sipQtSupport = client->em_qt_api;
- sipQObjectClass = *sipQtSupport->qt_qobject;
- }
-
- /* Append any initialiser extenders to the relevant classes. */
- if ((ie = client->em_initextend) != NULL)
- while (ie->ie_extender != NULL)
- {
- sipWrapperType *wt = getClassType(&ie->ie_class, client);
-
- ie->ie_next = wt->iextend;
- wt->iextend = ie;
-
- ++ie;
- }
-
- /* Set the base class object for any sub-class convertors. */
- if ((scc = client->em_convertors) != NULL)
- while (scc->scc_convertor != NULL)
- {
- scc->scc_basetype = getClassType(&scc->scc_base, client);
-
- ++scc;
- }
-
- /* Create the module's enums. */
- if (client->em_nrenums != 0)
- {
- if ((client->em_enums = sip_api_malloc(client->em_nrenums * sizeof (PyTypeObject *))) == NULL)
- return -1;
-
- for (i = 0; i < client->em_nrenums; ++i)
- if ((client->em_enums[i] = createEnum(client, &client->em_enumdefs[i], mod_dict)) == NULL)
- return -1;
- }
-
- for (emd = client->em_enummembers, i = 0; i < client->em_nrenummembers; ++i, ++emd)
- {
- PyObject *mo;
-
- if ((mo = sip_api_convert_from_named_enum(emd->em_val, client->em_enums[emd->em_enum])) == NULL)
- return -1;
-
- if (PyDict_SetItemString(mod_dict, emd->em_name, mo) < 0)
- return -1;
-
- Py_DECREF(mo);
- }
-
-
- /*
- * Add any class static instances. We need to do this once all types are
- * fully formed because of potential interdependencies.
- */
- if ((mw = client->em_types) != NULL)
- for (i = 0; i < client->em_nrtypes; ++i)
- {
- sipWrapperType *wt;
-
- if ((wt = *mw++) != NULL && addInstances(((PyTypeObject *)wt)->tp_dict, &wt->type->td_instances) < 0)
- return -1;
- }
-
- /* Add any global static instances. */
- if (addInstances(mod_dict, &client->em_instances) < 0)
- return -1;
-
- /* Add any license. */
- if (client->em_license != NULL && addLicense(mod_dict, client->em_license) < 0)
- return -1;
-
- /* See if the new module satisfies any outstanding external types. */
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipExternalTypeDef *etd;
-
- if (em->em_external == NULL)
- continue;
-
- for (etd = em->em_external; etd->et_nr >= 0; ++etd)
- {
- if (etd->et_name == NULL)
- continue;
-
- mw = client->em_types;
-
- for (i = 0; i < client->em_nrtypes; ++i)
- {
- sipWrapperType *wt;
- const char *tname;
-
- if ((wt = *mw++) == NULL)
- continue;
-
- tname = strchr(wt->type->td_name, '.') + 1;
-
- if (strcmp(etd->et_name, tname) == 0)
- {
- em->em_types[etd->et_nr] = wt;
- etd->et_name = NULL;
-
- break;
- }
- }
- }
- }
-
- /* Add to the list of client modules. */
- client->em_next = clientList;
- clientList = client;
-
- return 0;
-}
-
-
-/*
- * Called by the interpreter to do any final clearing up, just in case the
- * interpreter will re-start.
- */
-static void finalise(void)
-{
- sipExportedModuleDef *em;
-
- /* Mark the Python API as unavailable. */
- sipInterpreter = NULL;
-
- /* Handle any delayed dtors. */
- for (em = clientList; em != NULL; em = em->em_next)
- if (em->em_ddlist != NULL)
- {
- em->em_delayeddtors(em->em_ddlist);
-
- /* Free the list. */
- do
- {
- sipDelayedDtor *dd = em->em_ddlist;
-
- em->em_ddlist = dd->dd_next;
- sip_api_free(dd);
- }
- while (em->em_ddlist != NULL);
- }
-
- licenseName = NULL;
- licenseeName = NULL;
- typeName = NULL;
- timestampName = NULL;
- signatureName = NULL;
-
- /* Release all memory we've allocated directly. */
- sipOMFinalise(&cppPyMap);
-
- /* Re-initialise those globals that (might) need it. */
- clientList = NULL;
-}
-
-
-/*
- * Add a wrapped C/C++ pointer to the list of delayed dtors.
- */
-static void sip_api_add_delayed_dtor(sipWrapper *w)
-{
- void *ptr;
- sipTypeDef *td;
- sipExportedModuleDef *em;
-
- if ((ptr = getPtrTypeDef(w, &td)) == NULL)
- return;
-
- /* Find the defining module. */
- for (em = clientList; em != NULL; em = em->em_next)
- {
- int i;
-
- for (i = 0; i < em->em_nrtypes; ++i)
- if (em->em_types[i] != NULL && em->em_types[i]->type == td)
- {
- sipDelayedDtor *dd;
-
- if ((dd = sip_api_malloc(sizeof (sipDelayedDtor))) == NULL)
- return;
-
- /* Add to the list. */
- dd->dd_ptr = ptr;
- dd->dd_name = getBaseName(td->td_name);
- dd->dd_isderived = sipIsDerived(w);
- dd->dd_next = em->em_ddlist;
-
- em->em_ddlist = dd;
-
- return;
- }
- }
-}
-
-
-/*
- * A wrapper around the Python memory allocater that will raise an exception if
- * if the allocation fails.
- */
-void *sip_api_malloc(size_t nbytes)
-{
- void *mem;
-
- if ((mem = PyMem_Malloc(nbytes)) == NULL)
- PyErr_NoMemory();
-
- return mem;
-}
-
-
-/*
- * A wrapper around the Python memory de-allocater.
- */
-void sip_api_free(void *mem)
-{
- PyMem_Free(mem);
-}
-
-
-/*
- * Extend a Python slot by looking in other modules to see if there is an
- * extender function that can handle the arguments.
- */
-static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod,
- sipPySlotType st, sipWrapperType *type,
- PyObject *arg0, PyObject *arg1)
-{
- sipExportedModuleDef *em;
-
- /* Go through each module. */
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipPySlotExtenderDef *ex;
-
- /* Skip the module that couldn't handle the arguments. */
- if (em == mod)
- continue;
-
- /* Skip if the module doesn't have any extenders. */
- if (em->em_slotextend == NULL)
- continue;
-
- /* Go through each extender. */
- for (ex = em->em_slotextend; ex->pse_func != NULL; ++ex)
- {
- PyObject *res;
-
- /* Skip if not the right slot type. */
- if (ex->pse_type != st)
- continue;
-
- /* Check against the type if one was given. */
- if (type != NULL && type != getClassType(&ex->pse_class, NULL))
- continue;
-
- PyErr_Clear();
-
- res = ((binaryfunc)ex->pse_func)(arg0, arg1);
-
- if (res != Py_NotImplemented)
- return res;
- }
- }
-
- /* The arguments couldn't handled anywhere. */
- PyErr_Clear();
-
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
-}
-
-
-/*
- * Call the Python re-implementation of a C++ virtual.
- */
-static PyObject *sip_api_call_method(int *isErr, PyObject *method,
- const char *fmt, ...)
-{
- PyObject *args, *res;
- va_list va;
-
- va_start(va,fmt);
-
- if ((args = PyTuple_New(strlen(fmt))) != NULL && buildObject(args,fmt,va) != NULL)
- res = PyEval_CallObject(method,args);
- else
- {
- res = NULL;
-
- if (isErr != NULL)
- *isErr = TRUE;
- }
-
- Py_XDECREF(args);
-
- va_end(va);
-
- return res;
-}
-
-
-/*
- * Build a result object based on a format string.
- */
-static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...)
-{
- PyObject *res = NULL;
- int badfmt, tupsz;
- va_list va;
-
- va_start(va,fmt);
-
- /* Basic validation of the format string. */
-
- badfmt = FALSE;
-
- if (*fmt == '(')
- {
- char *ep;
-
- if ((ep = strchr(fmt,')')) == NULL || ep[1] != '\0')
- badfmt = TRUE;
- else
- tupsz = ep - fmt - 1;
- }
- else if (strlen(fmt) == 1)
- tupsz = -1;
- else
- badfmt = TRUE;
-
- if (badfmt)
- PyErr_Format(PyExc_SystemError,"sipBuildResult(): invalid format string \"%s\"",fmt);
- else if (tupsz < 0 || (res = PyTuple_New(tupsz)) != NULL)
- res = buildObject(res,fmt,va);
-
- va_end(va);
-
- if (res == NULL && isErr != NULL)
- *isErr = TRUE;
-
- return res;
-}
-
-
-/*
- * Get the values off the stack and put them into an object.
- */
-static PyObject *buildObject(PyObject *obj, const char *fmt, va_list va)
-{
- char ch, termch;
- int i;
-
- /*
- * The format string has already been checked that it is properly
- * formed if it is enclosed in parenthesis.
- */
- if (*fmt == '(')
- {
- termch = ')';
- ++fmt;
- }
- else
- termch = '\0';
-
- i = 0;
-
- while ((ch = *fmt++) != termch)
- {
- PyObject *el;
-
- switch (ch)
- {
- case 'a':
- {
- char *s;
- int l;
-
- s = va_arg(va, char *);
- l = va_arg(va, int);
-
- if (s != NULL)
- el = PyString_FromStringAndSize(s, (SIP_SSIZE_T)l);
- else
- {
- Py_INCREF(Py_None);
- el = Py_None;
- }
- }
-
- break;
-
- case 'A':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t *s;
- int l;
-
- s = va_arg(va, wchar_t *);
- l = va_arg(va, int);
-
- if (s != NULL)
- el = PyUnicode_FromWideChar(s, (SIP_SSIZE_T)l);
- else
- {
- Py_INCREF(Py_None);
- el = Py_None;
- }
- }
-#else
- raiseNoWChar();
- el = NULL;
-#endif
-
- break;
-
- case 'b':
- el = PyBool_FromLong(va_arg(va,int));
- break;
-
- case 'c':
- {
- char c = va_arg(va, int);
-
- el = PyString_FromStringAndSize(&c,1);
- }
-
- break;
-
- case 'w':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t c = va_arg(va, int);
-
- el = PyUnicode_FromWideChar(&c, 1);
- }
-#else
- raiseNoWChar();
- el = NULL;
-#endif
-
- break;
-
- case 'e':
- el = PyInt_FromLong(va_arg(va,int));
- break;
-
- case 'E':
- {
- int ev = va_arg(va, int);
- PyTypeObject *et = va_arg(va, PyTypeObject *);
-
- el = sip_api_convert_from_named_enum(ev, et);
- }
-
- break;
-
- case 'd':
- case 'f':
- el = PyFloat_FromDouble(va_arg(va,double));
- break;
-
- case 'h':
- case 'i':
- el = PyInt_FromLong(va_arg(va,int));
- break;
-
- case 'l':
- el = PyLong_FromLong(va_arg(va,long));
- break;
-
- case 'm':
- el = PyLong_FromUnsignedLong(va_arg(va, unsigned long));
- break;
-
- case 'n':
-#if defined(HAVE_LONG_LONG)
- el = PyLong_FromLongLong(va_arg(va, PY_LONG_LONG));
-#else
- el = PyLong_FromLong(va_arg(va, long));
-#endif
- break;
-
- case 'o':
-#if defined(HAVE_LONG_LONG)
- el = PyLong_FromUnsignedLongLong(va_arg(va, unsigned PY_LONG_LONG));
-#else
- el = PyLong_FromUnsignedLong(va_arg(va, unsigned long));
-#endif
- break;
-
- case 's':
- {
- char *s = va_arg(va, char *);
-
- if (s != NULL)
- el = PyString_FromString(s);
- else
- {
- Py_INCREF(Py_None);
- el = Py_None;
- }
- }
-
- break;
-
- case 'x':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t *s = va_arg(va, wchar_t *);
-
- if (s != NULL)
- el = PyUnicode_FromWideChar(s, (SIP_SSIZE_T)wcslen(s));
- else
- {
- Py_INCREF(Py_None);
- el = Py_None;
- }
- }
-#else
- raiseNoWChar();
- el = NULL;
-#endif
-
- break;
-
- case 't':
- case 'u':
- el = PyLong_FromUnsignedLong(va_arg(va, unsigned));
- break;
-
- case 'B':
- {
- void *p = va_arg(va,void *);
- sipWrapperType *wt = va_arg(va, sipWrapperType *);
- PyObject *xfer = va_arg(va, PyObject *);
-
- el = sip_api_convert_from_new_instance(p, wt, xfer);
- }
-
- break;
-
- case 'C':
- {
- void *p = va_arg(va,void *);
- sipWrapperType *wt = va_arg(va, sipWrapperType *);
- PyObject *xfer = va_arg(va, PyObject *);
-
- el = sip_api_convert_from_instance(p, wt, xfer);
- }
-
- break;
-
- case 'D':
- {
- void *p = va_arg(va, void *);
- const sipMappedType *mt = va_arg(va, const sipMappedType *);
- PyObject *xfer = va_arg(va, PyObject *);
-
- el = sip_api_convert_from_mapped_type(p, mt, xfer);
- }
-
- break;
-
- case 'M':
- case 'O':
- {
- void *sipCpp = va_arg(va,void *);
- sipWrapperType *wt = va_arg(va,sipWrapperType *);
-
- el = sip_api_convert_from_instance(sipCpp,wt,NULL);
- }
-
- break;
-
- case 'N':
- case 'P':
- {
- void *sipCpp = va_arg(va,void *);
- sipWrapperType *wt = va_arg(va,sipWrapperType *);
-
- el = sip_api_convert_from_new_instance(sipCpp,wt,NULL);
- }
-
- break;
-
- case 'R':
- el = va_arg(va,PyObject *);
- break;
-
- case 'S':
- el = va_arg(va,PyObject *);
- Py_INCREF(el);
- break;
-
- case 'T':
- {
- void *sipCpp = va_arg(va,void *);
- sipConvertFromFunc func = va_arg(va,sipConvertFromFunc);
-
- el = func(sipCpp, NULL);
- }
-
- break;
-
- case 'V':
- el = sip_api_convert_from_void_ptr(va_arg(va,void *));
- break;
-
- default:
- PyErr_Format(PyExc_SystemError,"buildObject(): invalid format character '%c'",ch);
- el = NULL;
- }
-
- if (el == NULL)
- {
- Py_XDECREF(obj);
- return NULL;
- }
-
- if (obj == NULL)
- return el;
-
- PyTuple_SET_ITEM(obj,i,el);
- ++i;
- }
-
- return obj;
-}
-
-
-/*
- * Parse a result object based on a format string.
- */
-static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res,
- const char *fmt, ...)
-{
- int tupsz, rc = 0;
- va_list va;
-
- va_start(va,fmt);
-
- /* Basic validation of the format string. */
-
- if (*fmt == '(')
- {
- char *ep;
-
- if ((ep = strchr(fmt,')')) == NULL || ep[1] != '\0')
- {
- PyErr_Format(PyExc_SystemError, "sipParseResult(): invalid format string \"%s\"", fmt);
- rc = -1;
- }
- else
- {
- tupsz = ep - ++fmt;
-
- if (tupsz >= 0 && (!PyTuple_Check(res) || PyTuple_GET_SIZE(res) != tupsz))
- {
- sip_api_bad_catcher_result(method);
- rc = -1;
- }
- }
- }
- else
- tupsz = -1;
-
- if (rc == 0)
- {
- char ch;
- int i = 0;
-
- while ((ch = *fmt++) != '\0' && ch != ')' && rc == 0)
- {
- PyObject *arg;
- int invalid = FALSE;
-
- if (tupsz > 0)
- {
- arg = PyTuple_GET_ITEM(res,i);
- ++i;
- }
- else
- arg = res;
-
- switch (ch)
- {
- case 'a':
- {
- char **p = va_arg(va, char **);
- int *szp = va_arg(va, int *);
-
- if (parseCharArray(arg, p, szp) < 0)
- invalid = TRUE;
- }
-
- break;
-
- case 'A':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t **p = va_arg(va, wchar_t **);
- int *szp = va_arg(va, int *);
-
- if (parseWCharArray(arg, p, szp) < 0)
- invalid = TRUE;
- }
-#else
- raiseNoWChar();
- invalid = TRUE;
-#endif
-
- break;
-
- case 'b':
- {
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- sipSetBool(va_arg(va,void *),v);
- }
-
- break;
-
- case 'c':
- {
- char *p = va_arg(va, char *);
-
- if (parseChar(arg, p) < 0)
- invalid = TRUE;
- }
-
- break;
-
- case 'w':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t *p = va_arg(va, wchar_t *);
-
- if (parseWChar(arg, p) < 0)
- invalid = TRUE;
- }
-#else
- raiseNoWChar();
- invalid = TRUE;
-#endif
-
- break;
-
- case 'd':
- {
- double v = PyFloat_AsDouble(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,double *) = v;
- }
-
- break;
-
- case 'e':
- {
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,int *) = v;
- }
-
- break;
-
- case 'E':
- {
- PyTypeObject *et = va_arg(va, PyTypeObject *);
- int *p = va_arg(va, int *);
-
- if (PyObject_TypeCheck(arg, et))
- *p = PyInt_AsLong(arg);
- else
- invalid = TRUE;
- }
-
- break;
-
- case 'f':
- {
- float v = PyFloat_AsDouble(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,float *) = v;
- }
-
- break;
-
- case 'h':
- {
- short v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,short *) = v;
- }
-
- break;
-
- case 't':
- {
- unsigned short v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,unsigned short *) = v;
- }
-
- break;
-
- case 'i':
- {
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,int *) = v;
- }
-
- break;
-
- case 'u':
- {
- unsigned v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,unsigned *) = v;
- }
-
- break;
-
- case 'l':
- {
- long v = PyLong_AsLong(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,long *) = v;
- }
-
- break;
-
- case 'm':
- {
- unsigned long v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va, unsigned long *) = v;
- }
-
- break;
-
- case 'n':
- {
-#if defined(HAVE_LONG_LONG)
- PY_LONG_LONG v = PyLong_AsLongLong(arg);
-#else
- long v = PyLong_AsLong(arg);
-#endif
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
-#if defined(HAVE_LONG_LONG)
- *va_arg(va, PY_LONG_LONG *) = v;
-#else
- *va_arg(va, long *) = v;
-#endif
- }
-
- break;
-
- case 'o':
- {
-#if defined(HAVE_LONG_LONG)
- unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLong(arg);
-#else
- unsigned long v = PyLong_AsUnsignedLong(arg);
-#endif
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
-#if defined(HAVE_LONG_LONG)
- *va_arg(va, unsigned PY_LONG_LONG *) = v;
-#else
- *va_arg(va, unsigned long *) = v;
-#endif
- }
-
- break;
-
- case 's':
- {
- char **p = va_arg(va, char **);
-
- if (parseCharString(arg, p) < 0)
- invalid = TRUE;
- }
-
- break;
-
- case 'x':
-#if defined(HAVE_WCHAR_H)
- {
- wchar_t **p = va_arg(va, wchar_t **);
-
- if (parseWCharString(arg, p) < 0)
- invalid = TRUE;
- }
-#else
- raiseNoWChar();
- invalid = TRUE;
-#endif
-
- break;
-
- case 'C':
- {
- if (*fmt == '\0')
- invalid = TRUE;
- else
- {
- int flags = *fmt++ - '0';
- int iserr = FALSE;
- sipWrapperType *type;
- void **cpp;
- int *state;
-
- type = va_arg(va, sipWrapperType *);
-
- if (flags & FORMAT_NO_STATE)
- state = NULL;
- else
- state = va_arg(va, int *);
-
- cpp = va_arg(va, void **);
-
- *cpp = sip_api_force_convert_to_instance(arg, type, (flags & FORMAT_FACTORY ? arg : NULL), (flags & FORMAT_DEREF ? SIP_NOT_NONE : 0), state, &iserr);
-
- if (iserr)
- invalid = TRUE;
- }
- }
-
- break;
-
- case 'D':
- {
- if (*fmt == '\0')
- invalid = TRUE;
- else
- {
- int flags = *fmt++ - '0';
- int iserr = FALSE;
- const sipMappedType *mt;
- void **cpp;
- int *state;
-
- mt = va_arg(va, const sipMappedType *);
-
- if (flags & FORMAT_NO_STATE)
- state = NULL;
- else
- state = va_arg(va, int *);
-
- cpp = va_arg(va, void **);
-
- *cpp = sip_api_force_convert_to_mapped_type(arg, mt, (flags & FORMAT_FACTORY ? arg : NULL), (flags & FORMAT_DEREF ? SIP_NOT_NONE : 0), state, &iserr);
-
- if (iserr)
- invalid = TRUE;
- }
- }
-
- break;
-
- case 'L':
- {
- sipForceConvertToFunc func = va_arg(va,sipForceConvertToFunc);
- void **sipCpp = va_arg(va,void **);
- int iserr = FALSE;
-
- *sipCpp = func(arg,&iserr);
-
- if (iserr)
- invalid = TRUE;
- }
-
- break;
-
- case 'M':
- {
- sipForceConvertToFunc func = va_arg(va,sipForceConvertToFunc);
- void **sipCpp = va_arg(va,void **);
- int iserr = FALSE;
-
- *sipCpp = func(arg,&iserr);
-
- if (iserr || *sipCpp == NULL)
- invalid = TRUE;
- }
-
- break;
-
- case 'N':
- {
- PyTypeObject *type = va_arg(va,PyTypeObject *);
- PyObject **p = va_arg(va,PyObject **);
-
- if (arg == Py_None || PyObject_TypeCheck(arg,type))
- {
- Py_INCREF(arg);
- *p = arg;
- }
- else
- invalid = TRUE;
- }
-
- break;
-
- case 'O':
- Py_INCREF(arg);
- *va_arg(va,PyObject **) = arg;
- break;
-
- case 'T':
- {
- PyTypeObject *type = va_arg(va,PyTypeObject *);
- PyObject **p = va_arg(va,PyObject **);
-
- if (PyObject_TypeCheck(arg,type))
- {
- Py_INCREF(arg);
- *p = arg;
- }
- else
- invalid = TRUE;
- }
-
- break;
-
- case 'V':
- {
- void *v = sip_api_convert_to_void_ptr(arg);
-
- if (PyErr_Occurred())
- invalid = TRUE;
- else
- *va_arg(va,void **) = v;
- }
-
- break;
-
- case 'Z':
- if (arg != Py_None)
- invalid = TRUE;
-
- break;
-
- default:
- PyErr_Format(PyExc_SystemError,"sipParseResult(): invalid format character '%c'",ch);
- rc = -1;
- }
-
- if (invalid)
- {
- sip_api_bad_catcher_result(method);
- rc = -1;
- break;
- }
- }
- }
-
- va_end(va);
-
- if (isErr != NULL && rc < 0)
- *isErr = TRUE;
-
- return rc;
-}
-
-
-/*
- * A thin wrapper around PyLong_AsUnsignedLong() that works around a bug in
- * Python versions prior to v2.4 where an integer (or a named enum) causes an
- * error.
- */
-static unsigned long sip_api_long_as_unsigned_long(PyObject *o)
-{
-#if PY_VERSION_HEX < 0x02040000
- if (o != NULL && !PyLong_Check(o) && PyInt_Check(o))
- {
- long v = PyInt_AsLong(o);
-
- if (v < 0)
- {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
-
- return (unsigned long)-1;
- }
-
- return v;
- }
-#endif
-
- return PyLong_AsUnsignedLong(o);
-}
-
-
-/*
- * Parse the arguments to a C/C++ function without any side effects.
- */
-static int sip_api_parse_args(int *argsParsedp, PyObject *sipArgs,
- const char *fmt, ...)
-{
- int valid, nrargs, selfarg;
- sipWrapper *self;
- PyObject *single_arg;
- va_list va;
-
- /* Previous sticky errors stop subsequent parses. */
- if (*argsParsedp & PARSE_STICKY)
- return 0;
-
- /* See if we are parsing a tuple or a single argument. */
- if (PyTuple_Check(sipArgs))
- {
- Py_INCREF(sipArgs);
- nrargs = PyTuple_GET_SIZE(sipArgs);
- }
- else if ((single_arg = PyTuple_New(1)) != NULL)
- {
- Py_INCREF(sipArgs);
- PyTuple_SET_ITEM(single_arg,0,sipArgs);
-
- sipArgs = single_arg;
- nrargs = 1;
- }
- else
- return 0;
-
- /*
- * The first pass checks all the types and does conversions that are
- * cheap and have no side effects.
- */
- va_start(va,fmt);
- valid = parsePass1(&self,&selfarg,&nrargs,sipArgs,fmt,va);
- va_end(va);
-
- if (valid != PARSE_OK)
- {
- int pvalid, pnrargs;
-
- /*
- * Use this error if there was no previous error, or if we
- * have parsed more arguments this time, or if the previous
- * error was that there were too many arguments.
- */
- pvalid = (*argsParsedp & PARSE_MASK);
- pnrargs = (*argsParsedp & ~PARSE_MASK);
-
- if (pvalid == PARSE_OK || pnrargs < nrargs ||
- (pnrargs == nrargs && pvalid == PARSE_MANY))
- *argsParsedp = valid | nrargs;
-
- Py_DECREF(sipArgs);
-
- return 0;
- }
-
- /*
- * The second pass does any remaining conversions now that we know we
- * have the right signature.
- */
- va_start(va,fmt);
- valid = parsePass2(self,selfarg,nrargs,sipArgs,fmt,va);
- va_end(va);
-
- if (valid != PARSE_OK)
- {
- *argsParsedp = valid | PARSE_STICKY;
-
- Py_DECREF(sipArgs);
-
- return 0;
- }
-
- *argsParsedp = nrargs;
-
- Py_DECREF(sipArgs);
-
- return 1;
-}
-
-
-/*
- * Parse a pair of arguments to a C/C++ function without any side effects.
- */
-static int sip_api_parse_pair(int *argsParsedp, PyObject *sipArg0,
- PyObject *sipArg1, const char *fmt, ...)
-{
- int valid, nrargs, selfarg;
- sipWrapper *self;
- PyObject *args;
- va_list va;
-
- /* Previous sticky errors stop subsequent parses. */
- if (*argsParsedp & PARSE_STICKY)
- return 0;
-
- if ((args = PyTuple_New(2)) == NULL)
- return 0;
-
- Py_INCREF(sipArg0);
- PyTuple_SET_ITEM(args, 0, sipArg0);
-
- Py_INCREF(sipArg1);
- PyTuple_SET_ITEM(args, 1, sipArg1);
-
- nrargs = 2;
-
- /*
- * The first pass checks all the types and does conversions that are
- * cheap and have no side effects.
- */
- va_start(va,fmt);
- valid = parsePass1(&self,&selfarg,&nrargs,args,fmt,va);
- va_end(va);
-
- if (valid != PARSE_OK)
- {
- int pvalid, pnrargs;
-
- /*
- * Use this error if there was no previous error, or if we
- * have parsed more arguments this time, or if the previous
- * error was that there were too many arguments.
- */
- pvalid = (*argsParsedp & PARSE_MASK);
- pnrargs = (*argsParsedp & ~PARSE_MASK);
-
- if (pvalid == PARSE_OK || pnrargs < nrargs ||
- (pnrargs == nrargs && pvalid == PARSE_MANY))
- *argsParsedp = valid | nrargs;
-
- Py_DECREF(args);
-
- return 0;
- }
-
- /*
- * The second pass does any remaining conversions now that we know we
- * have the right signature.
- */
- va_start(va,fmt);
- valid = parsePass2(self,selfarg,nrargs,args,fmt,va);
- va_end(va);
-
- if (valid != PARSE_OK)
- {
- *argsParsedp = valid | PARSE_STICKY;
-
- Py_DECREF(args);
-
- return 0;
- }
-
- *argsParsedp = nrargs;
-
- Py_DECREF(args);
-
- return 1;
-}
-
-
-/*
- * First pass of the argument parse, converting those that can be done so
- * without any side effects. Return PARSE_OK if the arguments matched.
- */
-static int parsePass1(sipWrapper **selfp, int *selfargp, int *argsParsedp,
- PyObject *sipArgs, const char *fmt, va_list va)
-{
- int valid, compulsory, nrargs, argnr, nrparsed;
-
- valid = PARSE_OK;
- nrargs = *argsParsedp;
- nrparsed = 0;
- compulsory = TRUE;
- argnr = 0;
-
- /*
- * Handle those format characters that deal with the "self" argument.
- * They will always be the first one.
- */
- *selfp = NULL;
- *selfargp = FALSE;
-
- switch (*fmt++)
- {
- case 'B':
- case 'p':
- {
- PyObject *self;
- sipWrapperType *type;
-
- self = *va_arg(va,PyObject **);
- type = va_arg(va,sipWrapperType *);
- va_arg(va,void **);
-
- if (self == NULL)
- {
- if ((valid = getSelfFromArgs(type,sipArgs,argnr,selfp)) != PARSE_OK)
- break;
-
- *selfargp = TRUE;
- ++nrparsed;
- ++argnr;
- }
- else
- *selfp = (sipWrapper *)self;
-
- break;
- }
-
- case 'C':
- *selfp = (sipWrapper *)va_arg(va,PyObject *);
- break;
-
- default:
- --fmt;
- }
-
- /* Now handle the remaining arguments. */
- while (valid == PARSE_OK)
- {
- char ch;
- PyObject *arg;
-
- PyErr_Clear();
-
- /* See if the following arguments are optional. */
- if ((ch = *fmt++) == '|')
- {
- compulsory = FALSE;
- ch = *fmt++;
- }
-
- /* See if we don't expect anything else. */
-
- if (ch == '\0')
- {
- /* Invalid if there are still arguments. */
- if (argnr < nrargs)
- valid = PARSE_MANY;
-
- break;
- }
-
- /* See if we have run out of arguments. */
-
- if (argnr == nrargs)
- {
- /*
- * It is an error if we are still expecting compulsory
- * arguments unless the current argume is an ellipsis.
- */
- if (ch != 'W' && ch != '\0' && compulsory)
- valid = PARSE_FEW;
-
- break;
- }
-
- /* Get the next argument. */
- arg = PyTuple_GET_ITEM(sipArgs,argnr);
- ++argnr;
-
- switch (ch)
- {
- case 'W':
- /* Ellipsis. */
- break;
-
- case 's':
- {
- /* String or None. */
-
- char **p = va_arg(va, char **);
-
- if (parseCharString(arg, p) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'x':
-#if defined(HAVE_WCHAR_H)
- {
- /* Wide string or None. */
-
- wchar_t **p = va_arg(va, wchar_t **);
-
- if (parseWCharString(arg, p) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-#else
- raiseNoWChar();
- valid = PARSE_RAISED;
- break;
-#endif
-
- case 'U':
- {
- /*
- * Slot name or callable, return the name or
- * callable.
- */
-
- char **sname = va_arg(va, char **);
- PyObject **scall = va_arg(va, PyObject **);
-
- *sname = NULL;
- *scall = NULL;
-
- if (PyString_Check(arg))
- {
- char *s = PyString_AS_STRING(arg);
-
- if (*s == '1' || *s == '2' || *s == '9')
- *sname = s;
- else
- valid = PARSE_TYPE;
- }
- else if (PyCallable_Check(arg))
- *scall = arg;
- else if (arg != Py_None)
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'S':
- {
- /* Slot name, return the name. */
-
- if (PyString_Check(arg))
- {
- char *s = PyString_AS_STRING(arg);
-
- if (*s == '1' || *s == '2' || *s == '9')
- *va_arg(va,char **) = s;
- else
- valid = PARSE_TYPE;
- }
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'G':
- {
- /* Signal name, return the name. */
-
- if (PyString_Check(arg))
- {
- char *s = PyString_AS_STRING(arg);
-
- if (*s == '2' || *s == '9')
- *va_arg(va,char **) = s;
- else
- valid = PARSE_TYPE;
- }
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'J':
- {
- /* Class instance. */
-
- if (*fmt == '\0')
- valid = PARSE_FORMAT;
- else
- {
- int flags = *fmt++ - '0';
- sipWrapperType *type;
- int iflgs = 0;
-
- type = va_arg(va,sipWrapperType *);
- va_arg(va,void **);
-
- if (flags & FORMAT_DEREF)
- iflgs |= SIP_NOT_NONE;
-
- if (flags & (FORMAT_GET_WRAPPER|FORMAT_TRANSFER_THIS))
- va_arg(va,PyObject **);
-
- if (flags & FORMAT_NO_CONVERTORS)
- iflgs |= SIP_NO_CONVERTORS;
- else
- va_arg(va, int *);
-
- if (!sip_api_can_convert_to_instance(arg, type, iflgs))
- valid = PARSE_TYPE;
- }
-
- break;
- }
-
- case 'M':
- {
- /* Mapped type instance. */
-
- if (*fmt == '\0')
- valid = PARSE_FORMAT;
- else
- {
- int flags = *fmt++ - '0';
- sipMappedType *mt;
- int iflgs = 0;
-
- mt = va_arg(va, sipMappedType *);
- va_arg(va, void **);
- va_arg(va, int *);
-
- if (flags & FORMAT_DEREF)
- iflgs |= SIP_NOT_NONE;
-
- if (!sip_api_can_convert_to_mapped_type(arg, mt, iflgs))
- valid = PARSE_TYPE;
- }
-
- break;
- }
-
-
- case 'N':
- {
- /* Python object of given type or None. */
-
- PyTypeObject *type = va_arg(va,PyTypeObject *);
- PyObject **p = va_arg(va,PyObject **);
-
- if (arg == Py_None || PyObject_TypeCheck(arg,type))
- *p = arg;
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'P':
- {
- /*
- * Python object of any type with a
- * sub-format.
- */
-
- *va_arg(va,PyObject **) = arg;
-
- /* Skip the sub-format. */
- if (*fmt++ == '\0')
- valid = PARSE_FORMAT;
-
- break;
- }
-
- case 'T':
- {
- /* Python object of given type. */
-
- PyTypeObject *type = va_arg(va,PyTypeObject *);
- PyObject **p = va_arg(va,PyObject **);
-
- if (PyObject_TypeCheck(arg,type))
- *p = arg;
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'R':
- {
- /* Sub-class of TQObject. */
-
- if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass))
- valid = PARSE_TYPE;
- else
- *va_arg(va,PyObject **) = arg;
-
- break;
- }
-
- case 'F':
- {
- /* Python callable object. */
-
- if (PyCallable_Check(arg))
- *va_arg(va,PyObject **) = arg;
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'H':
- {
- /* Python callable object or None. */
-
- if (arg == Py_None || PyCallable_Check(arg))
- *va_arg(va,PyObject **) = arg;
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'q':
- {
- /* Qt receiver to connect. */
-
- va_arg(va,char *);
- va_arg(va,void **);
- va_arg(va,const char **);
-
- if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass))
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'Q':
- {
- /* Qt receiver to disconnect. */
-
- va_arg(va,char *);
- va_arg(va,void **);
- va_arg(va,const char **);
-
- if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass))
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'y':
- {
- /* Python slot to connect. */
-
- va_arg(va,char *);
- va_arg(va,void **);
- va_arg(va,const char **);
-
- if (sipQtSupport == NULL || !PyCallable_Check(arg))
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'Y':
- {
- /* Python slot to disconnect. */
-
- va_arg(va,char *);
- va_arg(va,void **);
- va_arg(va,const char **);
-
- if (sipQtSupport == NULL || !PyCallable_Check(arg))
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'a':
- {
- /* Char array or None. */
-
- char **p = va_arg(va, char **);
- int *szp = va_arg(va, int *);
-
- if (parseCharArray(arg, p, szp) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'A':
-#if defined(HAVE_WCHAR_H)
- {
- /* Wide char array or None. */
-
- wchar_t **p = va_arg(va, wchar_t **);
- int *szp = va_arg(va, int *);
-
- if (parseWCharArray(arg, p, szp) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-#else
- raiseNoWChar();
- valid = PARSE_RAISED;
- break
-#endif
-
- case 'c':
- {
- /* Character. */
-
- char *p = va_arg(va, char *);
-
- if (parseChar(arg, p) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'w':
-#if defined(HAVE_WCHAR_H)
- {
- /* Wide character. */
-
- wchar_t *p = va_arg(va, wchar_t *);
-
- if (parseWChar(arg, p) < 0)
- valid = PARSE_TYPE;
-
- break;
- }
-#else
- raiseNoWChar();
- valid = PARSE_RAISED;
- break
-#endif
-
- case 'b':
- {
- /* Bool. */
-
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- sipSetBool(va_arg(va,void *),v);
-
- break;
- }
-
- case 'e':
- {
- /* Anonymous enum. */
-
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,int *) = v;
-
- break;
- }
-
- case 'E':
- {
- /* Named enum. */
-
- PyTypeObject *et = va_arg(va, PyTypeObject *);
-
- va_arg(va, int *);
-
- if (!PyObject_TypeCheck(arg, et))
- valid = PARSE_TYPE;
- }
-
- break;
-
- case 'i':
- {
- /* Integer. */
-
- int v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,int *) = v;
-
- break;
- }
-
- case 'u':
- {
- /* Unsigned integer. */
-
- unsigned v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va, unsigned *) = v;
-
- break;
- }
-
- case 'h':
- {
- /* Short integer. */
-
- short v = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,short *) = v;
-
- break;
- }
-
- case 't':
- {
- /* Unsigned short integer. */
-
- unsigned short v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va, unsigned short *) = v;
-
- break;
- }
-
- case 'l':
- {
- /* Long integer. */
-
- long v = PyLong_AsLong(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,long *) = v;
-
- break;
- }
-
- case 'm':
- {
- /* Unsigned long integer. */
-
- unsigned long v = sip_api_long_as_unsigned_long(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va, unsigned long *) = v;
-
- break;
- }
-
- case 'n':
- {
- /* Long long integer. */
-
-#if defined(HAVE_LONG_LONG)
- PY_LONG_LONG v = PyLong_AsLongLong(arg);
-#else
- long v = PyLong_AsLong(arg);
-#endif
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
-#if defined(HAVE_LONG_LONG)
- *va_arg(va, PY_LONG_LONG *) = v;
-#else
- *va_arg(va, long *) = v;
-#endif
-
- break;
- }
-
- case 'o':
- {
- /* Unsigned long long integer. */
-
-#if defined(HAVE_LONG_LONG)
- unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLong(arg);
-#else
- unsigned long v = PyLong_AsUnsignedLong(arg);
-#endif
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
-#if defined(HAVE_LONG_LONG)
- *va_arg(va, unsigned PY_LONG_LONG *) = v;
-#else
- *va_arg(va, unsigned long *) = v;
-#endif
-
- break;
- }
-
- case 'f':
- {
- /* Float. */
-
- double v = PyFloat_AsDouble(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,float *) = (float)v;
-
- break;
- }
-
- case 'X':
- {
- /* Constrained (ie. exact) types. */
-
- switch (*fmt++)
- {
- case 'b':
- {
- /* Boolean. */
-
- if (PyBool_Check(arg))
- sipSetBool(va_arg(va,void *),(arg == Py_True));
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'd':
- {
- /* Double float. */
-
- if (PyFloat_Check(arg))
- *va_arg(va,double *) = PyFloat_AS_DOUBLE(arg);
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'f':
- {
- /* Float. */
-
- if (PyFloat_Check(arg))
- *va_arg(va,float *) = (float)PyFloat_AS_DOUBLE(arg);
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- case 'i':
- {
- /* Integer. */
-
- if (PyInt_Check(arg))
- *va_arg(va,int *) = PyInt_AS_LONG(arg);
- else
- valid = PARSE_TYPE;
-
- break;
- }
-
- default:
- valid = PARSE_FORMAT;
- }
-
- break;
- }
-
- case 'd':
- {
- /* Double float. */
-
- double v = PyFloat_AsDouble(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,double *) = v;
-
- break;
- }
-
- case 'v':
- {
- /* Void pointer. */
-
- void *v = sip_api_convert_to_void_ptr(arg);
-
- if (PyErr_Occurred())
- valid = PARSE_TYPE;
- else
- *va_arg(va,void **) = v;
-
- break;
- }
-
- default:
- valid = PARSE_FORMAT;
- }
-
- if (valid == PARSE_OK)
- {
- if (ch == 'W')
- {
- /*
- * An ellipsis matches everything and ends the
- * parse.
- */
- nrparsed = nrargs;
- break;
- }
-
- ++nrparsed;
- }
- }
-
- *argsParsedp = nrparsed;
-
- return valid;
-}
-
-
-/*
- * Second pass of the argument parse, converting the remaining ones that might
- * have side effects. Return PARSE_OK if there was no error.
- */
-static int parsePass2(sipWrapper *self, int selfarg, int nrargs,
- PyObject *sipArgs, const char *fmt, va_list va)
-{
- int a, valid;
-
- valid = PARSE_OK;
-
- /* Handle the converions of "self" first. */
- switch (*fmt++)
- {
- case 'B':
- {
- /*
- * The address of a C++ instance when calling one of
- * its public methods.
- */
-
- sipWrapperType *type;
- void **p;
-
- *va_arg(va,PyObject **) = (PyObject *)self;
- type = va_arg(va,sipWrapperType *);
- p = va_arg(va,void **);
-
- if ((*p = sip_api_get_cpp_ptr(self,type)) == NULL)
- valid = PARSE_RAISED;
-
- break;
- }
-
- case 'p':
- {
- /*
- * The address of a C++ instance when calling one of
- * its protected methods.
- */
-
- void **p;
-
- *va_arg(va,PyObject **) = (PyObject *)self;
- va_arg(va,sipWrapperType *);
- p = va_arg(va,void **);
-
- if ((*p = sip_api_get_complex_cpp_ptr(self)) == NULL)
- valid = PARSE_RAISED;
-
- break;
- }
-
- case 'C':
- va_arg(va,PyObject *);
- break;
-
- default:
- --fmt;
- }
-
- for (a = (selfarg ? 1 : 0); a < nrargs && *fmt != 'W' && valid == PARSE_OK; ++a)
- {
- char ch;
- PyObject *arg = PyTuple_GET_ITEM(sipArgs,a);
-
- /* Skip the optional character. */
- if ((ch = *fmt++) == '|')
- ch = *fmt++;
-
- /*
- * Do the outstanding conversions. For most types it has
- * already been done, so we are just skipping the parameters.
- */
- switch (ch)
- {
- case 'q':
- {
- /* Qt receiver to connect. */
-
- char *sig = va_arg(va,char *);
- void **rx = va_arg(va,void **);
- const char **slot = va_arg(va,const char **);
-
- if ((*rx = sip_api_convert_rx(self,sig,arg,*slot,slot)) == NULL)
- valid = PARSE_RAISED;
-
- break;
- }
-
- case 'Q':
- {
- /* Qt receiver to disconnect. */
-
- char *sig = va_arg(va,char *);
- void **rx = va_arg(va,void **);
- const char **slot = va_arg(va,const char **);
-
- *rx = sipGetRx(self,sig,arg,*slot,slot);
- break;
- }
-
- case 'y':
- {
- /* Python slot to connect. */
-
- char *sig = va_arg(va,char *);
- void **rx = va_arg(va,void **);
- const char **slot = va_arg(va,const char **);
-
- if ((*rx = sip_api_convert_rx(self,sig,arg,NULL,slot)) == NULL)
- valid = PARSE_RAISED;
-
- break;
- }
-
- case 'Y':
- {
- /* Python slot to disconnect. */
-
- char *sig = va_arg(va,char *);
- void **rx = va_arg(va,void **);
- const char **slot = va_arg(va,const char **);
-
- *rx = sipGetRx(self,sig,arg,NULL,slot);
- break;
- }
-
- case 'J':
- {
- /* Class instance. */
-
- int flags = *fmt++ - '0';
- sipWrapperType *type;
- void **p;
- int iflgs = 0;
- int iserr = FALSE;
- int *state;
- PyObject *xfer, **wrapper;
-
- type = va_arg(va,sipWrapperType *);
- p = va_arg(va,void **);
-
- if (flags & FORMAT_TRANSFER)
- xfer = (self ? (PyObject *)self : arg);
- else if (flags & FORMAT_TRANSFER_BACK)
- xfer = Py_None;
- else
- xfer = NULL;
-
- if (flags & FORMAT_DEREF)
- iflgs |= SIP_NOT_NONE;
-
- if (flags & (FORMAT_GET_WRAPPER|FORMAT_TRANSFER_THIS))
- wrapper = va_arg(va, PyObject **);
-
- if (flags & FORMAT_NO_CONVERTORS)
- {
- iflgs |= SIP_NO_CONVERTORS;
- state = NULL;
- }
- else
- state = va_arg(va, int *);
-
- *p = sip_api_convert_to_instance(arg, type, xfer, iflgs, state, &iserr);
-
- if (iserr)
- valid = PARSE_RAISED;
-
- if (flags & FORMAT_GET_WRAPPER)
- *wrapper = (*p != NULL ? arg : NULL);
- else if (flags & FORMAT_TRANSFER_THIS && *p != NULL)
- *wrapper = arg;
-
- break;
- }
-
- case 'M':
- {
- /* Mapped type instance. */
-
- int flags = *fmt++ - '0';
- sipMappedType *mt;
- void **p;
- int iflgs = 0;
- int iserr = FALSE;
- int *state;
- PyObject *xfer;
-
- mt = va_arg(va, sipMappedType *);
- p = va_arg(va, void **);
- state = va_arg(va, int *);
-
- if (flags & FORMAT_TRANSFER)
- xfer = (self ? (PyObject *)self : arg);
- else if (flags & FORMAT_TRANSFER_BACK)
- xfer = Py_None;
- else
- xfer = NULL;
-
- if (flags & FORMAT_DEREF)
- iflgs |= SIP_NOT_NONE;
-
- *p = sip_api_convert_to_mapped_type(arg, mt, xfer, iflgs, state, &iserr);
-
- if (iserr)
- valid = PARSE_RAISED;
-
- break;
- }
-
- case 'P':
- {
- /*
- * Python object of any type with a
- * sub-format.
- */
-
- PyObject **p = va_arg(va,PyObject **);
- int flags = *fmt++ - '0';
-
- if (flags & FORMAT_TRANSFER)
- {
- Py_XINCREF(*p);
- }
- else if (flags & FORMAT_TRANSFER_BACK)
- {
- Py_XDECREF(*p);
- }
-
- break;
- }
-
- case 'X':
- {
- /* Constrained (ie. exact) type. */
-
- ++fmt;
- va_arg(va,void *);
-
- break;
- }
-
-
- case 'E':
- {
- /* Named enum. */
-
- int *p;
-
- va_arg(va, PyTypeObject *);
- p = va_arg(va, int *);
-
- *p = PyInt_AsLong(arg);
-
- break;
- }
-
- /*
- * Every other argument is a pointer and only differ in how
- * many there are.
- */
- case 'N':
- case 'T':
- case 'a':
- case 'A':
- va_arg(va,void *);
-
- /* Drop through. */
-
- default:
- va_arg(va,void *);
- }
- }
-
- /* Handle any ellipsis argument. */
- if (*fmt == 'W' && valid == PARSE_OK)
- {
- PyObject *al;
-
- /* Create a tuple for any remaining arguments. */
- if ((al = PyTuple_New(nrargs - a)) != NULL)
- {
- int da = 0;
-
- while (a < nrargs)
- {
- PyObject *arg = PyTuple_GET_ITEM(sipArgs,a);
-
- /* Add the remaining argument to the tuple. */
- Py_INCREF(arg);
- PyTuple_SET_ITEM(al, da, arg);
-
- ++a;
- ++da;
- }
-
- /* Return the tuple. */
- *va_arg(va, PyObject **) = al;
- }
- else
- valid = PARSE_RAISED;
- }
-
- return valid;
-}
-
-
-/*
- * Carry out actions common to all ctors.
- */
-static void sip_api_common_ctor(sipMethodCache *cache,int nrmeths)
-{
- /* This is thread safe. */
- while (nrmeths-- > 0)
- cache++->mcflags = 0;
-}
-
-
-/*
- * Carry out actions common to all dtors.
- */
-static void sip_api_common_dtor(sipWrapper *sipSelf)
-{
- if (sipSelf != NULL && sipInterpreter != NULL)
- {
- SIP_BLOCK_THREADS
-
- callPyDtor(sipSelf);
-
- if (!sipNotInMap(sipSelf))
- sipOMRemoveObject(&cppPyMap,sipSelf);
-
- /* This no longer points to anything useful. */
- sipSelf->u.cppPtr = NULL;
-
- /*
- * If C/C++ has a reference (and therefore no parent) then remove it.
- * Otherwise remove the object from any parent.
- */
- if (sipCppHasRef(sipSelf))
- {
- sipResetCppHasRef(sipSelf);
- Py_DECREF(sipSelf);
- }
- else
- removeFromParent(sipSelf);
-
- SIP_UNBLOCK_THREADS
- }
-}
-
-
-/*
- * Call self.__dtor__() if it is implemented.
- */
-static void callPyDtor(sipWrapper *self)
-{
- sip_gilstate_t sipGILState;
- sipMethodCache pymc;
- PyObject *meth;
-
- /* No need to cache the method, it will only be called once. */
- pymc.mcflags = 0;
- meth = sip_api_is_py_method(&sipGILState, &pymc, self, NULL, "__dtor__");
-
- if (meth != NULL)
- {
- PyObject *res = sip_api_call_method(0, meth, "", NULL);
-
- Py_DECREF(meth);
-
- /* Discard any result. */
- Py_XDECREF(res);
-
- SIP_RELEASE_GIL(sipGILState);
- }
-}
-
-
-/*
- * Add a wrapper to it's parent owner if it has one. The wrapper must not
- * currently have a parent and, therefore, no siblings.
- */
-static void addToParent(sipWrapper *self, sipWrapper *owner)
-{
- if (owner != NULL)
- {
- if (owner->first_child != NULL)
- {
- self->sibling_next = owner->first_child;
- owner->first_child->sibling_prev = self;
- }
-
- owner->first_child = self;
- self->parent = owner;
-
- /*
- * The owner holds a real reference so that the cyclic garbage
- * collector works properly.
- */
- Py_INCREF(self);
- }
-}
-
-
-/*
- * Remove a wrapper from it's parent if it has one.
- */
-static void removeFromParent(sipWrapper *self)
-{
- if (self->parent != NULL)
- {
- if (self->parent->first_child == self)
- self->parent->first_child = self->sibling_next;
-
- if (self->sibling_next != NULL)
- self->sibling_next->sibling_prev = self->sibling_prev;
-
- if (self->sibling_prev != NULL)
- self->sibling_prev->sibling_next = self->sibling_next;
-
- self->parent = NULL;
- self->sibling_next = NULL;
- self->sibling_prev = NULL;
-
- /*
- * We must do this last, after all the pointers are correct,
- * because this is used by the clear slot.
- */
- Py_DECREF(self);
- }
-}
-
-
-/*
- * Convert a sequence index. Return the index or a negative value if there was
- * an error.
- */
-static SIP_SSIZE_T sip_api_convert_from_sequence_index(SIP_SSIZE_T idx,
- SIP_SSIZE_T len)
-{
- /* Negative indices start from the other end. */
- if (idx < 0)
- idx = len + idx;
-
- if (idx < 0 || idx >= len)
- {
- PyErr_Format(PyExc_IndexError, "sequence index out of range");
- return -1;
- }
-
- return idx;
-}
-
-
-/*
- * Create and return a single type object.
- */
-static sipWrapperType *createType(sipExportedModuleDef *client,
- sipTypeDef *type, PyObject *mod_dict)
-{
- PyObject *name, *bases, *typedict, *args, *dict;
- sipEncodedClassDef *sup;
- sipWrapperType *wt;
-
- /* Create an object corresponding to the type name. */
- if ((name = getBaseNameObject(type->td_name)) == NULL)
- goto reterr;
-
- /* Create the tuple of super types. */
- if ((sup = type->td_supers) == NULL)
- {
- static PyObject *nobases = NULL;
-
- if (nobases == NULL && (nobases = Py_BuildValue("(O)",&sipWrapper_Type)) == NULL)
- goto relname;
-
- Py_INCREF(nobases);
- bases = nobases;
- }
- else
- {
- int i, nrsupers = 0;
-
- do
- ++nrsupers;
- while (!sup++->sc_flag);
-
- if ((bases = PyTuple_New(nrsupers)) == NULL)
- goto relname;
-
- for (sup = type->td_supers, i = 0; i < nrsupers; ++i, ++sup)
- {
- PyObject *st = (PyObject *)getClassType(sup, client);
-
- Py_INCREF(st);
- PyTuple_SET_ITEM(bases,i,st);
- }
- }
-
- /* Create the type dictionary. */
- if ((typedict = createTypeDict(client->em_nameobj)) == NULL)
- goto relbases;
-
- /* Initialise the rest of the type and pass it via the back door. */
- type->td_module = client;
- currentType = type;
-
- /* Create the type by calling the metatype. */
- if ((args = Py_BuildValue("OOO",name,bases,typedict)) == NULL)
- goto reldict;
-
- if ((wt = (sipWrapperType *)PyObject_Call((PyObject *)&sipWrapperType_Type,args,NULL)) == NULL)
- goto relargs;
-
- /* Get the dictionary into which the type will be placed. */
- if (type->td_scope.sc_flag)
- dict = mod_dict;
- else
- dict = ((PyTypeObject *)getClassType(&type->td_scope, client))->tp_dict;
-
- /* Add the type to the "parent" dictionary. */
- if (PyDict_SetItem(dict,name,(PyObject *)wt) < 0)
- goto reltype;
-
- /* We can now release our references. */
- Py_DECREF(args);
- Py_DECREF(typedict);
- Py_DECREF(bases);
- Py_DECREF(name);
-
- return wt;
-
- /* Unwind after an error. */
-
-reltype:
- Py_DECREF((PyObject *)wt);
-
-relargs:
- Py_DECREF(args);
-
-reldict:
- Py_DECREF(typedict);
-
-relbases:
- Py_DECREF(bases);
-
-relname:
- Py_DECREF(name);
-
-reterr:
- return NULL;
-}
-
-
-/*
- * Create and return an enum type object.
- */
-static PyTypeObject *createEnum(sipExportedModuleDef *client, sipEnumDef *ed,
- PyObject *mod_dict)
-{
- static PyObject *bases = NULL;
- PyObject *name, *typedict, *args, *dict;
- PyTypeObject *et;
-
- /* Get the module and dictionary into which the type will be placed. */
- if (ed->e_scope < 0)
- dict = mod_dict;
- else
- dict = ((PyTypeObject *)client->em_types[ed->e_scope])->tp_dict;
-
- /* Create the base type tuple if it hasn't already been done. */
- if (bases == NULL && (bases = Py_BuildValue("(O)",&PyInt_Type)) == NULL)
- goto reterr;
-
- /* Create an object corresponding to the type name. */
- if ((name = getBaseNameObject(ed->e_name)) == NULL)
- goto reterr;
-
- /* Create the type dictionary. */
- if ((typedict = createTypeDict(client->em_nameobj)) == NULL)
- goto relname;
-
- /* Create the type by calling the metatype. */
- if ((args = Py_BuildValue("OOO",name,bases,typedict)) == NULL)
- goto reldict;
-
- if ((et = (PyTypeObject *)PyObject_Call((PyObject *)&PyType_Type,args,NULL)) == NULL)
- goto relargs;
-
- /* Initialise any slots. */
- if (ed->e_pyslots != NULL)
- initSlots(et, et->tp_as_number, et->tp_as_sequence, et->tp_as_mapping, ed->e_pyslots, TRUE);
-
- /* Add the type to the "parent" dictionary. */
- if (PyDict_SetItem(dict,name,(PyObject *)et) < 0)
- goto reltype;
-
- /* We can now release our references. */
- Py_DECREF(args);
- Py_DECREF(typedict);
- Py_DECREF(name);
-
- return et;
-
- /* Unwind after an error. */
-
-reltype:
- Py_DECREF((PyObject *)et);
-
-relargs:
- Py_DECREF(args);
-
-reldict:
- Py_DECREF(typedict);
-
-relname:
- Py_DECREF(name);
-
-reterr:
- return NULL;
-}
-
-
-/*
- * Return a pointer to the basename of a Python "pathname".
- */
-static const char *getBaseName(const char *name)
-{
- const char *bn;
-
- if ((bn = strrchr(name, '.')) != NULL)
- ++bn;
- else
- bn = name;
-
- return bn;
-}
-
-
-/*
- * Create a Python object corresponding to the basename of a Python "pathname".
- */
-static PyObject *getBaseNameObject(const char *name)
-{
- return PyString_FromString(getBaseName(name));
-}
-
-
-/*
- * Create a type dictionary for dynamic type being created in the module with
- * the specified name.
- */
-static PyObject *createTypeDict(PyObject *mname)
-{
- static PyObject *proto = NULL;
- static PyObject *mstr = NULL;
- PyObject *dict;
-
- /* Create a prototype dictionary. */
- if (proto == NULL)
- {
- if ((proto = PyDict_New()) == NULL)
- return NULL;
-
- /*
- * These tell pickle that SIP generated classes can't be
- * pickled.
- */
- if (PyDict_SetItemString(proto, "__reduce_ex__", Py_None) < 0 ||
- PyDict_SetItemString(proto, "__reduce__", Py_None) < 0)
- {
- Py_DECREF(proto);
- proto = NULL;
-
- return NULL;
- }
- }
-
- /* Create an object for "__module__". */
- if (mstr == NULL && (mstr = PyString_FromString("__module__")) == NULL)
- return NULL;
-
- if ((dict = PyDict_Copy(proto)) == NULL)
- return NULL;
-
- /* We need to set the module name as an attribute for dynamic types. */
- if (PyDict_SetItem(dict, mstr, mname) < 0)
- {
- Py_DECREF(dict);
- return NULL;
- }
-
- return dict;
-}
-
-
-/*
- * Add a set of static instances to a dictionary.
- */
-static int addInstances(PyObject *dict,sipInstancesDef *id)
-{
- if (id->id_class != NULL && addClassInstances(dict,id->id_class) < 0)
- return -1;
-
- if (id->id_voidp != NULL && addVoidPtrInstances(dict,id->id_voidp) < 0)
- return -1;
-
- if (id->id_char != NULL && addCharInstances(dict,id->id_char) < 0)
- return -1;
-
- if (id->id_string != NULL && addStringInstances(dict,id->id_string) < 0)
- return -1;
-
- if (id->id_int != NULL && addIntInstances(dict, id->id_int) < 0)
- return -1;
-
- if (id->id_long != NULL && addLongInstances(dict,id->id_long) < 0)
- return -1;
-
- if (id->id_ulong != NULL && addUnsignedLongInstances(dict, id->id_ulong) < 0)
- return -1;
-
- if (id->id_llong != NULL && addLongLongInstances(dict, id->id_llong) < 0)
- return -1;
-
- if (id->id_ullong != NULL && addUnsignedLongLongInstances(dict, id->id_ullong) < 0)
- return -1;
-
- if (id->id_double != NULL && addDoubleInstances(dict,id->id_double) < 0)
- return -1;
-
- if (id->id_enum != NULL && addEnumInstances(dict,id->id_enum) < 0)
- return -1;
-
- return 0;
-}
-
-
-/*
- * Get "self" from the argument tuple for a method called as
- * Class.Method(self, ...) rather than self.Method(...).
- */
-static int getSelfFromArgs(sipWrapperType *type, PyObject *args, int argnr,
- sipWrapper **selfp)
-{
- PyObject *self;
-
- /* Get self from the argument tuple. */
-
- if (argnr >= PyTuple_GET_SIZE(args))
- return PARSE_UNBOUND;
-
- self = PyTuple_GET_ITEM(args, argnr);
-
- if (!PyObject_TypeCheck(self, (PyTypeObject *)type))
- return PARSE_UNBOUND;
-
- *selfp = (sipWrapper *)self;
-
- return PARSE_OK;
-}
-
-
-/*
- * Handle the result of a call to the class/instance setattro methods.
- */
-static int handleSetLazyAttr(PyObject *nameobj,PyObject *valobj,
- sipWrapperType *wt,sipWrapper *w)
-{
- char *name;
- PyMethodDef *pmd, *vmd;
- sipEnumMemberDef *enm;
-
- /* See if it was a lazy attribute. */
- if ((name = PyString_AsString(nameobj)) == NULL)
- return -1;
-
- pmd = NULL;
- enm = NULL;
- vmd = NULL;
-
- findLazyAttr(wt,name,&pmd,&enm,&vmd,NULL);
-
- if (vmd != NULL)
- {
- if (valobj == NULL)
- {
- PyErr_Format(PyExc_ValueError,"%s.%s cannot be deleted",wt->type->td_name,name);
-
- return -1;
- }
-
- if ((vmd->ml_flags & METH_STATIC) != 0 || w != NULL)
- {
- PyObject *res;
-
- if ((res = (*vmd->ml_meth)((PyObject *)w,valobj)) == NULL)
- return -1;
-
- /* Ignore the result (which should be Py_None). */
- Py_DECREF(res);
-
- return 0;
- }
-
- PyErr_SetObject(PyExc_AttributeError,nameobj);
-
- return -1;
- }
-
- /* It isn't a variable. */
- return 1;
-}
-
-
-/*
- * Handle the result of a call to the class/instance getattro methods.
- */
-static PyObject *handleGetLazyAttr(PyObject *nameobj,sipWrapperType *wt,
- sipWrapper *w)
-{
- char *name;
- PyMethodDef *pmd, *vmd;
- sipEnumMemberDef *enm;
- sipTypeDef *in;
-
- /* If it was an error, propagate it. */
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))
- return NULL;
-
- PyErr_Clear();
-
- /* See if it was a lazy attribute. */
- if ((name = PyString_AsString(nameobj)) == NULL)
- return NULL;
-
- pmd = NULL;
- enm = NULL;
- vmd = NULL;
-
- findLazyAttr(wt,name,&pmd,&enm,&vmd,&in);
-
- if (pmd != NULL)
- return PyCFunction_New(pmd,(PyObject *)w);
-
- if (enm != NULL)
- {
- PyObject *attr;
-
- /*
- * Convert the value to an object. Note that we cannot cache
- * it in the type dictionary because a sub-type might have a
- * lazy attribute of the same name. In this case (because we
- * call the standard getattro code first) this one would be
- * wrongly found in preference to the one in the sub-class.
- * The example in PyQt is TQScrollView::ResizePolicy and
- * TQListView::WidthMode both having a member called Manual.
- * One way around this might be to cache them in a separate
- * dictionary and search that before doing the binary search
- * through the lazy enum table.
- */
- if ((attr = createEnumMember(in, enm)) == NULL)
- return NULL;
-
- return attr;
- }
-
- if (vmd != NULL)
- if ((vmd->ml_flags & METH_STATIC) != 0 || w != NULL)
- return (*vmd->ml_meth)((PyObject *)w,NULL);
-
- PyErr_SetObject(PyExc_AttributeError,nameobj);
-
- return NULL;
-}
-
-
-/*
- * Create a Python object for an enum member.
- */
-static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm)
-{
- if (enm->em_enum < 0)
- return PyInt_FromLong(enm->em_val);
-
- return sip_api_convert_from_named_enum(enm->em_val, td->td_module->em_enums[enm->em_enum]);
-}
-
-
-/*
- * Create a Python object for a member of a named enum.
- */
-PyObject *sip_api_convert_from_named_enum(int eval, PyTypeObject *et)
-{
- PyObject *args, *mo;
-
- if ((args = Py_BuildValue("(i)", eval)) == NULL)
- return NULL;
-
- mo = PyObject_Call((PyObject *)et, args, NULL);
-
- Py_DECREF(args);
-
- return mo;
-}
-
-
-/*
- * Find definition for a lazy class attribute.
- */
-static void findLazyAttr(sipWrapperType *wt,char *name,PyMethodDef **pmdp,
- sipEnumMemberDef **enmp,PyMethodDef **vmdp,
- sipTypeDef **in)
-{
- sipTypeDef *td, *nsx;
- sipEncodedClassDef *sup;
-
- /* The base type doesn't have any type information. */
- if ((td = wt->type) == NULL)
- return;
-
- /* Search the possible linked list of namespace extenders. */
- nsx = td;
-
- do
- {
- /* Try the methods. */
- if (nsx->td_nrmethods > 0 &&
- (*pmdp = (PyMethodDef *)bsearch(name, nsx->td_methods, nsx->td_nrmethods, sizeof (PyMethodDef), compareMethodName)) != NULL)
- return;
-
- /* Try the enum members. */
- if (nsx->td_nrenummembers > 0 &&
- (*enmp = (sipEnumMemberDef *)bsearch(name, nsx->td_enummembers, nsx->td_nrenummembers, sizeof (sipEnumMemberDef), compareEnumMemberName)) != NULL)
- {
- if (in != NULL)
- *in = nsx;
-
- return;
- }
-
- /* Try the variables. Note, these aren't sorted. */
- if (nsx->td_variables != NULL)
- {
- PyMethodDef *md;
-
- for (md = nsx->td_variables; md->ml_name != NULL; ++md)
- if (strcmp(name, md->ml_name) == 0)
- {
- *vmdp = md;
- return;
- }
- }
-
- nsx = nsx->td_nsextender;
- }
- while (nsx != NULL);
-
- /* Check the base classes. */
- if ((sup = td->td_supers) != NULL)
- do
- {
- findLazyAttr(getClassType(sup, td->td_module), name, pmdp, enmp, vmdp, in);
-
- if (*pmdp != NULL || *enmp != NULL || *vmdp != NULL)
- break;
- }
- while (!sup++->sc_flag);
-}
-
-
-/*
- * The bsearch() helper function for searching a sorted method table.
- */
-static int compareMethodName(const void *key,const void *el)
-{
- return strcmp((const char *)key,((const PyMethodDef *)el)->ml_name);
-}
-
-
-/*
- * The bsearch() helper function for searching a sorted enum member table.
- */
-static int compareEnumMemberName(const void *key,const void *el)
-{
- return strcmp((const char *)key,((const sipEnumMemberDef *)el)->em_name);
-}
-
-
-/*
- * Report a function with invalid argument types.
- */
-static void sip_api_no_function(int argsParsed, const char *func)
-{
- badArgs(argsParsed,NULL,func);
-}
-
-
-/*
- * Report a method/function/signal with invalid argument types.
- */
-static void sip_api_no_method(int argsParsed, const char *classname, const char *method)
-{
- badArgs(argsParsed,classname,method);
-}
-
-
-/*
- * Report an abstract method called with an unbound self.
- */
-static void sip_api_abstract_method(const char *classname, const char *method)
-{
- PyErr_Format(PyExc_TypeError,"%s.%s() is abstract and cannot be called as an unbound method", classname, method);
-}
-
-
-/*
- * Handle error reporting for bad arguments to various things.
- */
-static void badArgs(int argsParsed, const char *classname, const char *method)
-{
- char *sep;
- int nrparsed = argsParsed & ~PARSE_MASK;
-
- if (classname != NULL)
- sep = ".";
- else
- {
- classname = "";
- sep = "";
- }
-
- switch (argsParsed & PARSE_MASK)
- {
- case PARSE_FEW:
- PyErr_Format(PyExc_TypeError,"insufficient number of arguments to %s%s%s()",classname,sep,method);
- break;
-
- case PARSE_MANY:
- PyErr_Format(PyExc_TypeError,"too many arguments to %s%s%s(), %d at most expected",classname,sep,method,nrparsed);
- break;
-
- case PARSE_TYPE:
- PyErr_Format(PyExc_TypeError,"argument %d of %s%s%s() has an invalid type",nrparsed + 1,classname,sep,method);
- break;
-
- case PARSE_FORMAT:
- PyErr_Format(PyExc_TypeError,"invalid format to sipParseArgs() from %s%s%s()",classname,sep,method);
- break;
-
- case PARSE_UNBOUND:
- PyErr_Format(PyExc_TypeError,"first argument of unbound method %s%s%s() must be a %s instance",classname,sep,method,classname);
- break;
-
- case PARSE_RAISED:
- /* It has already been taken care of. */
-
- break;
-
- case PARSE_OK:
- /* This is raised by a private re-implementation. */
- PyErr_Format(PyExc_AttributeError,"%s%s%s is a private method",classname,sep,method);
- break;
- }
-}
-
-
-/*
- * Report a bad operator argument. Only a small subset of operators need to
- * be handled (those that don't return Py_NotImplemented).
- */
-static void sip_api_bad_operator_arg(PyObject *self, PyObject *arg,
- sipPySlotType st)
-{
- const char *sn = NULL;
-
- /* Try and get the text to match a Python exception. */
-
- switch (st)
- {
- case concat_slot:
- case iconcat_slot:
- PyErr_Format(PyExc_TypeError, "cannot concatenate '%s' and '%s' objects", self->ob_type->tp_name, arg->ob_type->tp_name);
- break;
-
- case repeat_slot:
- sn = "*";
- break;
-
- case irepeat_slot:
- sn = "*=";
- break;
-
- default:
- sn = "unknown";
- }
-
- if (sn != NULL)
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for %s: '%s' and '%s'", sn, self->ob_type->tp_name, arg->ob_type->tp_name);
-}
-
-
-/*
- * Report a sequence length that does not match the length of a slice.
- */
-static void sip_api_bad_length_for_slice(SIP_SSIZE_T seqlen,
- SIP_SSIZE_T slicelen)
-{
- PyErr_Format(PyExc_ValueError,
-#if PY_VERSION_HEX >= 0x02050000
- "attempt to assign sequence of size %zd to slice of size %zd",
-#else
- "attempt to assign sequence of size %d to slice of size %d",
-#endif
- seqlen, slicelen);
-}
-
-
-/*
- * Report a Python object that cannot be converted to a particular class.
- */
-static void sip_api_bad_class(const char *classname)
-{
- PyErr_Format(PyExc_TypeError,"cannot convert Python object to an instance of %s",classname);
-}
-
-
-/*
- * Report a Python class variable with an unexpected type.
- */
-static void sip_api_bad_set_type(const char *classname,const char *var)
-{
- PyErr_Format(PyExc_TypeError,"invalid type for variable %s.%s",classname,var);
-}
-
-
-/*
- * Report a Python member function with an unexpected return type.
- */
-static void sip_api_bad_catcher_result(PyObject *method)
-{
- const char *cname;
- char *mname;
-
- /*
- * This is part of the public API so we make no assumptions about the
- * method object.
- */
- if (!PyMethod_Check(method) ||
- PyMethod_GET_FUNCTION(method) == NULL ||
- !PyFunction_Check(PyMethod_GET_FUNCTION(method)) ||
- PyMethod_GET_SELF(method) == NULL)
- {
- PyErr_Format(PyExc_TypeError,"invalid argument to sipBadCatcherResult()");
- return;
- }
-
- mname = PyString_AsString(((PyFunctionObject *)PyMethod_GET_FUNCTION(method))->func_name);
-
- if (mname == NULL)
- return;
-
- cname = PyMethod_GET_SELF(method)->ob_type->tp_name;
-
- PyErr_Format(PyExc_TypeError,"invalid result type from %s.%s()",cname,mname);
-}
-
-
-/*
- * Return the name of the class corresponding to a wrapper object. This comes
- * with a reference.
- */
-static PyObject *sip_api_class_name(PyObject *self)
-{
- return PyString_FromString(self->ob_type->tp_name);
-}
-
-
-/*
- * Return non-zero if the object is a C++ instance wrapper.
- */
-int sip_api_wrapper_check(PyObject *o)
-{
- return PyObject_TypeCheck(o,(PyTypeObject *)&sipWrapper_Type);
-}
-
-
-/*
- * Return non-zero if the object is a C++ instance wrapper type.
- */
-static int sipWrapperType_Check(PyObject *op)
-{
- return PyObject_TypeCheck(op,(PyTypeObject *)&sipWrapperType_Type);
-}
-
-
-/*
- * Transfer ownership of a class instance to Python from C/C++.
- */
-static void sip_api_transfer_back(PyObject *self)
-{
- if (self != NULL && sip_api_wrapper_check(self))
- {
- sipWrapper *w = (sipWrapper *)self;
-
- if (sipCppHasRef(w))
- {
- sipResetCppHasRef(w);
- Py_DECREF(w);
- }
- else
- removeFromParent(w);
-
- sipSetPyOwned(w);
- }
-}
-
-
-/*
- * Transfer ownership of a class instance to C/C++ from Python.
- */
-static void sip_api_transfer_to(PyObject *self, PyObject *owner)
-{
- /*
- * There is a legitimate case where we try to transfer a PyObject that
- * may not be a SIP generated class. The virtual handler code calls
- * this function to keep the C/C++ instance alive when it gets rid of
- * the Python object returned by the Python method. A class may have
- * handwritten code that converts a regular Python type - so we can't
- * assume that we can simply cast to sipWrapper.
- */
- if (self != NULL && sip_api_wrapper_check(self) && (owner == NULL || sip_api_wrapper_check(owner)))
- {
- sipWrapper *w = (sipWrapper *)self;
-
- /*
- * Keep the object alive while we do the transfer. If C++ has a
- * reference then there is no need to increment it, just reset the flag
- * and the following decrement will bring everything back to the way it
- * should be.
- */
- if (sipCppHasRef(w))
- sipResetCppHasRef(w);
- else
- {
- Py_INCREF(self);
- removeFromParent(w);
- }
-
- addToParent(w, (sipWrapper *)owner);
-
- Py_DECREF(self);
-
- sipResetPyOwned(w);
- }
-}
-
-
-/*
- * Transfer ownership of a class instance from Python to C/C++, or vice versa.
- * This is deprecated.
- */
-static void sip_api_transfer(PyObject *self, int toCpp)
-{
- if (toCpp)
- sip_api_transfer_to(self, self);
- else
- sip_api_transfer_back(self);
-}
-
-
-/*
- * Add a license to a dictionary.
- */
-static int addLicense(PyObject *dict,sipLicenseDef *lc)
-{
- int rc;
- PyObject *ldict, *proxy, *o;
-
- /* Convert the strings we use to objects if not already done. */
-
- if (licenseName == NULL && (licenseName = PyString_FromString("__license__")) == NULL)
- return -1;
-
- if (licenseeName == NULL && (licenseeName = PyString_FromString("Licensee")) == NULL)
- return -1;
-
- if (typeName == NULL && (typeName = PyString_FromString("Type")) == NULL)
- return -1;
-
- if (timestampName == NULL && (timestampName = PyString_FromString("Timestamp")) == NULL)
- return -1;
-
- if (signatureName == NULL && (signatureName = PyString_FromString("Signature")) == NULL)
- return -1;
-
- /* We use a dictionary to hold the license information. */
- if ((ldict = PyDict_New()) == NULL)
- return -1;
-
- /* The license type is compulsory, the rest are optional. */
- if (lc->lc_type == NULL || (o = PyString_FromString(lc->lc_type)) == NULL)
- goto deldict;
-
- rc = PyDict_SetItem(ldict,typeName,o);
- Py_DECREF(o);
-
- if (rc < 0)
- goto deldict;
-
- if (lc->lc_licensee != NULL)
- {
- if ((o = PyString_FromString(lc->lc_licensee)) == NULL)
- goto deldict;
-
- rc = PyDict_SetItem(ldict,licenseeName,o);
- Py_DECREF(o);
-
- if (rc < 0)
- goto deldict;
- }
-
- if (lc->lc_timestamp != NULL)
- {
- if ((o = PyString_FromString(lc->lc_timestamp)) == NULL)
- goto deldict;
-
- rc = PyDict_SetItem(ldict,timestampName,o);
- Py_DECREF(o);
-
- if (rc < 0)
- goto deldict;
- }
-
- if (lc->lc_signature != NULL)
- {
- if ((o = PyString_FromString(lc->lc_signature)) == NULL)
- goto deldict;
-
- rc = PyDict_SetItem(ldict,signatureName,o);
- Py_DECREF(o);
-
- if (rc < 0)
- goto deldict;
- }
-
- /* Create a read-only proxy. */
- if ((proxy = PyDictProxy_New(ldict)) == NULL)
- goto deldict;
-
- Py_DECREF(ldict);
-
- rc = PyDict_SetItem(dict,licenseName,proxy);
- Py_DECREF(proxy);
-
- return rc;
-
-deldict:
- Py_DECREF(ldict);
-
- return -1;
-}
-
-
-/*
- * Add the void pointer instances to a dictionary.
- */
-static int addVoidPtrInstances(PyObject *dict,sipVoidPtrInstanceDef *vi)
-{
- while (vi->vi_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = sip_api_convert_from_void_ptr(vi->vi_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,vi->vi_name,w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++vi;
- }
-
- return 0;
-}
-
-
-/*
- * Add the char instances to a dictionary.
- */
-static int addCharInstances(PyObject *dict,sipCharInstanceDef *ci)
-{
- while (ci->ci_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyString_FromStringAndSize(&ci->ci_val,1)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,ci->ci_name,w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++ci;
- }
-
- return 0;
-}
-
-
-/*
- * Add the string instances to a dictionary.
- */
-static int addStringInstances(PyObject *dict,sipStringInstanceDef *si)
-{
- while (si->si_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyString_FromString(si->si_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,si->si_name,w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++si;
- }
-
- return 0;
-}
-
-
-/*
- * Add the int instances to a dictionary.
- */
-static int addIntInstances(PyObject *dict, sipIntInstanceDef *ii)
-{
- while (ii->ii_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyInt_FromLong(ii->ii_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict, ii->ii_name, w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++ii;
- }
-
- return 0;
-}
-
-
-/*
- * Add the long instances to a dictionary.
- */
-static int addLongInstances(PyObject *dict,sipLongInstanceDef *li)
-{
- while (li->li_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyLong_FromLong(li->li_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,li->li_name,w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++li;
- }
-
- return 0;
-}
-
-
-/*
- * Add the unsigned long instances to a dictionary.
- */
-static int addUnsignedLongInstances(PyObject *dict, sipUnsignedLongInstanceDef *uli)
-{
- while (uli->uli_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyLong_FromUnsignedLong(uli->uli_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict, uli->uli_name, w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++uli;
- }
-
- return 0;
-}
-
-
-/*
- * Add the long long instances to a dictionary.
- */
-static int addLongLongInstances(PyObject *dict, sipLongLongInstanceDef *lli)
-{
- while (lli->lli_name != NULL)
- {
- int rc;
- PyObject *w;
-
-#if defined(HAVE_LONG_LONG)
- if ((w = PyLong_FromLongLong(lli->lli_val)) == NULL)
-#else
- if ((w = PyLong_FromLong(lli->lli_val)) == NULL)
-#endif
- return -1;
-
- rc = PyDict_SetItemString(dict, lli->lli_name, w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++lli;
- }
-
- return 0;
-}
-
-
-/*
- * Add the unsigned long long instances to a dictionary.
- */
-static int addUnsignedLongLongInstances(PyObject *dict, sipUnsignedLongLongInstanceDef *ulli)
-{
- while (ulli->ulli_name != NULL)
- {
- int rc;
- PyObject *w;
-
-#if defined(HAVE_LONG_LONG)
- if ((w = PyLong_FromUnsignedLongLong(ulli->ulli_val)) == NULL)
-#else
- if ((w = PyLong_FromUnsignedLong(ulli->ulli_val)) == NULL)
-#endif
- return -1;
-
- rc = PyDict_SetItemString(dict, ulli->ulli_name, w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++ulli;
- }
-
- return 0;
-}
-
-
-/*
- * Add the double instances to a dictionary.
- */
-static int addDoubleInstances(PyObject *dict,sipDoubleInstanceDef *di)
-{
- while (di->di_name != NULL)
- {
- int rc;
- PyObject *w;
-
- if ((w = PyFloat_FromDouble(di->di_val)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,di->di_name,w);
- Py_DECREF(w);
-
- if (rc < 0)
- return -1;
-
- ++di;
- }
-
- return 0;
-}
-
-
-/*
- * Wrap a set of enum instances and add them to a dictionary.
- */
-static int addEnumInstances(PyObject *dict, sipEnumInstanceDef *ei)
-{
- while (ei->ei_name != NULL)
- {
- if (addSingleEnumInstance(dict, ei->ei_name, ei->ei_val, *ei->ei_type) < 0)
- return -1;
-
- ++ei;
- }
-
- return 0;
-}
-
-
-/*
- * Wrap a single enum instance and add it to a dictionary.
- */
-static int addSingleEnumInstance(PyObject *dict, const char *name, int value,
- PyTypeObject *type)
-{
- int rc;
- PyObject *w;
-
- if ((w = sip_api_convert_from_named_enum(value, type)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict, name, w);
- Py_DECREF(w);
-
- return rc;
-}
-
-
-/*
- * Wrap an enum instance and add it to a dictionary.
- */
-static int sip_api_add_enum_instance(PyObject *dict, const char *name,
- int value, PyTypeObject *type)
-{
- /* If this is a wrapped type then get the type dictionary. */
- if (sipWrapperType_Check(dict))
- dict = ((PyTypeObject *)dict)->tp_dict;
-
- return addSingleEnumInstance(dict, name, value, type);
-}
-
-
-/*
- * Wrap a set of class instances and add them to a dictionary.
- */
-static int addClassInstances(PyObject *dict, sipClassInstanceDef *ci)
-{
- while (ci->ci_name != NULL)
- {
- if (addSingleClassInstance(dict, ci->ci_name, ci->ci_ptr, *ci->ci_type, ci->ci_flags) < 0)
- return -1;
-
- ++ci;
- }
-
- return 0;
-}
-
-
-/*
- * Wrap a single class instance and add it to a dictionary.
- */
-static int addSingleClassInstance(PyObject *dict, const char *name,
- void *cppPtr, sipWrapperType *wt, int initflags)
-{
- int rc;
- PyObject *w;
-
- if ((w = sipWrapSimpleInstance(cppPtr,wt,NULL,initflags)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,name,w);
- Py_DECREF(w);
-
- return rc;
-}
-
-
-/*
- * Wrap a class instance and add it to a dictionary.
- */
-static int sip_api_add_class_instance(PyObject *dict, const char *name,
- void *cppPtr, sipWrapperType *wt)
-{
- /* If this is a wrapped type then get the type dictionary. */
- if (sipWrapperType_Check(dict))
- dict = ((PyTypeObject *)dict)->tp_dict;
-
- return addSingleClassInstance(dict, name, cppPtr, wt, 0);
-}
-
-
-/*
- * Wrap a mapped type instance and add it to a dictionary.
- */
-static int sip_api_add_mapped_type_instance(PyObject *dict, const char *name,
- void *cppPtr, const sipMappedType *mt)
-{
- int rc;
- PyObject *w;
-
- /* If this is a wrapped type then get the type dictionary. */
- if (sipWrapperType_Check(dict))
- dict = ((PyTypeObject *)dict)->tp_dict;
-
- if ((w = mt->mt_cfrom(cppPtr, NULL)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict, name, w);
- Py_DECREF(w);
-
- return rc;
-}
-
-
-/*
- * Get the C/C++ pointer for a complex object.
- */
-static void *sip_api_get_complex_cpp_ptr(sipWrapper *w)
-{
- if (!sipIsDerived(w))
- {
- PyErr_SetString(PyExc_RuntimeError,"no access to protected functions or signals for objects not created from Python");
-
- return NULL;
- }
-
- if (checkPointer(w->u.cppPtr) < 0)
- return NULL;
-
- return w->u.cppPtr;
-}
-
-
-/*
- * Return the Python member function corresponding to a C/C++ virtual function,
- * if any. If one was found then the Python lock is acquired.
- */
-static PyObject *sip_api_is_py_method(sip_gilstate_t *gil,sipMethodCache *pymc,
- sipWrapper *sipSelf,char *cname,
- char *mname)
-{
- /* We might still have C++ going after the interpreter has gone. */
- if (sipInterpreter == NULL)
- return NULL;
-
- /*
- * It's possible that the Python object has been deleted but the
- * underlying (complex) C/C++ instance is still working and trying to
- * handle virtual functions. Or an instance has started handling
- * virtual functions before its ctor has returned. In either case say
- * there is no Python method.
- */
- if (sipSelf == NULL)
- return NULL;
-
-#ifdef WITH_THREAD
- *gil = PyGILState_Ensure();
-#endif
-
- /* See if we have already looked for the Python method. */
- if (!sipFoundMethod(pymc))
- {
- PyObject *methobj;
-
- /*
- * Using PyMethod_Check() rather than PyCallable_Check() has
- * the added benefits of ensuring the (common) case of there
- * being no Python method is handled as a direct call to C/C++
- * (rather than converted to Python and then back to C/C++) and
- * makes sure that abstract virtuals are trapped.
- */
- if ((methobj = PyObject_GetAttrString((PyObject *)sipSelf,mname)) != NULL)
- {
- if (PyMethod_Check(methobj))
- {
- sipSetIsMethod(pymc);
- sipSaveMethod(&pymc->pyMethod,methobj);
- }
-
- Py_DECREF(methobj);
- }
-
- PyErr_Clear();
-
- sipSetFoundMethod(pymc);
- }
- else if (sipIsMethod(pymc))
- PyErr_Clear();
-
- if (sipIsMethod(pymc))
- return PyMethod_New(pymc->pyMethod.mfunc,pymc->pyMethod.mself,pymc->pyMethod.mclass);
-
- if (cname != NULL)
- PyErr_Format(PyExc_NotImplementedError,"%s.%s() is abstract and must be overridden",cname,mname);
-
-#ifdef WITH_THREAD
- PyGILState_Release(*gil);
-#endif
-
- return NULL;
-}
-
-
-/*
- * Convert a C/C++ pointer to the object that wraps it.
- */
-static PyObject *sip_api_get_wrapper(void *cppPtr,sipWrapperType *type)
-{
- return (PyObject *)sipOMFindObject(&cppPyMap,cppPtr,type);
-}
-
-
-/*
- * Return the C/C++ pointer from a wrapper without any checks.
- */
-void *sipGetAddress(sipWrapper *w)
-{
- if (sipIsAccessFunc(w))
- return (*w->u.afPtr)();
-
- if (sipIsIndirect(w))
- return *((void **)w->u.cppPtr);
-
- return w->u.cppPtr;
-}
-
-
-/*
- * Get the C/C++ pointer from a wrapper and optionally cast it to the required
- * type.
- */
-void *sip_api_get_cpp_ptr(sipWrapper *w,sipWrapperType *type)
-{
- void *ptr = sipGetAddress(w);
-
- if (checkPointer(ptr) < 0)
- return NULL;
-
- if (type != NULL)
- ptr = cast_cpp_ptr(ptr, (sipWrapperType *)w->ob_type, type);
-
- return ptr;
-}
-
-
-/*
- * Cast a C/C++ pointer from a source type to a destination type.
- */
-static void *cast_cpp_ptr(void *ptr, sipWrapperType *src_type,
- sipWrapperType *dst_type)
-{
- sipCastFunc cast = src_type->type->td_cast;
-
- /* C structures don't have cast functions. */
- if (cast != NULL)
- ptr = (*cast)(ptr, dst_type);
-
- return ptr;
-}
-
-
-/*
- * Check that a pointer is non-NULL.
- */
-static int checkPointer(void *ptr)
-{
- if (ptr == NULL)
- {
- PyErr_SetString(PyExc_RuntimeError,"underlying C/C++ object has been deleted");
- return -1;
- }
-
- return 0;
-}
-
-
-/*
- * Check to see if a Python object can be converted to a wrapped type.
- */
-static int sip_api_can_convert_to_instance(PyObject *pyObj,
- sipWrapperType *type, int flags)
-{
- int ok;
- sipConvertToFunc cto = type->type->td_cto;
-
- /* None is handled outside the type checkers. */
- if (pyObj == Py_None)
- ok = ((flags & SIP_NOT_NONE) == 0);
- else if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0)
- ok = PyObject_TypeCheck(pyObj, (PyTypeObject *)type);
- else
- ok = cto(pyObj, NULL, NULL, NULL);
-
- return ok;
-}
-
-
-/*
- * Check to see if a Python object can be converted to a mapped type.
- */
-static int sip_api_can_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt,
- int flags)
-{
- int ok;
-
- /* None is handled outside the type checkers. */
- if (pyObj == Py_None)
- ok = ((flags & SIP_NOT_NONE) == 0);
- else
- ok = mt->mt_cto(pyObj, NULL, NULL, NULL);
-
- return ok;
-}
-
-
-/*
- * Convert a Python object to a C/C++ pointer, assuming a previous call to
- * sip_api_can_convert_to_instance() has been successful. Allow ownership to
- * be transferred and any type convertors to be disabled.
- */
-static void *sip_api_convert_to_instance(PyObject *pyObj, sipWrapperType *type,
- PyObject *transferObj, int flags,
- int *statep, int *iserrp)
-{
- void *cpp = NULL;
- int state = 0;
- sipConvertToFunc cto = type->type->td_cto;
-
- /* Don't convert if there has already been an error. */
- if (!*iserrp)
- {
- /* Do the conversion. */
- if (pyObj == Py_None)
- cpp = NULL;
- else if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0)
- {
- if ((cpp = sip_api_get_cpp_ptr((sipWrapper *)pyObj, type)) == NULL)
- *iserrp = TRUE;
- else if (transferObj != NULL)
- if (transferObj == Py_None)
- sip_api_transfer_back(pyObj);
- else
- sip_api_transfer_to(pyObj, transferObj);
- }
- else
- state = cto(pyObj, &cpp, iserrp, transferObj);
- }
-
- if (statep != NULL)
- *statep = state;
-
- return cpp;
-}
-
-
-/*
- * Convert a Python object to a C/C++ pointer, assuming a previous call to
- * sip_api_can_convert_to_mapped_type() has been successful. Allow ownership
- * to be transferred.
- */
-static void *sip_api_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt,
- PyObject *transferObj, int flags,
- int *statep, int *iserrp)
-{
- void *cpp = NULL;
- int state = 0;
-
- /* Don't convert if there has already been an error. */
- if (!*iserrp)
- if (pyObj == Py_None)
- cpp = NULL;
- else
- state = mt->mt_cto(pyObj, &cpp, iserrp, transferObj);
-
- if (statep != NULL)
- *statep = state;
-
- return cpp;
-}
-
-
-/*
- * Convert a Python object to a C/C++ pointer and raise an exception if it
- * can't be done.
- */
-static void *sip_api_force_convert_to_instance(PyObject *pyObj,
- sipWrapperType *type,
- PyObject *transferObj,
- int flags, int *statep,
- int *iserrp)
-{
- /* Don't even try if there has already been an error. */
- if (*iserrp)
- return NULL;
-
- /* See if the object's type can be converted. */
- if (!sip_api_can_convert_to_instance(pyObj, type, flags))
- {
- PyErr_Format(PyExc_TypeError, "%s cannot be converted to %s in this context", pyObj->ob_type->tp_name, type->type->td_name);
-
- if (statep != NULL)
- *statep = 0;
-
- *iserrp = TRUE;
- return NULL;
- }
-
- /* Do the conversion. */
- return sip_api_convert_to_instance(pyObj, type, transferObj, flags, statep, iserrp);
-}
-
-
-/*
- * Convert a Python object to a C/C++ pointer and raise an exception if it
- * can't be done.
- */
-static void *sip_api_force_convert_to_mapped_type(PyObject *pyObj,
- const sipMappedType *mt,
- PyObject *transferObj,
- int flags, int *statep,
- int *iserrp)
-{
- /* Don't even try if there has already been an error. */
- if (*iserrp)
- return NULL;
-
- /* See if the object's type can be converted. */
- if (!sip_api_can_convert_to_mapped_type(pyObj, mt, flags))
- {
- PyErr_Format(PyExc_TypeError, "%s cannot be converted to %s in this context", pyObj->ob_type->tp_name, mt->mt_name);
-
- if (statep != NULL)
- *statep = 0;
-
- *iserrp = TRUE;
- return NULL;
- }
-
- /* Do the conversion. */
- return sip_api_convert_to_mapped_type(pyObj, mt, transferObj, flags, statep, iserrp);
-}
-
-
-/*
- * Release a possibly temporary instance created by a type convertor.
- */
-static void sip_api_release_instance(void *cpp, sipWrapperType *type, int state)
-{
- /* See if there is something to release. */
- if (state & SIP_TEMPORARY)
- release(cpp, type->type, state);
-}
-
-
-/*
- * Release an instance.
- */
-static void release(void *addr, sipTypeDef *td, int state)
-{
- sipReleaseFunc rel = td->td_release;
-
- /*
- * If there is no release function then it must be a C structure and we can
- * just free it.
- */
- if (rel == NULL)
- sip_api_free(addr);
- else
- rel(addr, state);
-}
-
-
-/*
- * Release a possibly temporary mapped type created by a type convertor.
- */
-static void sip_api_release_mapped_type(void *cpp, const sipMappedType *mt,
- int state)
-{
- /* See if there is something to release. */
- if (state & SIP_TEMPORARY)
- {
- sipReleaseFunc rel = mt->mt_release;
-
- /*
- * If there is no release function then it must be a C
- * structure and we can just free it.
- */
- if (rel == NULL)
- sip_api_free(cpp);
- else
- rel(cpp, state);
- }
-}
-
-
-/*
- * Convert a C/C++ instance to a Python instance.
- */
-PyObject *sip_api_convert_from_instance(void *cpp, sipWrapperType *type,
- PyObject *transferObj)
-{
- PyObject *py;
-
- /* Handle None. */
- if (cpp == NULL)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* Apply any sub-class convertor. */
- if (sipTypeHasSCC(type))
- type = convertSubClass(type, &cpp);
-
- /* See if we have already wrapped it. */
- if ((py = sip_api_get_wrapper(cpp, type)) != NULL)
- Py_INCREF(py);
- else if ((py = sipWrapSimpleInstance(cpp, type, NULL, SIP_SHARE_MAP)) == NULL)
- return NULL;
-
- /* Handle any ownership transfer. */
- if (transferObj != NULL)
- if (transferObj == Py_None)
- sip_api_transfer_back(py);
- else
- sip_api_transfer_to(py, transferObj);
-
- return py;
-}
-
-
-/*
- * Convert a new C/C++ instance to a Python instance.
- */
-static PyObject *sip_api_convert_from_new_instance(void *cpp,
- sipWrapperType *type,
- PyObject *transferObj)
-{
- sipWrapper *owner;
-
- /* Handle None. */
- if (cpp == NULL)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* Apply any sub-class convertor. */
- if (sipTypeHasSCC(type))
- type = convertSubClass(type, &cpp);
-
- /* Handle any ownership transfer. */
- if (transferObj != NULL && transferObj != Py_None)
- owner = (sipWrapper *)transferObj;
- else
- owner = NULL;
-
- return sipWrapSimpleInstance(cpp, type, owner, (owner == NULL ? SIP_PY_OWNED : 0));
-}
-
-
-/*
- * Convert a C/C++ instance implemented as a mapped type to a Python object.
- */
-static PyObject *sip_api_convert_from_mapped_type(void *cpp,
- const sipMappedType *mt,
- PyObject *transferObj)
-{
- /* Handle None. */
- if (cpp == NULL)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return mt->mt_cfrom(cpp, transferObj);
-}
-
-
-/*
- * Convert a Python instance of a class to a C/C++ object pointer, checking
- * that the instance's class is derived from a given base type.
- */
-static void *sip_api_convert_to_cpp(PyObject *sipSelf,sipWrapperType *type,
- int *iserrp)
-{
- return sip_api_convert_to_instance(sipSelf, type, NULL, SIP_NO_CONVERTORS, NULL, iserrp);
-}
-
-
-/*
- * Implement the normal transfer policy for the result of %ConvertToTypeCode,
- * ie. it is temporary unless it is being transferred from Python.
- */
-int sip_api_get_state(PyObject *transferObj)
-{
- return (transferObj == NULL || transferObj == Py_None) ? SIP_TEMPORARY : 0;
-}
-
-
-/*
- * Return the mapped type structure for a particular mapped type.
- */
-static const sipMappedType *sip_api_find_mapped_type(const char *type)
-{
- sipExportedModuleDef *em;
-
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipMappedType **mtypes, *mt;
-
- if ((mtypes = em->em_mappedtypes) == NULL)
- continue;
-
- while ((mt = *mtypes++) != NULL)
- {
- const char *s1 = mt->mt_name, *s2 = type;
-
- /*
- * Compare while ignoring spaces so that we don't impose a rigorous
- * naming standard.
- */
- do
- {
- while (*s1 == ' ')
- ++s1;
-
- while (*s2 == ' ')
- ++s2;
-
- if (*s1 == '\0' && *s2 == '\0')
- return mt;
- }
- while (*s1++ == *s2++);
- }
- }
-
- return NULL;
-}
-
-
-/*
- * Return the type structure for a particular class.
- */
-static sipWrapperType *sip_api_find_class(const char *type)
-{
- sipExportedModuleDef *em;
- size_t type_len = strlen(type);
-
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipWrapperType *wt = findClass(em, type, type_len);
-
- if (wt != NULL)
- return wt;
- }
-
- return NULL;
-}
-
-
-/*
- * Return the type structure for a particular named enum.
- */
-static PyTypeObject *sip_api_find_named_enum(const char *type)
-{
- sipExportedModuleDef *em;
- size_t type_len = strlen(type);
-
- for (em = clientList; em != NULL; em = em->em_next)
- {
- PyTypeObject *py = findEnum(em, type, type_len);
-
- if (py != NULL)
- return py;
- }
-
- return NULL;
-}
-
-
-/*
- * Save the components of a Python method.
- */
-void sipSaveMethod(sipPyMethod *pm,PyObject *meth)
-{
- pm->mfunc = PyMethod_GET_FUNCTION(meth);
- pm->mself = PyMethod_GET_SELF(meth);
- pm->mclass = PyMethod_GET_CLASS(meth);
-}
-
-
-/*
- * Call a hook.
- */
-static void sip_api_call_hook(const char *hookname)
-{
- PyObject *dictofmods, *mod, *dict, *hook, *res;
-
- /* Get the dictionary of modules. */
- if ((dictofmods = PyImport_GetModuleDict()) == NULL)
- return;
-
- /* Get the __builtin__ module. */
- if ((mod = PyDict_GetItemString(dictofmods,"__builtin__")) == NULL)
- return;
-
- /* Get it's dictionary. */
- if ((dict = PyModule_GetDict(mod)) == NULL)
- return;
-
- /* Get the function hook. */
- if ((hook = PyDict_GetItemString(dict,hookname)) == NULL)
- return;
-
- /* Call the hook and discard any result. */
- res = PyObject_CallObject(hook,NULL);
-
- Py_XDECREF(res);
-}
-
-
-/*
- * Call any sub-class convertors for a given type returning a pointer to the
- * sub-type object, and possibly modifying the C++ address (in the case of
- * multiple inheritence).
- */
-static sipWrapperType *convertSubClass(sipWrapperType *type, void **cppPtr)
-{
- sipExportedModuleDef *em;
-
- if (*cppPtr == NULL)
- return NULL;
-
- /*
- * Note that this code depends on the fact that a module appears in the
- * list of modules before any module it imports, ie. sub-class convertors
- * will be invoked for more specific types first.
- */
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipSubClassConvertorDef *scc;
-
- if ((scc = em->em_convertors) == NULL)
- continue;
-
- while (scc->scc_convertor != NULL)
- {
- /*
- * The base type is the "root" class that may have a number of
- * convertors each handling a "branch" of the derived tree of
- * classes. The "root" normally implements the base function that
- * provides the RTTI used by the convertors and is re-implemented
- * by derived classes. We therefore see if the target type is a
- * sub-class of the root, ie. see if the convertor might be able to
- * convert the target type to something more specific.
- */
- if (PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)scc->scc_basetype))
- {
- void *ptr;
- sipWrapperType *subtype;
-
- ptr = cast_cpp_ptr(*cppPtr, type, scc->scc_basetype);
- subtype = (*scc->scc_convertor)(&ptr);
-
- /*
- * We are only interested in types that are not super-classes
- * of the target. This happens either because it is in an
- * earlier convertor than the one that handles the type or it
- * is in a later convertor that handles a different branch of
- * the hierarchy. Either way, the ordering of the modules
- * ensures that there will be no more than one and that it will
- * be the right one.
- */
- if (subtype != NULL && !PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)subtype))
- {
- *cppPtr = ptr;
- return subtype;
- }
- }
-
- ++scc;
- }
- }
-
- /*
- * We haven't found the exact type, so return the most specific type that
- * it must be. This can happen legitimately if the wrapped library is
- * returning an internal class that is down-cast to a more generic class.
- * Also we want this function to be safe when a class doesn't have any
- * convertors.
- */
- return type;
-}
-
-
-/*
- * The bsearch() helper function for searching a sorted string map table.
- */
-static int compareStringMapEntry(const void *key,const void *el)
-{
- return strcmp((const char *)key,((const sipStringTypeClassMap *)el)->typeString);
-}
-
-
-/*
- * A convenience function for %ConvertToSubClassCode for types represented as a
- * string. Returns the Python class object or NULL if the type wasn't
- * recognised.
- */
-static sipWrapperType *sip_api_map_string_to_class(const char *typeString,
- const sipStringTypeClassMap *map,
- int maplen)
-{
- sipStringTypeClassMap *me;
-
- me = (sipStringTypeClassMap *)bsearch((const void *)typeString,
- (const void *)map,maplen,
- sizeof (sipStringTypeClassMap),
- compareStringMapEntry);
-
- return ((me != NULL) ? *me->pyType : NULL);
-}
-
-
-/*
- * The bsearch() helper function for searching a sorted integer map table.
- */
-static int compareIntMapEntry(const void *keyp,const void *el)
-{
- int key = *(int *)keyp;
-
- if (key > ((const sipIntTypeClassMap *)el)->typeInt)
- return 1;
-
- if (key < ((const sipIntTypeClassMap *)el)->typeInt)
- return -1;
-
- return 0;
-}
-
-
-/*
- * A convenience function for %ConvertToSubClassCode for types represented as
- * an integer. Returns the Python class object or NULL if the type wasn't
- * recognised.
- */
-static sipWrapperType *sip_api_map_int_to_class(int typeInt,
- const sipIntTypeClassMap *map,
- int maplen)
-{
- sipIntTypeClassMap *me;
-
- me = (sipIntTypeClassMap *)bsearch((const void *)&typeInt,
- (const void *)map,maplen,
- sizeof (sipIntTypeClassMap),
- compareIntMapEntry);
-
- return ((me != NULL) ? *me->pyType : NULL);
-}
-
-
-/*
- * Raise an unknown exception. Make no assumptions about the GIL.
- */
-static void sip_api_raise_unknown_exception(void)
-{
- static PyObject *mobj = NULL;
-
- SIP_BLOCK_THREADS
-
- if (mobj == NULL)
- mobj = PyString_FromString("unknown");
-
- PyErr_SetObject(PyExc_Exception, mobj);
-
- SIP_UNBLOCK_THREADS
-}
-
-
-/*
- * Raise an exception implemented as a class. Make no assumptions about the
- * GIL.
- */
-static void sip_api_raise_class_exception(sipWrapperType *type,void *ptr)
-{
- PyObject *self;
-
- SIP_BLOCK_THREADS
-
- self = sipWrapSimpleInstance(ptr,type,NULL,SIP_PY_OWNED);
-
- PyErr_SetObject((PyObject *)type,self);
-
- Py_XDECREF(self);
-
- SIP_UNBLOCK_THREADS
-}
-
-
-/*
- * Raise an exception implemented as a class or sub-class. Make no assumptions
- * about the GIL.
- */
-static void sip_api_raise_sub_class_exception(sipWrapperType *type,void *ptr)
-{
- PyObject *self;
-
- SIP_BLOCK_THREADS
-
- self = sipWrapSimpleInstance(ptr,type,NULL,SIP_PY_OWNED);
-
- PyErr_SetObject((PyObject *)type,self);
-
- Py_XDECREF(self);
-
- SIP_UNBLOCK_THREADS
-}
-
-
-/*
- * Return the module of an encoded class.
- */
-static sipExportedModuleDef *getClassModule(sipEncodedClassDef *enc,
- sipExportedModuleDef *em)
-{
- if (enc->sc_module != 255)
- em = em->em_imports[enc->sc_module].im_module;
-
- return em;
-}
-
-
-/*
- * Return the type of an encoded class.
- */
-static sipWrapperType *getClassType(sipEncodedClassDef *enc,
- sipExportedModuleDef *em)
-{
- return getClassModule(enc, em)->em_types[enc->sc_class];
-}
-
-
-/*
- * Find a particular slot function for a wrapper.
- */
-static void *findSlot(PyObject *self,sipPySlotType st)
-{
- sipTypeDef *td = ((sipWrapperType *)(self->ob_type))->type;
- sipEncodedClassDef *sup;
- void *slot;
-
- /* Check the immediate type. */
- if ((slot = findSlotInType(td, st)) != NULL)
- return slot;
-
- /* Check the super-types, if there are any. */
- if ((sup = td->td_supers) != NULL)
- do
- if ((slot = findSlotInType(getClassType(sup, td->td_module)->type, st)) != NULL)
- return slot;
- while (!sup++->sc_flag);
-
- /* This should never happen. */
- return NULL;
-}
-
-
-/*
- * Find a particular slot function in a type.
- */
-static void *findSlotInType(sipTypeDef *td, sipPySlotType st)
-{
- sipPySlotDef *psd;
-
- if ((psd = td->td_pyslots) != NULL)
- while (psd->psd_func != NULL)
- {
- if (psd->psd_type == st)
- return psd->psd_func;
-
- ++psd;
- }
-
- return NULL;
-}
-
-
-/*
- * Return the C/C++ address and the basic type information for a wrapper.
- */
-static void *getPtrTypeDef(sipWrapper *self, sipTypeDef **td)
-{
- *td = ((sipWrapperType *)self->ob_type)->type;
-
- return (sipNotInMap(self) ? NULL : self->u.cppPtr);
-}
-
-
-/*
- * Handle an objobjargproc slot.
- */
-static int objobjargprocSlot(PyObject *self,PyObject *arg1,PyObject *arg2,
- sipPySlotType st)
-{
- int (*f)(PyObject *,PyObject *);
- PyObject *args;
- int res;
-
- /*
- * Slot handlers require a single PyObject *. The second argument is
- * optional.
- */
- if (arg2 == NULL)
- args = arg1;
- else if (PyTuple_Check(arg1))
- {
- int i;
-
- /*
- * It's already a tuple so we need to copy it and append the
- * value.
- */
- if ((args = PyTuple_New(PyTuple_GET_SIZE(arg1) + 1)) == NULL)
- return -1;
-
- for (i = 0; i < PyTuple_GET_SIZE(arg1); ++i)
- {
- PyObject *o = PyTuple_GET_ITEM(arg1,i);
-
- PyTuple_SET_ITEM(args,i,o);
- Py_INCREF(o);
- }
-
- PyTuple_SET_ITEM(args,i,arg2);
- Py_INCREF(arg2);
- }
- else if ((args = Py_BuildValue("(OO)",arg1,arg2)) == NULL)
- return -1;
-
- f = (int (*)(PyObject *,PyObject *))findSlot(self,st);
-
- res = f(self,args);
-
- if (arg2 != NULL)
- {
- Py_DECREF(args);
- }
-
- return res;
-}
-
-
-/*
- * Handle an ssizeobjargproc slot.
- */
-static int ssizeobjargprocSlot(PyObject *self, SIP_SSIZE_T arg1,
- PyObject *arg2, sipPySlotType st)
-{
- int (*f)(PyObject *,PyObject *);
- PyObject *args;
- int res;
-
- /*
- * Slot handlers require a single PyObject *. The second argument is
- * optional.
- */
- if (arg2 == NULL)
-#if PY_VERSION_HEX >= 0x02050000
- args = PyInt_FromSsize_t(arg1);
-#else
- args = PyInt_FromLong(arg1);
-#endif
- else
-#if PY_VERSION_HEX >= 0x02050000
- args = Py_BuildValue("(nO)", arg1, arg2);
-#else
- args = Py_BuildValue("(iO)", arg1, arg2);
-#endif
-
- if (args == NULL)
- return -1;
-
- f = (int (*)(PyObject *,PyObject *))findSlot(self,st);
-
- res = f(self,args);
-
- Py_DECREF(args);
-
- return res;
-}
-
-
-/*****************************************************************************
- * The functions, data types and structures to support a Python type to hold a
- * void * that can be converted to an integer.
- *****************************************************************************/
-
-/* The object data structure. */
-typedef struct {
- PyObject_HEAD
- void *voidptr;
-} sipVoidPtr;
-
-
-/*
- * Implement __new__ for the type.
- */
-static PyObject *sipVoidPtr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
-{
- PyObject *obj;
- void *ptr;
- int nargs, bad;
-
- /* We don't support keyword arguments. */
- if (kwds != NULL)
- {
- PyErr_SetString(PyExc_TypeError, "keyword arguments are not supported");
- return NULL;
- }
-
- /* Get the single argument. */
- if ((nargs = PyTuple_Size(args)) < 0)
- return NULL;
-
- bad = FALSE;
-
- if (nargs == 1)
- {
- PyObject *arg = PyTuple_GET_ITEM(args, 0);
-
- if (arg == Py_None)
- ptr = NULL;
- else if (PyCObject_Check(arg))
- ptr = PyCObject_AsVoidPtr(arg);
- else if (arg->ob_type == &sipVoidPtr_Type)
- {
- /*
- * The type is immutable so just return the argument.
- */
- Py_INCREF(arg);
- return arg;
- }
- else
- {
- ptr = (void *)PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- bad = TRUE;
- }
- }
- else
- bad = TRUE;
-
- if (bad)
- {
- PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None or another voidptr is required");
- return NULL;
- }
-
- /* Create the instance. */
- if ((obj = subtype->tp_alloc(subtype, 0)) == NULL)
- return NULL;
-
- /* Save the pointer. */
- ((sipVoidPtr *)obj)->voidptr = ptr;
-
- return obj;
-}
-
-
-/*
- * Implement int() for the type.
- */
-static PyObject *sipVoidPtr_int(sipVoidPtr *v)
-{
- return PyInt_FromLong((long)v->voidptr);
-}
-
-
-/*
- * Implement hex() for the type.
- */
-static PyObject *sipVoidPtr_hex(sipVoidPtr *v)
-{
- char buf[2 + 16 + 1];
-
- PyOS_snprintf(buf, sizeof (buf), "0x%.*lx", (int)(sizeof (void *) * 2), (unsigned long)v->voidptr);
-
- return PyString_FromString(buf);
-}
-
-
-/*
- * Implement ascobject() for the type.
- */
-static PyObject *sipVoidPtr_ascobject(sipVoidPtr *v, PyObject *arg)
-{
- return PyCObject_FromVoidPtr(v->voidptr, NULL);
-}
-
-
-/*
- * Implement asstring() for the type.
- */
-static PyObject *sipVoidPtr_asstring(sipVoidPtr *v,PyObject *arg)
-{
- long nbytes = PyInt_AsLong(arg);
-
- if (PyErr_Occurred())
- return NULL;
-
- return PyString_FromStringAndSize(v->voidptr,nbytes);
-}
-
-
-/* The methods data structure. */
-static PyMethodDef sipVoidPtr_Methods[] = {
- {"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL},
- {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_O, NULL},
- {NULL}
-};
-
-
-/* The number methods data structure. */
-PyNumberMethods sipVoidPtr_NumberMethods = {
- 0, /* nb_add */
- 0, /* nb_subtract */
- 0, /* nb_multiply */
- 0, /* nb_divide */
- 0, /* nb_remainder */
- 0, /* nb_divmod */
- 0, /* nb_power */
- 0, /* nb_negative */
- 0, /* nb_positive */
- 0, /* nb_absolute */
- 0, /* nb_nonzero */
- 0, /* nb_invert */
- 0, /* nb_lshift */
- 0, /* nb_rshift */
- 0, /* nb_and */
- 0, /* nb_xor */
- 0, /* nb_or */
- 0, /* nb_coerce */
- (unaryfunc)sipVoidPtr_int, /* nb_int */
- 0, /* nb_long */
- 0, /* nb_float */
- 0, /* nb_oct */
- (unaryfunc)sipVoidPtr_hex, /* nb_hex */
-};
-
-
-/* The type data structure. */
-static PyTypeObject sipVoidPtr_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "sip.voidptr", /* tp_name */
- sizeof (sipVoidPtr), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- &sipVoidPtr_NumberMethods, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- sipVoidPtr_Methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- sipVoidPtr_new, /* tp_new */
-};
-
-
-/*
- * A convenience function to convert a C/C++ void pointer from a Python object.
- */
-static void *sip_api_convert_to_void_ptr(PyObject *obj)
-{
- if (obj == NULL)
- {
- PyErr_SetString(PyExc_TypeError,"sip.voidptr is NULL");
- return NULL;
- }
-
- if (obj == Py_None)
- return NULL;
-
- /* Save a conversion if it's not a sub-type. */
- if (obj->ob_type == &sipVoidPtr_Type)
- return ((sipVoidPtr *)obj)->voidptr;
-
- return (void *)PyInt_AsLong(obj);
-}
-
-
-/*
- * A convenience function to convert a C/C++ void pointer to a Python object.
- */
-PyObject *sip_api_convert_from_void_ptr(void *val)
-{
- sipVoidPtr *self;
-
- if (val == NULL)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- if ((self = PyObject_NEW(sipVoidPtr,&sipVoidPtr_Type)) == NULL)
- return NULL;
-
- self->voidptr = val;
-
- return (PyObject *)self;
-}
-
-
-/*
- * Return TRUE if a type is a wrapped type, rather than a sub-type implemented
- * in Python or the super-type.
- */
-static int isExactWrappedType(sipWrapperType *wt)
-{
- char *name;
-
- /*
- * We check by comparing the actual type name with the name used to create
- * the original wrapped type.
- */
-#if PY_VERSION_HEX >= 0x02050000
- if ((name = PyString_AsString(wt->super.ht_name)) == NULL)
-#else
- if ((name = PyString_AsString(wt->super.name)) == NULL)
-#endif
- return FALSE;
-
- return (strcmp(name, getBaseName(wt->type->td_name)) == 0);
-}
-
-
-/*****************************************************************************
- * The Python metatype for a C++ wrapper type.
- *****************************************************************************/
-
-/*
- * The type alloc slot.
- */
-static PyObject *sipWrapperType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems)
-{
- PyObject *o;
-
- /* Call the standard super-metatype alloc. */
- if ((o = PyType_Type.tp_alloc(self, nitems)) == NULL)
- return NULL;
-
- /*
- * Consume any extra type specific information and use it to initialise
- * the slots. This only happens for directly wrapped classes (and not
- * programmer written sub-classes). This must be done in the alloc
- * function because it is the only place we can break out of the
- * default new() function before PyType_Ready() is called.
- */
- if (currentType != NULL)
- {
- ((sipWrapperType *)o)->type = currentType;
- addSlots((sipWrapperType *)o, currentType);
- currentType = NULL;
- }
-
- return o;
-}
-
-
-/*
- * The type init slot.
- */
-static int sipWrapperType_init(sipWrapperType *self, PyObject *args,
- PyObject *kwds)
-{
- /* Call the standard super-metatype init. */
- if (PyType_Type.tp_init((PyObject *)self, args, kwds) < 0)
- return -1;
-
- /*
- * If we don't yet have any extra type specific information (because we are
- * a programmer defined sub-class) then get it from the (first) super-type.
- */
- if (self->type == NULL)
- {
- PyTypeObject *sc = ((PyTypeObject *)self)->tp_base;
-
- /*
- * Make sure that the type is derived from sip.wrapper. It might not
- * if the type specifies sip.wrappertype as the __metaclass__.
- */
- if (sc == NULL || !sipWrapperType_Check((PyObject *)sc))
- {
- PyErr_Format(PyExc_TypeError,
- "type %s must be derived from sip.wrapper",
- ((PyTypeObject *)self)->tp_name);
-
- return -1;
- }
-
- self->type = ((sipWrapperType *)sc)->type;
- }
-
- return 0;
-}
-
-
-/*
- * The type getattro slot.
- */
-static PyObject *sipWrapperType_getattro(PyObject *obj,PyObject *name)
-{
- char *nm;
- PyObject *attr;
- sipWrapperType *wt = (sipWrapperType *)obj;
-
- /*
- * If we are getting the type dictionary for a base wrapped type then we
- * don't want the super-metatype to handle it.
- */
- if ((nm = PyString_AsString(name)) == NULL)
- return NULL;
-
- if (strcmp(nm, "__dict__") == 0)
- {
- int i;
- sipTypeDef *td;
- sipEnumMemberDef *enm;
- PyObject *dict;
- PyMethodDef *pmd;
-
- dict = ((PyTypeObject *)wt)->tp_dict;
-
- /* The base type doesn't have any type information. */
- if ((td = wt->type) == NULL || !isExactWrappedType(wt))
- {
- Py_INCREF(dict);
- return dict;
- }
-
- /*
- * We can't cache the methods or variables so we need to make a
- * temporary copy of the type dictionary and return that (so
- * that it will get garbage collected immediately afterwards).
- */
- if ((dict = PyDict_Copy(dict)) == NULL)
- return NULL;
-
- /* Search the possible linked list of namespace extenders. */
- do
- {
- /*
- * Add the type's lazy enums. It doesn't matter if
- * they are already there.
- */
- enm = td->td_enummembers;
-
- for (i = 0; i < td->td_nrenummembers; ++i)
- {
- int rc;
- PyObject *val;
-
- if ((val = createEnumMember(td, enm)) == NULL)
- return NULL;
-
- rc = PyDict_SetItemString(dict, enm->em_name, val);
-
- Py_DECREF(val);
-
- if (rc < 0)
- return NULL;
-
- ++enm;
- }
-
- /* Do the methods. */
- pmd = td->td_methods;
-
- for (i = 0; i < td->td_nrmethods; ++i)
- {
- int rc;
- PyObject *meth;
-
- if ((meth = PyCFunction_New(pmd, NULL)) == NULL)
- {
- Py_DECREF(dict);
- return NULL;
- }
-
- rc = PyDict_SetItemString(dict, pmd->ml_name, meth);
-
- Py_DECREF(meth);
-
- if (rc < 0)
- {
- Py_DECREF(dict);
- return NULL;
- }
-
- ++pmd;
- }
-
- /* Do the static variables. */
- if ((pmd = td->td_variables) != NULL)
- while (pmd->ml_name != NULL)
- {
- if ((pmd->ml_flags & METH_STATIC) != 0)
- {
- int rc;
- PyObject *val;
-
- if ((val = (*pmd->ml_meth)(NULL, NULL)) == NULL)
- {
- Py_DECREF(dict);
- return NULL;
- }
-
- rc = PyDict_SetItemString(dict, pmd->ml_name, val);
-
- Py_DECREF(val);
-
- if (rc < 0)
- {
- Py_DECREF(dict);
- return NULL;
- }
- }
-
- ++pmd;
- }
-
- td = td->td_nsextender;
- }
- while (td != NULL);
-
- return dict;
- }
-
- /* Now try the super-metatype's method. */
- if ((attr = PyType_Type.tp_getattro(obj,name)) != NULL)
- return attr;
-
- return handleGetLazyAttr(name,wt,NULL);
-}
-
-
-/*
- * The type setattro slot.
- */
-static int sipWrapperType_setattro(PyObject *obj,PyObject *name,PyObject *value)
-{
- int rc;
-
- rc = handleSetLazyAttr(name,value,(sipWrapperType *)obj,NULL);
-
- if (rc <= 0)
- return rc;
-
- /* Try the super-type's method last. */
- return PyType_Type.tp_setattro(obj,name,value);
-}
-
-
-/*
- * The type data structure. We inherit everything from the standard Python
- * metatype except the init and getattro methods and the size of the type
- * object created is increased to accomodate the extra information we associate
- * with a wrapped type.
- */
-static PyTypeObject sipWrapperType_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "sip.wrappertype", /* tp_name */
- sizeof (sipWrapperType), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- sipWrapperType_getattro, /* tp_getattro */
- sipWrapperType_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)sipWrapperType_init, /* tp_init */
- sipWrapperType_alloc, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
-};
-
-
-/*****************************************************************************
- * The Python type that is the super-type for all C++ wrapper types.
- *****************************************************************************/
-
-/*
- * The instance new slot.
- */
-static PyObject *sipWrapper_new(sipWrapperType *wt,PyObject *args,PyObject *kwds)
-{
- /* See if it is a namespace. */
- if (wt->type->td_fcto == NULL)
- {
- PyErr_Format(PyExc_TypeError, "%s represents a C++ namespace that cannot be instantiated", wt->type->td_name);
-
- return NULL;
- }
-
- /*
- * See if the object is being created explicitly rather than being wrapped.
- */
- if (sipGetPending(NULL, NULL) == NULL)
- {
- /*
- * See if it cannot be instantiated or sub-classed from Python, eg.
- * it's an opaque class. Some restrictions might be overcome with
- * better SIP support.
- */
- if (wt->type->td_init == NULL)
- {
- PyErr_Format(PyExc_TypeError,"%s cannot be instantiated or sub-classed", wt->type->td_name);
-
- return NULL;
- }
-
- /* See if it is an abstract type. */
- if (sipTypeIsAbstract(wt) && strcmp(strchr(wt->type->td_name, '.') + 1, ((PyTypeObject *)wt)->tp_name) == 0)
- {
- PyErr_Format(PyExc_TypeError, "%s represents a C++ abstract class and cannot be instantiated", wt->type->td_name);
-
- return NULL;
- }
- }
-
- /* Call the standard super-type new. */
- return PyBaseObject_Type.tp_new((PyTypeObject *)wt, args, kwds);
-}
-
-
-/*
- * The instance init slot.
- */
-static int sipWrapper_init(sipWrapper *self,PyObject *args,PyObject *kwds)
-{
- void *sipNew;
- int sipFlags;
- sipWrapper *owner;
-
- if (self->ob_type == (PyTypeObject *)&sipWrapper_Type)
- {
- PyErr_SetString(PyExc_TypeError,"the sip.wrapper type cannot be instantiated");
- return -1;
- }
-
- if (kwds != NULL)
- {
- PyErr_SetString(PyExc_TypeError,"keyword arguments are not supported");
- return -1;
- }
-
- /* Check there is no existing C++ instance waiting to be wrapped. */
- if ((sipNew = sipGetPending(&owner, &sipFlags)) == NULL)
- {
- int argsparsed = 0;
- sipWrapperType *wt = (sipWrapperType *)self->ob_type;
-
- /* Call the C++ ctor. */
- owner = NULL;
-
- if ((sipNew = wt->type->td_init(self, args, &owner, &argsparsed)) != NULL)
- sipFlags = SIP_DERIVED_CLASS;
- else
- {
- int pstate = argsparsed & PARSE_MASK;
- sipInitExtenderDef *ie = wt->iextend;
-
- /*
- * While we just have signature errors, try any initialiser
- * extenders.
- */
- while (ie != NULL && (pstate == PARSE_MANY || pstate == PARSE_FEW || pstate == PARSE_TYPE))
- {
- argsparsed = 0;
-
- if ((sipNew = ie->ie_extender(self, args, &owner, &argsparsed)) != NULL)
- break;
-
- pstate = argsparsed & PARSE_MASK;
- ie = ie->ie_next;
- }
-
- if (sipNew == NULL)
- {
- /*
- * If the arguments were parsed without error then assume an
- * exception has already been raised for why the instance
- * wasn't created.
- */
- if (pstate == PARSE_OK)
- argsparsed = PARSE_RAISED;
-
- badArgs(argsparsed, NULL, getBaseName(wt->type->td_name));
- return -1;
- }
-
- sipFlags = 0;
- }
-
- if (owner == NULL)
- sipFlags |= SIP_PY_OWNED;
- }
-
- addToParent(self, owner);
-
- self->u.cppPtr = sipNew;
- self->flags = sipFlags;
-
- if (!sipNotInMap(self))
- sipOMAddObject(&cppPyMap,self);
-
- return 0;
-}
-
-
-/*
- * The instance traverse slot.
- */
-static int sipWrapper_traverse(sipWrapper *self, visitproc visit, void *arg)
-{
- int vret;
- void *ptr;
- sipTypeDef *td;
- sipWrapper *w;
- sipPySig *ps;
-
- /* Call the nearest handwritten traverse code in the class hierachy. */
- if ((ptr = getPtrTypeDef(self, &td)) != NULL)
- {
- sipTypeDef *ctd = td;
-
- if (td->td_traverse == NULL)
- {
- sipEncodedClassDef *sup;
-
- if ((sup = td->td_supers) != NULL)
- do
- ctd = getClassType(sup, td->td_module)->type;
- while (ctd->td_traverse == NULL && !sup++->sc_flag);
- }
-
- if (ctd->td_traverse != NULL)
- if ((vret = ctd->td_traverse(ptr, visit, arg)) != 0)
- return vret;
- }
-
- if (qt_and_sip_api_3_4())
- {
- void *tx = sipGetAddress(self);
-
- if (tx != NULL)
- {
- sipSlotConnection *conn;
- void *context = NULL;
-
- while ((conn = sipQtSupport->qt_find_connection(tx, &context)) != NULL)
- {
- if ((vret = visitSlot(&conn->sc_slot, visit, arg)) != 0)
- return vret;
-
- if (context == NULL)
- break;
- }
- }
- }
-
- for (ps = self->pySigList; ps != NULL; ps = ps->next)
- {
- sipSlotList *psrx;
-
- for (psrx = ps->rxlist; psrx != NULL; psrx = psrx->next)
- if ((vret = visitSlot(&psrx->rx, visit, arg)) != 0)
- return vret;
- }
-
- if (self->user != NULL)
- if ((vret = visit(self->user, arg)) != 0)
- return vret;
-
- if (self->dict != NULL)
- if ((vret = visit(self->dict, arg)) != 0)
- return vret;
-
- for (w = self->first_child; w != NULL; w = w->sibling_next)
- {
- /*
- * We don't traverse if the wrapper is a child of itself. We
- * do this so that wrapped objects returned by virtual methods
- * with the /Factory/ don't have those objects collected. This
- * then means that plugins implemented in Python have a chance
- * of working.
- */
- if (w != self)
- if ((vret = visit((PyObject *)w, arg)) != 0)
- return vret;
- }
-
- return 0;
-}
-
-
-/*
- * The instance clear slot.
- */
-static int sipWrapper_clear(sipWrapper *self)
-{
- int vret = 0;
- void *ptr;
- sipTypeDef *td;
- PyObject *tmp;
- sipPySig *ps;
-
- /* Call the nearest handwritten clear code in the class hierachy. */
- if ((ptr = getPtrTypeDef(self, &td)) != NULL)
- {
- sipTypeDef *ctd = td;
-
- if (td->td_clear == NULL)
- {
- sipEncodedClassDef *sup;
-
- if ((sup = td->td_supers) != NULL)
- do
- ctd = getClassType(sup, td->td_module)->type;
- while (ctd->td_clear == NULL && !sup++->sc_flag);
- }
-
- if (ctd->td_clear != NULL)
- vret = ctd->td_clear(ptr);
- }
-
- /* Remove any lambda slots connected via a proxy. */
- if (qt_and_sip_api_3_4())
- {
- void *tx = sipGetAddress(self);
-
- if (tx != NULL)
- {
- sipSlotConnection *conn;
- void *context = NULL;
-
- while ((conn = sipQtSupport->qt_find_connection(tx, &context)) != NULL)
- {
- clearAnyLambda(&conn->sc_slot);
-
- if (context == NULL)
- break;
- }
- }
- }
-
- /* Remove any lambda slots connected to PyQt v3 Python signals. */
- for (ps = self->pySigList; ps != NULL; ps = ps->next)
- {
- sipSlotList *psrx;
-
- for (psrx = ps->rxlist; psrx != NULL; psrx = psrx->next)
- clearAnyLambda(&psrx->rx);
- }
-
- /* Remove any user object. */
- tmp = self->user;
- self->user = NULL;
- Py_XDECREF(tmp);
-
- /* Remove the instance dictionary. */
- tmp = self->dict;
- self->dict = NULL;
- Py_XDECREF(tmp);
-
- /* Detach children (which will be owned by C/C++. */
- while (self->first_child != NULL)
- {
- /*
- * Although this object is being garbage collected it doesn't follow
- * that it's children should be. So we make sure that the child stays
- * alive and remember we have done so.
- */
- Py_INCREF(self->first_child);
- sipSetCppHasRef(self->first_child);
-
- removeFromParent(self->first_child);
- }
-
- return vret;
-}
-
-
-/*
- * The instance read buffer slot.
- */
-static SIP_SSIZE_T sipWrapper_getreadbuffer(sipWrapper *self,
- SIP_SSIZE_T segment, void **ptrptr)
-{
- void *ptr;
- sipTypeDef *td;
-
- if ((ptr = getPtrTypeDef(self, &td)) == NULL)
- return -1;
-
- return td->td_readbuffer((PyObject *)self, ptr, segment, ptrptr);
-}
-
-
-/*
- * The instance write buffer slot.
- */
-static SIP_SSIZE_T sipWrapper_getwritebuffer(sipWrapper *self,
- SIP_SSIZE_T segment, void **ptrptr)
-{
- void *ptr;
- sipTypeDef *td;
-
- if ((ptr = getPtrTypeDef(self, &td)) == NULL)
- return -1;
-
- return td->td_writebuffer((PyObject *)self, ptr, segment, ptrptr);
-}
-
-
-/*
- * The instance segment count slot.
- */
-static SIP_SSIZE_T sipWrapper_getsegcount(sipWrapper *self, SIP_SSIZE_T *lenp)
-{
- void *ptr;
- sipTypeDef *td;
-
- if ((ptr = getPtrTypeDef(self, &td)) == NULL)
- return 0;
-
- return td->td_segcount((PyObject *)self, ptr, lenp);
-}
-
-
-/*
- * The instance char buffer slot.
- */
-static SIP_SSIZE_T sipWrapper_getcharbuffer(sipWrapper *self,
- SIP_SSIZE_T segment, void **ptrptr)
-{
- void *ptr;
- sipTypeDef *td;
-
- if ((ptr = getPtrTypeDef(self, &td)) == NULL)
- return -1;
-
- return td->td_charbuffer((PyObject *)self, ptr, segment, ptrptr);
-}
-
-
-/*
- * The instance dealloc slot.
- */
-static void sipWrapper_dealloc(sipWrapper *self)
-{
- sipTypeDef *td;
-
- if (getPtrTypeDef(self, &td) != NULL)
- {
- /*
- * Remove the object from the map before calling the class specific
- * dealloc code. This code calls the C++ dtor and may result in
- * further calls that pass the instance as an argument. If this is
- * still in the map then it's reference count would be increased (to
- * one) and bad things happen when it drops back to zero again. (An
- * example is PyQt events generated during the dtor call being passed
- * to an event filter implemented in Python.) By removing it from the
- * map first we ensure that a new Python object is created.
- */
- sipOMRemoveObject(&cppPyMap, self);
-
- /* Call the C++ dtor if there is one. */
- if (td->td_dealloc != NULL)
- td->td_dealloc(self);
- }
-
- /*
- * Now that the C++ object no longer exists we can tidy up the Python
- * object. We used to do this first but that meant lambda slots were
- * removed too soon (if they were connected to TQObject.destroyed()).
- */
- sipWrapper_clear(self);
-
- while (self->pySigList != NULL)
- {
- sipPySig *ps;
- sipSlotList *psrx;
-
- /* Take this one out of the list. */
- ps = self->pySigList;
- self->pySigList = ps->next;
-
- while ((psrx = ps->rxlist) != NULL)
- {
- ps->rxlist = psrx->next;
- sipFreeSlotList(psrx);
- }
-
- sip_api_free(ps->name);
- sip_api_free(ps);
- }
-
- /* Call the standard super-type dealloc. */
- PyBaseObject_Type.tp_dealloc((PyObject *)self);
-}
-
-
-/*
- * The instance call slot. Note that keyword arguments aren't supported.
- */
-static PyObject *sipWrapper_call(PyObject *self,PyObject *args,PyObject *kw)
-{
- PyObject *(*f)(PyObject *,PyObject *);
-
- f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self,call_slot);
-
- return f(self,args);
-}
-
-
-/*
- * The sequence instance item slot.
- */
-static PyObject *sipWrapper_sq_item(PyObject *self, SIP_SSIZE_T n)
-{
- PyObject *(*f)(PyObject *,PyObject *);
- PyObject *arg, *res;
-
-#if PY_VERSION_HEX >= 0x02050000
- if ((arg = PyInt_FromSsize_t(n)) == NULL)
-#else
- if ((arg = PyInt_FromLong(n)) == NULL)
-#endif
- return NULL;
-
- f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self,getitem_slot);
-
- res = f(self,arg);
-
- Py_DECREF(arg);
-
- return res;
-}
-
-
-/*
- * The mapping instance assign subscript slot.
- */
-static int sipWrapper_mp_ass_subscript(PyObject *self,PyObject *key,
- PyObject *value)
-{
- return objobjargprocSlot(self,key,value,(value != NULL ? setitem_slot : delitem_slot));
-}
-
-
-/*
- * The sequence instance assign item slot.
- */
-static int sipWrapper_sq_ass_item(PyObject *self, SIP_SSIZE_T i, PyObject *o)
-{
- return ssizeobjargprocSlot(self, i, o, (o != NULL ? setitem_slot : delitem_slot));
-}
-
-
-/*
- * The instance rich compare slot.
- */
-static PyObject *sipWrapper_richcompare(PyObject *self,PyObject *arg,int op)
-{
- PyObject *(*f)(PyObject *,PyObject *);
- sipPySlotType st;
-
- /* Convert the operation to a slot type. */
- switch (op)
- {
- case Py_LT:
- st = lt_slot;
- break;
-
- case Py_LE:
- st = le_slot;
- break;
-
- case Py_EQ:
- st = eq_slot;
- break;
-
- case Py_NE:
- st = ne_slot;
- break;
-
- case Py_GT:
- st = gt_slot;
- break;
-
- case Py_GE:
- st = ge_slot;
- break;
- }
-
- /* It might not exist if not all the above have been implemented. */
- if ((f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self,st)) == NULL)
- {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- return f(self,arg);
-}
-
-
-/*
- * The instance getattro slot.
- */
-static PyObject *sipWrapper_getattro(PyObject *obj,PyObject *name)
-{
- char *nm;
- PyObject *attr;
- sipWrapperType *wt = (sipWrapperType *)obj->ob_type;
- sipWrapper *w = (sipWrapper *)obj;
-
- /*
- * If we are getting the instance dictionary of a base wrapper type
- * then we don't want the metatype to handle it.
- */
- if ((nm = PyString_AsString(name)) == NULL)
- return NULL;
-
- if (strcmp(nm, "__dict__") == 0)
- {
- PyObject *tmpdict = NULL;
-
- if (isExactWrappedType(wt) && getNonStaticVariables(wt, w, &tmpdict) < 0)
- {
- Py_XDECREF(tmpdict);
- return NULL;
- }
-
- /*
- * If a copy of the instance dictionary wasn't created then
- * just return the original. Note that Python doesn't want a
- * proxy.
- */
- if (tmpdict == NULL)
- if ((tmpdict = w->dict) == NULL)
- tmpdict = PyDict_New();
- else
- Py_INCREF(tmpdict);
-
- return tmpdict;
- }
-
- /* Try the super-type's method first. */
- if ((attr = PyBaseObject_Type.tp_getattro(obj,name)) != NULL)
- return attr;
-
- return handleGetLazyAttr(name,wt,w);
-}
-
-
-/*
- * Add the values of all non-static variables to a dictionary (first making a
- * copy of the dictionary if needed).
- */
-static int getNonStaticVariables(sipWrapperType *wt,sipWrapper *w,
- PyObject **ndict)
-{
- PyMethodDef *pmd;
-
- if ((pmd = wt->type->td_variables) != NULL)
- while (pmd->ml_name != NULL)
- {
- if ((pmd->ml_flags & METH_STATIC) == 0)
- {
- int rc;
- PyObject *val, *dict;
-
- /*
- * Create a copy of the original dictionary if
- * it hasn't already been done.
- */
- if ((dict = *ndict) == NULL)
- {
- if ((dict = PyDict_Copy(w->dict)) == NULL)
- return -1;
-
- *ndict = dict;
- }
-
- if ((val = (*pmd->ml_meth)((PyObject *)w,NULL)) == NULL)
- return -1;
-
- rc = PyDict_SetItemString(dict,pmd->ml_name,val);
-
- Py_DECREF(val);
-
- if (rc < 0)
- return -1;
- }
-
- ++pmd;
- }
-
- return 0;
-}
-
-
-/*
- * The instance setattro slot.
- */
-static int sipWrapper_setattro(PyObject *obj,PyObject *name,PyObject *value)
-{
- int rc;
-
- rc = handleSetLazyAttr(name,value,(sipWrapperType *)obj->ob_type,(sipWrapper *)obj);
-
- if (rc <= 0)
- return rc;
-
- /* Try the super-type's method last. */
- return PyBaseObject_Type.tp_setattro(obj,name,value);
-}
-
-
-/*
- * The type data structure. Note that we pretend to be a mapping object and a
- * sequence object at the same time. Python will choose one over another,
- * depending on the context, but we implement as much as we can and don't make
- * assumptions about which Python will choose.
- */
-static sipWrapperType sipWrapper_Type = {
- {
- {
- PyObject_HEAD_INIT(&sipWrapperType_Type)
- 0, /* ob_size */
- "sip.wrapper", /* tp_name */
- sizeof (sipWrapper), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)sipWrapper_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- sipWrapper_getattro, /* tp_getattro */
- sipWrapper_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- 0, /* tp_doc */
- (traverseproc)sipWrapper_traverse, /* tp_traverse */
- (inquiry)sipWrapper_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(sipWrapper,dict), /* tp_dictoffset */
- (initproc)sipWrapper_init, /* tp_init */
- 0, /* tp_alloc */
- (newfunc)sipWrapper_new, /* tp_new */
- 0, /* tp_free */
- },
- },
- 0,
- 0
-};
-
-
-/*
- * Add the slots for a type and all its super-types.
- */
-static void addSlots(sipWrapperType *wt, sipTypeDef *td)
-{
- sipEncodedClassDef *sup;
-
- /* Add the buffer interface. */
- if (td->td_readbuffer != NULL)
-#if PY_VERSION_HEX >= 0x02050000
- wt->super.as_buffer.bf_getreadbuffer = (readbufferproc)sipWrapper_getreadbuffer;
-#else
- wt->super.as_buffer.bf_getreadbuffer = (getreadbufferproc)sipWrapper_getreadbuffer;
-#endif
-
- if (td->td_writebuffer != NULL)
-#if PY_VERSION_HEX >= 0x02050000
- wt->super.as_buffer.bf_getwritebuffer = (writebufferproc)sipWrapper_getwritebuffer;
-#else
- wt->super.as_buffer.bf_getwritebuffer = (getwritebufferproc)sipWrapper_getwritebuffer;
-#endif
-
- if (td->td_segcount != NULL)
-#if PY_VERSION_HEX >= 0x02050000
- wt->super.as_buffer.bf_getsegcount = (segcountproc)sipWrapper_getsegcount;
-#else
- wt->super.as_buffer.bf_getsegcount = (getsegcountproc)sipWrapper_getsegcount;
-#endif
-
- if (td->td_charbuffer != NULL)
-#if PY_VERSION_HEX >= 0x02050000
- wt->super.as_buffer.bf_getcharbuffer = (charbufferproc)sipWrapper_getcharbuffer;
-#else
- wt->super.as_buffer.bf_getcharbuffer = (getcharbufferproc)sipWrapper_getcharbuffer;
-#endif
-
- /* Add the slots for this type. */
- if (td->td_pyslots != NULL)
- initSlots((PyTypeObject *)wt, &wt->super.as_number, &wt->super.as_sequence, &wt->super.as_mapping, td->td_pyslots, FALSE);
-
- /* Recurse through any super-types. */
- if ((sup = td->td_supers) != NULL)
- do
- addSlots(wt, getClassType(sup, td->td_module)->type);
- while (!sup++->sc_flag);
-}
-
-
-/*
- * Add the slot handler for each slot present in the type, optionally replacing
- * any that have already been defined.
- */
-static void initSlots(PyTypeObject *to, PyNumberMethods *nb, PySequenceMethods *sq, PyMappingMethods *mp, sipPySlotDef *slots, int force)
-{
- void *f;
-
- while ((f = slots->psd_func) != NULL)
- switch (slots++->psd_type)
- {
- case str_slot:
- if (force || to->tp_str == NULL)
- to->tp_str = (reprfunc)f;
- break;
-
- case int_slot:
- if (nb != NULL)
- if (force || nb->nb_int == NULL)
- nb->nb_int = (unaryfunc)f;
- break;
-
- case long_slot:
- if (nb != NULL)
- if (force || nb->nb_long == NULL)
- nb->nb_long = (unaryfunc)f;
- break;
-
- case float_slot:
- if (nb != NULL)
- if (force || nb->nb_float == NULL)
- nb->nb_float = (unaryfunc)f;
- break;
-
- case len_slot:
- if (mp != NULL)
- if (force || mp->mp_length == NULL)
-#if PY_VERSION_HEX >= 0x02050000
- mp->mp_length = (lenfunc)f;
-#else
- mp->mp_length = (inquiry)f;
-#endif
- if (sq != NULL)
- if (force || sq->sq_length == NULL)
-#if PY_VERSION_HEX >= 0x02050000
- sq->sq_length = (lenfunc)f;
-#else
- sq->sq_length = (inquiry)f;
-#endif
- break;
-
- case contains_slot:
- if (sq != NULL)
- if (force || sq->sq_contains == NULL)
- sq->sq_contains = (objobjproc)f;
- break;
-
- case add_slot:
- if (nb != NULL)
- if (force || nb->nb_add == NULL)
- nb->nb_add = (binaryfunc)f;
- break;
-
- case concat_slot:
- if (sq != NULL)
- if (force || sq->sq_concat == NULL)
- sq->sq_concat = (binaryfunc)f;
- break;
-
- case sub_slot:
- if (nb != NULL)
- if (force || nb->nb_subtract == NULL)
- nb->nb_subtract = (binaryfunc)f;
- break;
-
- case mul_slot:
- if (nb != NULL)
- if (force || nb->nb_multiply == NULL)
- nb->nb_multiply = (binaryfunc)f;
- break;
-
- case repeat_slot:
- if (sq != NULL)
- if (force || sq->sq_repeat == NULL)
-#if PY_VERSION_HEX >= 0x02050000
- sq->sq_repeat = (ssizeargfunc)f;
-#else
- sq->sq_repeat = (intargfunc)f;
-#endif
- break;
-
- case div_slot:
- if (nb != NULL)
- {
- if (force || nb->nb_divide == NULL)
- nb->nb_divide = (binaryfunc)f;
-
- if (force || nb->nb_true_divide == NULL)
- nb->nb_true_divide = (binaryfunc)f;
- }
- break;
-
- case mod_slot:
- if (nb != NULL)
- if (force || nb->nb_remainder == NULL)
- nb->nb_remainder = (binaryfunc)f;
- break;
-
- case and_slot:
- if (nb != NULL)
- if (force || nb->nb_and == NULL)
- nb->nb_and = (binaryfunc)f;
- break;
-
- case or_slot:
- if (nb != NULL)
- if (force || nb->nb_or == NULL)
- nb->nb_or = (binaryfunc)f;
- break;
-
- case xor_slot:
- if (nb != NULL)
- if (force || nb->nb_xor == NULL)
- nb->nb_xor = (binaryfunc)f;
- break;
-
- case lshift_slot:
- if (nb != NULL)
- if (force || nb->nb_lshift == NULL)
- nb->nb_lshift = (binaryfunc)f;
- break;
-
- case rshift_slot:
- if (nb != NULL)
- if (force || nb->nb_rshift == NULL)
- nb->nb_rshift = (binaryfunc)f;
- break;
-
- case iadd_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_add == NULL)
- nb->nb_inplace_add = (binaryfunc)f;
- break;
-
- case iconcat_slot:
- if (sq != NULL)
- if (force || sq->sq_inplace_concat == NULL)
- sq->sq_inplace_concat = (binaryfunc)f;
- break;
-
- case isub_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_subtract == NULL)
- nb->nb_inplace_subtract = (binaryfunc)f;
- break;
-
- case imul_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_multiply == NULL)
- nb->nb_inplace_multiply = (binaryfunc)f;
- break;
-
- case irepeat_slot:
- if (sq != NULL)
- if (force || sq->sq_inplace_repeat == NULL)
-#if PY_VERSION_HEX >= 0x02050000
- sq->sq_inplace_repeat = (ssizeargfunc)f;
-#else
- sq->sq_inplace_repeat = (intargfunc)f;
-#endif
- break;
-
- case idiv_slot:
- if (nb != NULL)
- {
- if (force || nb->nb_inplace_divide == NULL)
- nb->nb_inplace_divide = (binaryfunc)f;
-
- if (force || nb->nb_inplace_true_divide == NULL)
- nb->nb_inplace_true_divide = (binaryfunc)f;
- }
- break;
-
- case imod_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_remainder == NULL)
- nb->nb_inplace_remainder = (binaryfunc)f;
- break;
-
- case iand_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_and == NULL)
- nb->nb_inplace_and = (binaryfunc)f;
- break;
-
- case ior_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_or == NULL)
- nb->nb_inplace_or = (binaryfunc)f;
- break;
-
- case ixor_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_xor == NULL)
- nb->nb_inplace_xor = (binaryfunc)f;
- break;
-
- case ilshift_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_lshift == NULL)
- nb->nb_inplace_lshift = (binaryfunc)f;
- break;
-
- case irshift_slot:
- if (nb != NULL)
- if (force || nb->nb_inplace_rshift == NULL)
- nb->nb_inplace_rshift = (binaryfunc)f;
- break;
-
- case invert_slot:
- if (nb != NULL)
- if (force || nb->nb_invert == NULL)
- nb->nb_invert = (unaryfunc)f;
- break;
-
- case call_slot:
- if (force || to->tp_call == NULL)
- to->tp_call = sipWrapper_call;
- break;
-
- case getitem_slot:
- if (mp != NULL)
- if (force || mp->mp_subscript == NULL)
- mp->mp_subscript = (binaryfunc)f;
- if (sq != NULL)
- if (force || sq->sq_item == NULL)
- sq->sq_item = sipWrapper_sq_item;
- break;
-
- case setitem_slot:
- case delitem_slot:
- if (mp != NULL)
- if (force || mp->mp_ass_subscript == NULL)
- mp->mp_ass_subscript = sipWrapper_mp_ass_subscript;
- if (sq != NULL)
- if (force || sq->sq_ass_item == NULL)
- sq->sq_ass_item = sipWrapper_sq_ass_item;
- break;
-
- case lt_slot:
- case le_slot:
- case eq_slot:
- case ne_slot:
- case gt_slot:
- case ge_slot:
- if (force || to->tp_richcompare == NULL)
- to->tp_richcompare = sipWrapper_richcompare;
- break;
-
- case cmp_slot:
- if (force || to->tp_compare == NULL)
- to->tp_compare = (cmpfunc)f;
- break;
-
- case nonzero_slot:
- if (nb != NULL)
- if (force || nb->nb_nonzero == NULL)
- nb->nb_nonzero = (inquiry)f;
- break;
-
- case neg_slot:
- if (nb != NULL)
- if (force || nb->nb_negative == NULL)
- nb->nb_negative = (unaryfunc)f;
- break;
-
- case repr_slot:
- if (force || to->tp_repr == NULL)
- to->tp_repr = (reprfunc)f;
- break;
-
- case hash_slot:
- if (force || to->tp_hash == NULL)
- to->tp_hash = (hashfunc)f;
- break;
-
- case pos_slot:
- if (nb != NULL)
- if (force || nb->nb_positive == NULL)
- nb->nb_positive = (unaryfunc)f;
- break;
-
- case abs_slot:
- if (nb != NULL)
- if (force || nb->nb_absolute == NULL)
- nb->nb_absolute = (unaryfunc)f;
- break;
- }
-}
-
-
-/*
- * Search for a named class and return the wrapper type.
- */
-static sipWrapperType *findClass(sipExportedModuleDef *emd, const char *name,
- size_t len)
-{
- int i;
- sipWrapperType **wtp = emd->em_types;
-
- for (i = 0; i < emd->em_nrtypes; ++i)
- {
- sipWrapperType *wt;
-
- if ((wt = *wtp++) == NULL)
- continue;
-
- if (wt->type->td_cname != NULL)
- {
- if (!nameEq(wt->type->td_cname, name, len))
- continue;
- }
- else if (!sameScopedName(wt->type->td_name, name, len))
- continue;
-
- return wt;
- }
-
- return NULL;
-}
-
-
-/*
- * Search for a named class and return TRUE and the necessary information to
- * create an instance of it if it was found.
- */
-static int findClassArg(sipExportedModuleDef *emd, const char *name,
- size_t len, sipSigArg *at, int indir)
-{
- sipWrapperType *wt = findClass(emd, name, len);
-
- if (wt == NULL)
- return FALSE;
-
- if (indir == 0)
- at->atype = class_sat;
- else if (indir == 1)
- at->atype = classp_sat;
- else
- at->atype = unknown_sat;
-
- at->u.wt = wt;
-
- return TRUE;
-}
-
-
-/*
- * Search for a mapped type and return TRUE and the necessary information to
- * create an instance of it if it was found.
- */
-static int findMtypeArg(sipMappedType **mttab, const char *name, size_t len,
- sipSigArg *at, int indir)
-{
- sipMappedType *mt;
-
- while ((mt = *mttab++) != NULL)
- if (nameEq(mt->mt_name, name, len))
- {
- if (indir == 0)
- at->atype = mtype_sat;
- else if (indir == 1)
- at->atype = mtypep_sat;
- else
- at->atype = unknown_sat;
-
- at->u.mt = mt;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/*
- * Search for a named enum in a particular module and return the corresponding
- * type object.
- */
-static PyTypeObject *findEnum(sipExportedModuleDef *emd, const char *name,
- size_t len)
-{
- int i;
- sipEnumDef *ed;
-
- for (ed = emd->em_enumdefs, i = 0; i < emd->em_nrenums; ++i, ++ed)
- {
- if (ed->e_cname != NULL)
- {
- if (!nameEq(ed->e_cname, name, len))
- continue;
- }
- else if (!sameScopedName(ed->e_name, name, len))
- continue;
-
- return emd->em_enums[i];
- }
-
- return NULL;
-}
-
-
-/*
- * Search for a named enum and return TRUE and the necessary information to
- * create an instance of it if it was found.
- */
-static int findEnumArg(sipExportedModuleDef *emd, const char *name, size_t len,
- sipSigArg *at, int indir)
-{
- PyTypeObject *py = findEnum(emd, name, len);
-
- if (py == NULL)
- return FALSE;
-
- if (indir == 0)
- at->atype = enum_sat;
- else
- at->atype = unknown_sat;
-
- at->u.et = py;
-
- return TRUE;
-}
-
-
-/*
- * Search for a named type and the necessary information to create an instance
- * of it.
- */
-void sipFindSigArgType(const char *name, size_t len, sipSigArg *at, int indir)
-{
- sipExportedModuleDef *em;
- sipPyObject *po;
-
- at->atype = unknown_sat;
-
- for (em = clientList; em != NULL; em = em->em_next)
- {
- sipTypedefDef *tdd;
-
- /* Search for a typedef. */
- if ((tdd = em->em_typedefs) != NULL)
- while (tdd->tdd_name != NULL)
- {
- if (nameEq(tdd->tdd_name, name, len))
- {
- sipExportedModuleDef *tem;
- const char *tn;
- size_t tnlen;
-
- at->atype = tdd->tdd_type;
-
- /* Done with the simple cases. */
- if ((tn = tdd->tdd_type_name) == NULL)
- return;
-
- /*
- * Find the module that this class, mapped type or enum is
- * defined in.
- */
- if (tdd->tdd_mod_name == NULL)
- tem = em;
- else
- for (tem = clientList; tem != NULL; tem = tem->em_next)
- if (strcmp(tem->em_name, tdd->tdd_mod_name) == 0)
- break;
-
- tnlen = strlen(tn);
-
- switch (tdd->tdd_type)
- {
- case class_sat:
- findClassArg(tem, tn, tnlen, at, indir);
- break;
-
- case mtype_sat:
- findMtypeArg(tem->em_mappedtypes, tn, tnlen, at, indir);
- break;
-
- case enum_sat:
- findEnumArg(tem, tn, tnlen, at, indir);
- break;
- }
-
- /* We should have found it by now. */
- return;
- }
-
- ++tdd;
- }
-
- /* Search for a class. */
- if (em->em_types != NULL && findClassArg(em, name, len, at, indir))
- return;
-
- /* Search for a mapped type. */
- if (em->em_mappedtypes != NULL && findMtypeArg(em->em_mappedtypes, name, len, at, indir))
- return;
-
- /* Search for an enum. */
- if (em->em_enums != NULL && findEnumArg(em, name, len, at, indir))
- return;
- }
-
- /* Search for a dynamically registered int type. */
- for (po = sipRegisteredIntTypes; po != NULL; po = po->next)
- {
- int i;
-
- for (i = 0; i < PyTuple_GET_SIZE(po->object); ++i)
- {
- char *int_nm = PyString_AsString(PyTuple_GET_ITEM(po->object, i));
-
- if (int_nm == NULL)
- continue;
-
- if (nameEq(int_nm, name, len))
- {
- at->atype = int_sat;
- return;
- }
- }
- }
-}
-
-
-/*
- * Compare a '\0' terminated string with the first len characters of a second
- * and return a non-zero value if they are equal.
- */
-static int nameEq(const char *with, const char *name, size_t len)
-{
- return (strlen(with) == len && strncmp(with, name, len) == 0);
-}
-
-
-/*
- * Return TRUE if a Python scoped name and a fixed length C++ scoped name
- * match.
- */
-static int sameScopedName(const char *pyname, const char *name, size_t len)
-{
- char ch;
-
- /* Skip the module name from the Python name. */
- pyname = strchr(pyname, '.') + 1;
-
- while ((ch = *pyname++) != '\0' && len)
- if (ch == '.')
- {
- if (len < 2 || name[0] != ':' || name[1] != ':')
- return FALSE;
-
- name += 2;
- len -= 2;
- }
- else if (ch == name[0])
- {
- ++name;
- --len;
- }
- else
- return FALSE;
-
- return (ch == '\0' && len == 0);
-}
-
-
-/*
- * Register a Python tuple of type names that will be interpreted as ints if
- * they are seen as signal arguments.
- */
-static int sip_api_register_int_types(PyObject *args)
-{
- sipPyObject *po;
- int bad_args = FALSE;
-
- /* Raise an exception if the arguments are bad. */
- if (PyTuple_Check(args))
- {
- int i;
-
- for (i = 0; i < PyTuple_GET_SIZE(args); ++i)
- if (!PyString_Check(PyTuple_GET_ITEM(args, i)))
- {
- bad_args = TRUE;
- break;
- }
- }
- else
- bad_args = TRUE;
-
- if (bad_args)
- {
- PyErr_SetString(PyExc_TypeError, "all arguments must be strings");
- return -1;
- }
-
- if ((po = sip_api_malloc(sizeof (sipPyObject))) == NULL)
- return -1;
-
- Py_INCREF(args);
-
- po->object = args;
- po->next = sipRegisteredIntTypes;
-
- sipRegisteredIntTypes = po;
-
- return 0;
-}
-
-
-/*
- * Register a symbol with a name. A negative value is returned if the name was
- * already registered.
- */
-static int sip_api_export_symbol(const char *name, void *sym)
-{
- sipSymbol *ss;
-
- if (sip_api_import_symbol(name) != NULL)
- return -1;
-
- if ((ss = sip_api_malloc(sizeof (sipSymbol))) == NULL)
- return -1;
-
- ss->name = name;
- ss->symbol = sym;
- ss->next = sipSymbolList;
-
- sipSymbolList = ss;
-
- return 0;
-}
-
-
-/*
- * Return the symbol registered with the given name. NULL is returned if the
- * name was not registered.
- */
-static void *sip_api_import_symbol(const char *name)
-{
- sipSymbol *ss;
-
- for (ss = sipSymbolList; ss != NULL; ss = ss->next)
- if (strcmp(ss->name, name) == 0)
- return ss->symbol;
-
- return NULL;
-}
-
-
-/*
- * Returns TRUE if the Qt support is present and conforms to the v3.4 or later
- * of the SIP API.
- */
-static int qt_and_sip_api_3_4(void)
-{
- return (sipQtSupport != NULL && sipQObjectClass->type->td_module->em_api_minor >= 4);
-}
-
-
-/*
- * Visit a slot connected to an object for the cyclic garbage collector.
- */
-static int visitSlot(sipSlot *slot, visitproc visit, void *arg)
-{
- if (slot->pyobj != NULL && sipLambdaSlot(slot->pyobj))
- return visit(slot->pyobj, arg);
-
- return 0;
-}
-
-
-/*
- * Clear a slot if it is a lambda function.
- */
-static void clearAnyLambda(sipSlot *slot)
-{
- PyObject *lam = slot->pyobj;
-
- if (lam != NULL && sipLambdaSlot(lam))
- {
- /*
- * Replace the lambda function with None. We don't use NULL as this
- * has another meaning.
- */
- Py_INCREF(Py_None);
- slot->pyobj = Py_None;
-
- Py_DECREF(lam);
- }
-}
-
-
-/*
- * Convert a Python object to a character.
- */
-static char sip_api_string_as_char(PyObject *obj)
-{
- char ch;
-
- if (parseChar(obj, &ch) < 0)
- {
- PyErr_SetString(PyExc_ValueError, "string of length 1 expected");
-
- return '\0';
- }
-
- return ch;
-}
-
-
-/*
- * Parse a character array and return it's address and length.
- */
-static int parseCharArray(PyObject *obj, char **ap, int *aszp)
-{
- if (obj == Py_None)
- {
- *ap = NULL;
- *aszp = 0;
- }
- else if (PyString_Check(obj))
- {
- *ap = PyString_AS_STRING(obj);
- *aszp = (int)PyString_GET_SIZE(obj);
- }
- else
- return -1;
-
- return 0;
-}
-
-
-/*
- * Parse a character and return it.
- */
-static int parseChar(PyObject *obj, char *ap)
-{
- if (!PyString_Check(obj) || PyString_GET_SIZE(obj) != 1)
- return -1;
-
- *ap = *PyString_AS_STRING(obj);
-
- return 0;
-}
-
-
-/*
- * Parse a character string and return it.
- */
-static int parseCharString(PyObject *obj, char **ap)
-{
- if (obj == Py_None)
- *ap = NULL;
- else if (PyString_Check(obj))
- *ap = PyString_AS_STRING(obj);
- else
- return -1;
-
- return 0;
-}
-
-
-#if defined(HAVE_WCHAR_H)
-/*
- * Convert a Python object to a wide character.
- */
-static wchar_t sip_api_unicode_as_wchar(PyObject *obj)
-{
- wchar_t ch;
-
- if (parseWChar(obj, &ch) < 0)
- {
- PyErr_SetString(PyExc_ValueError, "unicode string of length 1 expected");
-
- return L'\0';
- }
-
- return ch;
-}
-
-
-/*
- * Convert a Python object to a wide character string on the heap.
- */
-static wchar_t *sip_api_unicode_as_wstring(PyObject *obj)
-{
- wchar_t *p;
-
- if (parseWCharString(obj, &p) < 0)
- {
- PyErr_SetString(PyExc_ValueError, "unicode string expected");
-
- return NULL;
- }
-
- return p;
-}
-
-
-/*
- * Parse a wide character array and return it's address and length.
- */
-static int parseWCharArray(PyObject *obj, wchar_t **ap, int *aszp)
-{
- if (obj == Py_None)
- {
- *ap = NULL;
- *aszp = 0;
- }
- else if (PyUnicode_Check(obj))
- {
- SIP_SSIZE_T ulen;
- wchar_t *wc;
-
- ulen = PyUnicode_GET_SIZE(obj);
-
- if ((wc = sip_api_malloc(ulen * sizeof (wchar_t))) == NULL)
- return -1;
-
- ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen);
-
- if (ulen < 0)
- {
- sip_api_free(wc);
- return -1;
- }
-
- *ap = wc;
- *aszp = (int)ulen;
- }
- else
- return -1;
-
- return 0;
-}
-
-
-/*
- * Parse a wide character and return it.
- */
-static int parseWChar(PyObject *obj, wchar_t *ap)
-{
- if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1)
- return -1;
-
- if (PyUnicode_AsWideChar((PyUnicodeObject *)obj, ap, 1) != 1)
- return -1;
-
- return 0;
-}
-
-
-/*
- * Parse a wide character string and return it.
- */
-static int parseWCharString(PyObject *obj, wchar_t **ap)
-{
- if (obj == Py_None)
- *ap = NULL;
- else if (PyUnicode_Check(obj))
- {
- SIP_SSIZE_T ulen;
- wchar_t *wc;
-
- ulen = PyUnicode_GET_SIZE(obj);
-
- if ((wc = sip_api_malloc((ulen + 1) * sizeof (wchar_t))) == NULL)
- return -1;
-
- ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen);
-
- if (ulen < 0)
- {
- sip_api_free(wc);
- return -1;
- }
-
- wc[ulen] = L'\0';
-
- *ap = wc;
- }
- else
- return -1;
-
- return 0;
-}
-
-#else
-
-/*
- * Convert a Python object to a wide character.
- */
-static int sip_api_unicode_as_wchar(PyObject *obj)
-{
- raiseNoWChar();
-
- return 0;
-}
-
-
-/*
- * Convert a Python object to a wide character.
- */
-static int *sip_api_unicode_as_wstring(PyObject *obj)
-{
- raiseNoWChar();
-
- return NULL;
-}
-
-
-/*
- * Report the need for absent wide character support.
- */
-static void raiseNoWChar()
-{
- PyErr_SetString(PyExc_SystemError, "sip built without wchar_t support");
-}
-
-#endif
diff --git a/python/sip/siplib/siplib.sbf b/python/sip/siplib/siplib.sbf
deleted file mode 100644
index 2499d1b8..00000000
--- a/python/sip/siplib/siplib.sbf
+++ /dev/null
@@ -1,16 +0,0 @@
-# This is the build file for the extension module.
-#
-# Copyright (c) 2007
-# Riverbank Computing Limited <info@riverbankcomputing.co.uk>
-#
-# This file is part of SIP.
-#
-# This copy of SIP is licensed for use under the terms of the SIP License
-# Agreement. See the file LICENSE for more details.
-#
-# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-target = sip
-sources = siplib.c qtlib.c threads.c objmap.c bool.cpp
-headers = sip.h sipint.h
diff --git a/python/sip/siplib/threads.c b/python/sip/siplib/threads.c
deleted file mode 100644
index c4ee75ff..00000000
--- a/python/sip/siplib/threads.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Thread support for the SIP library. This module provides the hooks for
- * C++ classes that provide a thread interface to interact properly with the
- * Python threading infrastructure.
- *
- * Copyright (c) 2007
- * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
- *
- * This file is part of SIP.
- *
- * This copy of SIP is licensed for use under the terms of the SIP License
- * Agreement. See the file LICENSE for more details.
- *
- * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-#include "sip.h"
-#include "sipint.h"
-
-
-/*
- * The data associated with pending request to wrap an object.
- */
-typedef struct _pendingDef {
- void *cpp; /* The C/C++ object ot be wrapped. */
- sipWrapper *owner; /* The owner of the object. */
- int flags; /* The flags. */
-} pendingDef;
-
-
-#ifdef WITH_THREAD
-
-#include <pythread.h>
-
-
-/*
- * The per thread data we need to maintain.
- */
-typedef struct _threadDef {
- long thr_ident; /* The thread identifier. */
- pendingDef pending; /* An object waiting to be wrapped. */
- struct _threadDef *next; /* Next in the list. */
-} threadDef;
-
-
-static threadDef *threads = NULL; /* Linked list of threads. */
-
-
-static threadDef *currentThreadDef(void);
-
-#endif
-
-
-static pendingDef pending; /* An object waiting to be wrapped. */
-
-
-/*
- * Get the address of any C/C++ object waiting to be wrapped.
- */
-void *sipGetPending(sipWrapper **op, int *fp)
-{
- pendingDef *pp;
-
-#ifdef WITH_THREAD
- threadDef *td;
-
- if ((td = currentThreadDef()) != NULL)
- pp = &td->pending;
- else
- pp = &pending;
-#else
- pp = &pending;
-#endif
-
- if (pp->cpp != NULL)
- {
- if (op != NULL)
- *op = pp->owner;
-
- if (fp != NULL)
- *fp = pp->flags;
- }
-
- return pp->cpp;
-}
-
-
-/*
- * Convert a new C/C++ pointer to a Python instance.
- */
-PyObject *sipWrapSimpleInstance(void *cppPtr, sipWrapperType *type,
- sipWrapper *owner, int flags)
-{
- static PyObject *nullargs = NULL;
-
- pendingDef old_pending;
- PyObject *self;
-#ifdef WITH_THREAD
- threadDef *td;
-#endif
-
- if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL)
- return NULL;
-
- if (cppPtr == NULL)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /*
- * Object creation can trigger the Python garbage collector which in turn
- * can execute arbitrary Python code which can then call this function
- * recursively. Therefore we save any existing pending object before
- * setting the new one.
- */
-#ifdef WITH_THREAD
- if ((td = currentThreadDef()) != NULL)
- {
- old_pending = td->pending;
-
- td->pending.cpp = cppPtr;
- td->pending.owner = owner;
- td->pending.flags = flags;
- }
- else
- {
- old_pending = pending;
-
- pending.cpp = cppPtr;
- pending.owner = owner;
- pending.flags = flags;
- }
-#else
- old_pending = pending;
-
- pending.cpp = cppPtr;
- pending.owner = owner;
- pending.flags = flags;
-#endif
-
- self = PyObject_Call((PyObject *)type, nullargs, NULL);
-
-#ifdef WITH_THREAD
- if (td != NULL)
- td->pending = old_pending;
- else
- pending = old_pending;
-#else
- pending = old_pending;
-#endif
-
- return self;
-}
-
-
-/*
- * This is called from a newly created thread to initialise some thread local
- * storage.
- */
-void sip_api_start_thread(void)
-{
-#ifdef WITH_THREAD
- threadDef *td;
-
- /* Save the thread ID. First, find an empty slot in the list. */
- for (td = threads; td != NULL; td = td->next)
- if (td->thr_ident == 0)
- break;
-
- if (td == NULL)
- {
- td = sip_api_malloc(sizeof (threadDef));
- td->next = threads;
- threads = td;
- }
-
- if (td != NULL)
- {
- td->thr_ident = PyThread_get_thread_ident();
- td->pending.cpp = NULL;
- }
-#endif
-}
-
-
-/*
- * Handle the termination of a thread. The thread state should already have
- * been handled by the last call to PyGILState_Release().
- */
-void sip_api_end_thread(void)
-{
-#ifdef WITH_THREAD
- threadDef *td;
-
- /* We have the GIL at this point. */
- if ((td = currentThreadDef()) != NULL)
- td->thr_ident = 0;
-#endif
-}
-
-
-#ifdef WITH_THREAD
-
-/*
- * Return the thread data for the current thread or NULL if it wasn't
- * recognised.
- */
-static threadDef *currentThreadDef(void)
-{
- threadDef *td;
- long ident = PyThread_get_thread_ident();
-
- for (td = threads; td != NULL; td = td->next)
- if (td->thr_ident == ident)
- break;
-
- return td;
-}
-
-#endif