From 29de984d00d1a7562b54eaaebf56484a909cd160 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 1 Feb 2017 10:22:48 -0800 Subject: [PATCH] Update siplib --- sip/siplib/sip.h | 15 ++++++--- sip/siplib/siplib.c | 82 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/sip/siplib/sip.h b/sip/siplib/sip.h index e26f3506..669b98da 100644 --- a/sip/siplib/sip.h +++ b/sip/siplib/sip.h @@ -1,7 +1,7 @@ /* * The SIP module interface. * - * Copyright (c) 2015 Riverbank Computing Limited + * Copyright (c) 2017 Riverbank Computing Limited * * This file is part of SIP. * @@ -54,8 +54,8 @@ extern "C" { /* * Define the SIP version number. */ -#define SIP_VERSION 0x041301 -#define SIP_VERSION_STR "4.19.1.dev1701292222" +#define SIP_VERSION 0x04ffff +#define SIP_VERSION_STR "4.255.255" /* @@ -68,6 +68,8 @@ extern "C" { * * History: * + * 12.1 Added sip_api_enable_gc() to the public API. + * * 12.0 Added SIP_TYPE_LIMITED_API to the sipTypeDef flags. * Added sip_api_py_type_dict() and sip_api_py_type_name() to the public * API. @@ -244,7 +246,7 @@ extern "C" { * 0.0 Original version. */ #define SIP_API_MAJOR_NR 12 -#define SIP_API_MINOR_NR 0 +#define SIP_API_MINOR_NR 1 /* The name of the sip module. */ @@ -1801,6 +1803,11 @@ typedef struct _sipAPIDef { const sipIntTypeClassMap *map, int maplen); sipWrapperType *(*api_map_string_to_class)(const char *typeString, const sipStringTypeClassMap *map, int maplen); + + /* + * The following are part of the public API. + */ + int (*api_enable_gc)(int enable); } sipAPIDef; diff --git a/sip/siplib/siplib.c b/sip/siplib/siplib.c index 8a307733..55b93128 100644 --- a/sip/siplib/siplib.c +++ b/sip/siplib/siplib.c @@ -433,6 +433,7 @@ static int sip_api_get_buffer_info(PyObject *obj, sipBufferInfoDef *bi); static void sip_api_release_buffer_info(sipBufferInfoDef *bi); static PyObject *sip_api_get_user_object(const sipSimpleWrapper *sw); static void sip_api_set_user_object(sipSimpleWrapper *sw, PyObject *user); +static int sip_api_enable_gc(int enable); /* @@ -585,6 +586,10 @@ static const sipAPIDef sip_api = { sip_api_find_class, sip_api_map_int_to_class, sip_api_map_string_to_class, + /* + * The following are part of the public API. + */ + sip_api_enable_gc, }; @@ -9392,7 +9397,7 @@ static void sip_api_call_hook(const char *hookname) return; /* Call the hook and discard any result. */ - res = PyObject_CallObject(hook, NULL); + res = PyObject_Call(hook, empty_tuple, NULL); Py_XDECREF(res); } @@ -13458,3 +13463,78 @@ static int importExceptions(sipExportedModuleDef *client, return 0; } + + +/* + * Enable or disable the garbage collector. Return the previous state or -1 if + * there was an error. + */ +static int sip_api_enable_gc(int enable) +{ + static PyObject *enable_func = NULL, *disable_func, *isenabled_func; + PyObject *result; + int was_enabled; + + /* + * This may be -ve in the highly unusual event that a previous call failed. + */ + if (enable < 0) + return -1; + + /* Get the functions if we haven't already got them. */ + if (enable == NULL) + { + PyObject *gc_module; + + if ((gc_module = PyImport_ImportModule("gc")) == NULL) + return -1; + + if ((enable_func = PyObject_GetAttrString(gc_module, "enable")) == NULL) + { + Py_DECREF(gc_module); + return -1; + } + + if ((disable_func = PyObject_GetAttrString(gc_module, "disable")) == NULL) + { + Py_DECREF(enable_func); + Py_DECREF(gc_module); + return -1; + } + + if ((isenabled_func = PyObject_GetAttrString(gc_module, "isenabled")) == NULL) + { + Py_DECREF(disable_func); + Py_DECREF(enable_func); + Py_DECREF(gc_module); + return -1; + } + + Py_DECREF(gc_module); + } + + /* Get the current state. */ + if ((result = PyObject_Call(isenabled_func, empty_tuple, NULL)) == NULL) + return -1; + + was_enabled = PyObject_IsTrue(result); + Py_DECREF(result); + + if (was_enabled < 0) + return -1; + + /* See if the state needs changing. */ + if (!was_enabled != !enable) + { + /* Enable or disable as required. */ + result = PyObject_Call((enable ? enable_func : disable_func), + empty_tuple, NULL); + + Py_XDECREF(result); + + if (result != Py_None) + return -1; + } + + return was_enabled; +}