Skip to content
Next Next commit
Port curses capi pointer array to a struct.
  • Loading branch information
shihai1991 committed Jan 23, 2021
commit 3cb597151129fb0d4e8f9ac54a6d2cab00c97b99
21 changes: 13 additions & 8 deletions Include/py_curses.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@
extern "C" {
#endif

#define PyCurses_API_pointers 4
Comment thread
shihai1991 marked this conversation as resolved.

/* Type declarations */

typedef struct {
Expand All @@ -64,6 +62,13 @@ typedef struct {
char *encoding;
} PyCursesWindowObject;

typedef struct {
PyTypeObject *Window_Type;
int (*SetupTermCalled)(void);
int (*Initialised)(void);
int (*InitialisedColor)(void);
Comment thread
shihai1991 marked this conversation as resolved.
Outdated
} PyCurses_CAPI;

#define PyCursesWindow_Check(v) Py_IS_TYPE(v, &PyCursesWindow_Type)

#define PyCurses_CAPSULE_NAME "_curses._C_API"
Expand All @@ -75,15 +80,15 @@ typedef struct {
#else
/* This section is used in modules that use the _cursesmodule API */

static void **PyCurses_API;
static PyCurses_CAPI *PyCurses_API;

#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0])
#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;}
#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;}
#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;}
#define PyCursesWindow_Type (*PyCurses_API->Window_Type)
#define PyCursesSetupTermCalled {if (!PyCurses_API->SetupTermCalled()) return NULL;}
#define PyCursesInitialised {if (!PyCurses_API->Initialised()) return NULL;}
#define PyCursesInitialisedColor {if (!PyCurses_API->InitialisedColor()) return NULL;}

#define import_curses() \
PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1);
PyCurses_API = PyCapsule_Import(PyCurses_CAPSULE_NAME, 1);

#endif

Expand Down
19 changes: 10 additions & 9 deletions Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -4728,8 +4728,8 @@ static struct PyModuleDef _cursesmodule = {
static void
curses_destructor(PyObject *op)
{
void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME);
Py_DECREF(*(void **)ptr);
PyCurses_CAPI *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME);
Py_DECREF(ptr->Window_Type);
PyMem_Free(ptr);
}

Expand All @@ -4753,22 +4753,23 @@ PyInit__curses(void)
return NULL;
ModDict = d; /* For PyCurses_InitScr to use later */

void **PyCurses_API = PyMem_Calloc(PyCurses_API_pointers, sizeof(void *));
PyCurses_CAPI *PyCurses_API = PyMem_Malloc(sizeof(PyCurses_CAPI));
if (PyCurses_API == NULL) {
PyErr_NoMemory();
return NULL;
}
/* Initialize the C API pointer array */
PyCurses_API[0] = (void *)Py_NewRef(&PyCursesWindow_Type);
PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
PyCurses_API[2] = (void *)func_PyCursesInitialised;
PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
/* Initialize the C API struct pointer */
Comment thread
shihai1991 marked this conversation as resolved.
Outdated
PyCurses_API->Window_Type = (PyTypeObject *)Py_NewRef(
&PyCursesWindow_Type);
PyCurses_API->SetupTermCalled = func_PyCursesSetupTermCalled;
PyCurses_API->Initialised = func_PyCursesInitialised;
PyCurses_API->InitialisedColor = func_PyCursesInitialisedColor;

/* Add a capsule for the C API */
c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME,
curses_destructor);
if (c_api_object == NULL) {
Py_DECREF(PyCurses_API[0]);
Py_DECREF(PyCurses_API->Window_Type);
PyMem_Free(PyCurses_API);
return NULL;
}
Expand Down