gh-133579: correctly report C curses errors in _curses_panel
(#134629)
This is a follow-up to ee36db550076e5a9185444ffbc53eaf8157ef04c.
This commit is contained in:
parent
8fdbbf8b18
commit
d610f11d21
@ -17,6 +17,7 @@ static const char PyCursesVersion[] = "2.1";
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#define CURSES_PANEL_MODULE
|
||||
#include "py_curses.h"
|
||||
|
||||
#if defined(HAVE_NCURSESW_PANEL_H)
|
||||
@ -28,10 +29,12 @@ static const char PyCursesVersion[] = "2.1";
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject *PyCursesError;
|
||||
PyObject *error;
|
||||
PyTypeObject *PyCursesPanel_Type;
|
||||
} _curses_panel_state;
|
||||
|
||||
typedef struct PyCursesPanelObject PyCursesPanelObject;
|
||||
|
||||
static inline _curses_panel_state *
|
||||
get_curses_panel_state(PyObject *module)
|
||||
{
|
||||
@ -40,11 +43,30 @@ get_curses_panel_state(PyObject *module)
|
||||
return (_curses_panel_state *)state;
|
||||
}
|
||||
|
||||
static inline _curses_panel_state *
|
||||
get_curses_panel_state_by_panel(PyCursesPanelObject *panel)
|
||||
{
|
||||
/*
|
||||
* Note: 'state' may be NULL if Py_TYPE(panel) is not a heap
|
||||
* type associated with this module, but the compiler would
|
||||
* have likely already complained with an "invalid pointer
|
||||
* type" at compile-time.
|
||||
*
|
||||
* To make it more robust, all functions recovering a module's
|
||||
* state from an object should expect to return NULL with an
|
||||
* exception set (in contrast to functions recovering a module's
|
||||
* state from a module itself).
|
||||
*/
|
||||
void *state = PyType_GetModuleState(Py_TYPE(panel));
|
||||
assert(state != NULL);
|
||||
return (_curses_panel_state *)state;
|
||||
}
|
||||
|
||||
static int
|
||||
_curses_panel_clear(PyObject *mod)
|
||||
{
|
||||
_curses_panel_state *state = get_curses_panel_state(mod);
|
||||
Py_CLEAR(state->PyCursesError);
|
||||
Py_CLEAR(state->error);
|
||||
Py_CLEAR(state->PyCursesPanel_Type);
|
||||
return 0;
|
||||
}
|
||||
@ -54,7 +76,7 @@ _curses_panel_traverse(PyObject *mod, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(Py_TYPE(mod));
|
||||
_curses_panel_state *state = get_curses_panel_state(mod);
|
||||
Py_VISIT(state->PyCursesError);
|
||||
Py_VISIT(state->error);
|
||||
Py_VISIT(state->PyCursesPanel_Type);
|
||||
return 0;
|
||||
}
|
||||
@ -65,28 +87,149 @@ _curses_panel_free(void *mod)
|
||||
(void)_curses_panel_clear((PyObject *)mod);
|
||||
}
|
||||
|
||||
/* Utility Error Procedures
|
||||
*
|
||||
* The naming and implementations are identical to those in _cursesmodule.c.
|
||||
* Functions that are not yet needed (for instance, reporting an ERR value
|
||||
* from a module-wide function, namely curses_panel_set_error()) are
|
||||
* omitted and should only be added if needed.
|
||||
*/
|
||||
|
||||
static void
|
||||
_curses_panel_format_error(_curses_panel_state *state,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname,
|
||||
const char *return_value,
|
||||
const char *default_message)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
if (python_funcname == NULL && curses_funcname == NULL) {
|
||||
PyErr_SetString(state->error, default_message);
|
||||
}
|
||||
else if (python_funcname == NULL) {
|
||||
(void)PyErr_Format(state->error, CURSES_ERROR_FORMAT,
|
||||
curses_funcname, return_value);
|
||||
}
|
||||
else {
|
||||
assert(python_funcname != NULL);
|
||||
(void)PyErr_Format(state->error, CURSES_ERROR_VERBOSE_FORMAT,
|
||||
curses_funcname, python_funcname, return_value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a curses error for a function that returned ERR.
|
||||
*
|
||||
* Specify a non-NULL 'python_funcname' when the latter differs from
|
||||
* 'curses_funcname'. If both names are NULL, uses the 'catchall_ERR'
|
||||
* message instead.
|
||||
*/
|
||||
static void
|
||||
_curses_panel_set_error(_curses_panel_state *state,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
_curses_panel_format_error(state, curses_funcname, python_funcname,
|
||||
"ERR", catchall_ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a curses error for a function that returned NULL.
|
||||
*
|
||||
* Specify a non-NULL 'python_funcname' when the latter differs from
|
||||
* 'curses_funcname'. If both names are NULL, uses the 'catchall_NULL'
|
||||
* message instead.
|
||||
*/
|
||||
static void
|
||||
_curses_panel_set_null_error(_curses_panel_state *state,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
_curses_panel_format_error(state, curses_funcname, python_funcname,
|
||||
"NULL", catchall_NULL);
|
||||
}
|
||||
|
||||
/* Same as _curses_panel_set_null_error() for a module object. */
|
||||
static void
|
||||
curses_panel_set_null_error(PyObject *module,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
_curses_panel_state *state = get_curses_panel_state(module);
|
||||
_curses_panel_set_null_error(state, curses_funcname, python_funcname);
|
||||
}
|
||||
|
||||
/* Same as _curses_panel_set_error() for a panel object. */
|
||||
static void
|
||||
curses_panel_panel_set_error(PyCursesPanelObject *panel,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
_curses_panel_state *state = get_curses_panel_state_by_panel(panel);
|
||||
_curses_panel_set_error(state, curses_funcname, python_funcname);
|
||||
}
|
||||
|
||||
/* Same as _curses_panel_set_null_error() for a panel object. */
|
||||
static void
|
||||
curses_panel_panel_set_null_error(PyCursesPanelObject *panel,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
_curses_panel_state *state = get_curses_panel_state_by_panel(panel);
|
||||
_curses_panel_set_null_error(state, curses_funcname, python_funcname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate that a panel object couldn't be found.
|
||||
*
|
||||
* Use it for the following constructions:
|
||||
*
|
||||
* PROC caller_funcname:
|
||||
* pan = called_funcname()
|
||||
* find_po(panel)
|
||||
*
|
||||
* PROC caller_funcname:
|
||||
* find_po(self->pan)
|
||||
*/
|
||||
static void
|
||||
curses_panel_notfound_error(const char *called_funcname,
|
||||
const char *caller_funcname)
|
||||
{
|
||||
assert(!(called_funcname == NULL && caller_funcname == NULL));
|
||||
if (caller_funcname == NULL) {
|
||||
(void)PyErr_Format(PyExc_RuntimeError,
|
||||
"%s(): cannot find panel object",
|
||||
called_funcname);
|
||||
}
|
||||
else {
|
||||
(void)PyErr_Format(PyExc_RuntimeError,
|
||||
"%s() (called by %s()): cannot find panel object",
|
||||
called_funcname, caller_funcname);
|
||||
}
|
||||
}
|
||||
|
||||
/* Utility Functions */
|
||||
|
||||
/*
|
||||
* Check the return code from a curses function and return None
|
||||
* or raise an exception as appropriate.
|
||||
* Check the return code from a curses function, returning None
|
||||
* on success and setting an exception on error.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return None if 'code' is different from ERR (implementation-defined).
|
||||
* Otherwise, set an exception using curses_panel_panel_set_error() and
|
||||
* the remaining arguments, and return NULL.
|
||||
*/
|
||||
static PyObject *
|
||||
PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname)
|
||||
curses_panel_panel_check_err(PyCursesPanelObject *panel, int code,
|
||||
const char *curses_funcname,
|
||||
const char *python_funcname)
|
||||
{
|
||||
if (code != ERR) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else {
|
||||
if (fname == NULL) {
|
||||
PyErr_SetString(state->PyCursesError, catchall_ERR);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(state->PyCursesError, "%s() returned ERR", fname);
|
||||
}
|
||||
curses_panel_panel_set_error(panel, curses_funcname, python_funcname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -95,7 +238,7 @@ PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname)
|
||||
|
||||
/* Definition of the panel object and panel type */
|
||||
|
||||
typedef struct {
|
||||
typedef struct PyCursesPanelObject {
|
||||
PyObject_HEAD
|
||||
PANEL *pan;
|
||||
PyCursesWindowObject *wo; /* for reference counts */
|
||||
@ -144,8 +287,11 @@ insert_lop(PyCursesPanelObject *po)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove the panel object from lop */
|
||||
static void
|
||||
/* Remove the panel object from lop.
|
||||
*
|
||||
* Return -1 on error but do NOT set an exception; otherwise return 0.
|
||||
*/
|
||||
static int
|
||||
remove_lop(PyCursesPanelObject *po)
|
||||
{
|
||||
list_of_panels *temp, *n;
|
||||
@ -154,25 +300,23 @@ remove_lop(PyCursesPanelObject *po)
|
||||
if (temp->po == po) {
|
||||
lop = temp->next;
|
||||
PyMem_Free(temp);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
while (temp->next == NULL || temp->next->po != po) {
|
||||
if (temp->next == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"remove_lop: can't find Panel Object");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
n = temp->next->next;
|
||||
PyMem_Free(temp->next);
|
||||
temp->next = n;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the panel object that corresponds to pan */
|
||||
static PyCursesPanelObject *
|
||||
find_po(PANEL *pan)
|
||||
find_po_impl(PANEL *pan)
|
||||
{
|
||||
list_of_panels *temp;
|
||||
for (temp = lop; temp->po->pan != pan; temp = temp->next)
|
||||
@ -180,6 +324,17 @@ find_po(PANEL *pan)
|
||||
return temp->po;
|
||||
}
|
||||
|
||||
/* Same as find_po_impl() but with caller context information. */
|
||||
static PyCursesPanelObject *
|
||||
find_po(PANEL *pan, const char *called_funcname, const char *caller_funcname)
|
||||
{
|
||||
PyCursesPanelObject *res = find_po_impl(pan);
|
||||
if (res == NULL) {
|
||||
curses_panel_notfound_error(called_funcname, caller_funcname);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
module _curses_panel
|
||||
class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type"
|
||||
@ -193,67 +348,59 @@ class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type"
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.bottom
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Push the panel to the bottom of the stack.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=8ec7fbbc08554021 input=6b7d2c0578b5a1c4]*/
|
||||
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self)
|
||||
/*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, bottom_panel(self->pan), "bottom");
|
||||
int rtn = bottom_panel(self->pan);
|
||||
return curses_panel_panel_check_err(self, rtn, "bottom_panel", "bottom");
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.hide
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Hide the panel.
|
||||
|
||||
This does not delete the object, it just makes the window on screen invisible.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=cc6ab7203cdc1450 input=1bfc741f473e6055]*/
|
||||
_curses_panel_panel_hide_impl(PyCursesPanelObject *self)
|
||||
/*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, hide_panel(self->pan), "hide");
|
||||
int rtn = hide_panel(self->pan);
|
||||
return curses_panel_panel_check_err(self, rtn, "hide_panel", "hide");
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.show
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Display the panel (which might have been hidden).
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=dc3421de375f0409 input=8122e80151cb4379]*/
|
||||
_curses_panel_panel_show_impl(PyCursesPanelObject *self)
|
||||
/*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, show_panel(self->pan), "show");
|
||||
int rtn = show_panel(self->pan);
|
||||
return curses_panel_panel_check_err(self, rtn, "show_panel", "show");
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.top
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Push panel to the top of the stack.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=10a072e511e873f7 input=1f372d597dda3379]*/
|
||||
_curses_panel_panel_top_impl(PyCursesPanelObject *self)
|
||||
/*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, top_panel(self->pan), "top");
|
||||
int rtn = top_panel(self->pan);
|
||||
return curses_panel_panel_check_err(self, rtn, "top_panel", "top");
|
||||
}
|
||||
|
||||
/* Allocation and deallocation of Panel Objects */
|
||||
@ -287,13 +434,22 @@ PyCursesPanel_Dealloc(PyObject *self)
|
||||
tp = (PyObject *) Py_TYPE(po);
|
||||
obj = (PyObject *) panel_userptr(po->pan);
|
||||
if (obj) {
|
||||
(void)set_panel_userptr(po->pan, NULL);
|
||||
Py_DECREF(obj);
|
||||
if (set_panel_userptr(po->pan, NULL) == ERR) {
|
||||
curses_panel_panel_set_error(po, "set_panel_userptr", "__del__");
|
||||
PyErr_FormatUnraisable("Exception ignored in PyCursesPanel_Dealloc()");
|
||||
}
|
||||
}
|
||||
if (del_panel(po->pan) == ERR && !PyErr_Occurred()) {
|
||||
curses_panel_panel_set_error(po, "del_panel", "__del__");
|
||||
PyErr_FormatUnraisable("Exception ignored in PyCursesPanel_Dealloc()");
|
||||
}
|
||||
(void)del_panel(po->pan);
|
||||
if (po->wo != NULL) {
|
||||
Py_DECREF(po->wo);
|
||||
remove_lop(po);
|
||||
if (remove_lop(po) < 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "__del__: no panel object to delete");
|
||||
PyErr_FormatUnraisable("Exception ignored in PyCursesPanel_Dealloc()");
|
||||
}
|
||||
}
|
||||
PyObject_Free(po);
|
||||
Py_DECREF(tp);
|
||||
@ -315,18 +471,11 @@ _curses_panel_panel_above_impl(PyCursesPanelObject *self)
|
||||
PyCursesPanelObject *po;
|
||||
|
||||
pan = panel_above(self->pan);
|
||||
|
||||
if (pan == NULL) { /* valid output, it means the calling panel
|
||||
is on top of the stack */
|
||||
if (pan == NULL) { /* valid output: it means no panel exists yet */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
po = find_po(pan);
|
||||
if (po == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"panel_above: can't find Panel Object");
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(po);
|
||||
po = find_po(pan, "panel_above", "above");
|
||||
return Py_XNewRef(po);
|
||||
}
|
||||
|
||||
/* panel_below(NULL) returns the top panel in the stack. To get
|
||||
@ -345,18 +494,11 @@ _curses_panel_panel_below_impl(PyCursesPanelObject *self)
|
||||
PyCursesPanelObject *po;
|
||||
|
||||
pan = panel_below(self->pan);
|
||||
|
||||
if (pan == NULL) { /* valid output, it means the calling panel
|
||||
is on the bottom of the stack */
|
||||
if (pan == NULL) { /* valid output: it means no panel exists yet */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
po = find_po(pan);
|
||||
if (po == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"panel_below: can't find Panel Object");
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(po);
|
||||
po = find_po(pan, "panel_below", "below");
|
||||
return Py_XNewRef(po);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@ -378,7 +520,6 @@ _curses_panel_panel_hidden_impl(PyCursesPanelObject *self)
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.move
|
||||
|
||||
cls: defining_class
|
||||
y: int
|
||||
x: int
|
||||
/
|
||||
@ -387,12 +528,11 @@ Move the panel to the screen coordinates (y, x).
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
|
||||
int y, int x)
|
||||
/*[clinic end generated code: output=ce546c93e56867da input=60a0e7912ff99849]*/
|
||||
_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x)
|
||||
/*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, move_panel(self->pan, y, x), "move_panel");
|
||||
int rtn = move_panel(self->pan, y, x);
|
||||
return curses_panel_panel_check_err(self, rtn, "move_panel", "move");
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@ -411,7 +551,6 @@ _curses_panel_panel_window_impl(PyCursesPanelObject *self)
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.replace
|
||||
|
||||
cls: defining_class
|
||||
win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
|
||||
/
|
||||
|
||||
@ -420,22 +559,17 @@ Change the window associated with the panel to the window win.
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_replace_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls,
|
||||
PyCursesWindowObject *win)
|
||||
/*[clinic end generated code: output=c71f95c212d58ae7 input=dbec7180ece41ff5]*/
|
||||
/*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
|
||||
PyCursesPanelObject *po = find_po(self->pan);
|
||||
PyCursesPanelObject *po = find_po(self->pan, "replace", NULL);
|
||||
if (po == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"replace_panel: can't find Panel Object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rtn = replace_panel(self->pan, win->win);
|
||||
if (rtn == ERR) {
|
||||
PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR");
|
||||
curses_panel_panel_set_error(self, "replace_panel", "replace");
|
||||
return NULL;
|
||||
}
|
||||
Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win));
|
||||
@ -445,7 +579,6 @@ _curses_panel_panel_replace_impl(PyCursesPanelObject *self,
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.set_userptr
|
||||
|
||||
cls: defining_class
|
||||
obj: object
|
||||
/
|
||||
|
||||
@ -454,8 +587,8 @@ Set the panel's user pointer to obj.
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls, PyObject *obj)
|
||||
/*[clinic end generated code: output=db74f3db07b28080 input=e3fee2ff7b1b8e48]*/
|
||||
PyObject *obj)
|
||||
/*[clinic end generated code: output=7fa1fd23f69db71e input=d2c6a9dbefabbf39]*/
|
||||
{
|
||||
PyCursesInitialised;
|
||||
Py_INCREF(obj);
|
||||
@ -464,34 +597,27 @@ _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
|
||||
if (rc == ERR) {
|
||||
/* In case of an ncurses error, decref the new object again */
|
||||
Py_DECREF(obj);
|
||||
curses_panel_panel_set_error(self, "set_panel_userptr", "set_userptr");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Py_XDECREF(oldobj);
|
||||
}
|
||||
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
return PyCursesCheckERR(state, rc, "set_panel_userptr");
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_curses_panel.panel.userptr
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Return the user pointer for the panel.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=eea6e6f39ffc0179 input=f22ca4f115e30a80]*/
|
||||
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self)
|
||||
/*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/
|
||||
{
|
||||
_curses_panel_state *state = PyType_GetModuleState(cls);
|
||||
|
||||
PyCursesInitialised;
|
||||
PyObject *obj = (PyObject *) panel_userptr(self->pan);
|
||||
if (obj == NULL) {
|
||||
PyErr_SetString(state->PyCursesError, "no userptr set");
|
||||
curses_panel_panel_set_null_error(self, "panel_userptr", "userptr");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -552,18 +678,11 @@ _curses_panel_bottom_panel_impl(PyObject *module)
|
||||
PyCursesInitialised;
|
||||
|
||||
pan = panel_above(NULL);
|
||||
|
||||
if (pan == NULL) { /* valid output, it means
|
||||
there's no panel at all */
|
||||
if (pan == NULL) { /* valid output: it means no panel exists yet */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
po = find_po(pan);
|
||||
if (po == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"panel_above: can't find Panel Object");
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(po);
|
||||
po = find_po(pan, "panel_above", "bottom_panel");
|
||||
return Py_XNewRef(po);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@ -579,14 +698,13 @@ static PyObject *
|
||||
_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win)
|
||||
/*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/
|
||||
{
|
||||
_curses_panel_state *state = get_curses_panel_state(module);
|
||||
|
||||
PANEL *pan = new_panel(win->win);
|
||||
if (pan == NULL) {
|
||||
PyErr_SetString(state->PyCursesError, catchall_NULL);
|
||||
curses_panel_set_null_error(module, "new_panel", NULL);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)PyCursesPanel_New(state, pan, win);
|
||||
_curses_panel_state *state = get_curses_panel_state(module);
|
||||
return PyCursesPanel_New(state, pan, win);
|
||||
}
|
||||
|
||||
|
||||
@ -610,18 +728,11 @@ _curses_panel_top_panel_impl(PyObject *module)
|
||||
PyCursesInitialised;
|
||||
|
||||
pan = panel_below(NULL);
|
||||
|
||||
if (pan == NULL) { /* valid output, it means
|
||||
there's no panel at all */
|
||||
if (pan == NULL) { /* valid output: it means no panel exists yet */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
po = find_po(pan);
|
||||
if (po == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"panel_below: can't find Panel Object");
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(po);
|
||||
po = find_po(pan, "panel_below", "top_panel");
|
||||
return Py_XNewRef(po);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@ -673,10 +784,10 @@ _curses_panel_exec(PyObject *mod)
|
||||
}
|
||||
|
||||
/* For exception _curses_panel.error */
|
||||
state->PyCursesError = PyErr_NewException(
|
||||
state->error = PyErr_NewException(
|
||||
"_curses_panel.error", NULL, NULL);
|
||||
|
||||
if (PyModule_AddObjectRef(mod, "error", state->PyCursesError) < 0) {
|
||||
if (PyModule_AddObjectRef(mod, "error", state->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
157
Modules/clinic/_curses_panel.c.h
generated
157
Modules/clinic/_curses_panel.c.h
generated
@ -2,10 +2,7 @@
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# include "pycore_runtime.h" // _Py_SINGLETON()
|
||||
#endif
|
||||
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
||||
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_panel_bottom__doc__,
|
||||
"bottom($self, /)\n"
|
||||
@ -14,19 +11,15 @@ PyDoc_STRVAR(_curses_panel_panel_bottom__doc__,
|
||||
"Push the panel to the bottom of the stack.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \
|
||||
{"bottom", _PyCFunction_CAST(_curses_panel_panel_bottom), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__},
|
||||
{"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls);
|
||||
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_bottom(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_bottom(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
|
||||
PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return _curses_panel_panel_bottom_impl((PyCursesPanelObject *)self, cls);
|
||||
return _curses_panel_panel_bottom_impl((PyCursesPanelObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_panel_hide__doc__,
|
||||
@ -38,19 +31,15 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__,
|
||||
"This does not delete the object, it just makes the window on screen invisible.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_HIDE_METHODDEF \
|
||||
{"hide", _PyCFunction_CAST(_curses_panel_panel_hide), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__},
|
||||
{"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls);
|
||||
_curses_panel_panel_hide_impl(PyCursesPanelObject *self);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_hide(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_hide(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
|
||||
PyErr_SetString(PyExc_TypeError, "hide() takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return _curses_panel_panel_hide_impl((PyCursesPanelObject *)self, cls);
|
||||
return _curses_panel_panel_hide_impl((PyCursesPanelObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_panel_show__doc__,
|
||||
@ -60,19 +49,15 @@ PyDoc_STRVAR(_curses_panel_panel_show__doc__,
|
||||
"Display the panel (which might have been hidden).");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_SHOW_METHODDEF \
|
||||
{"show", _PyCFunction_CAST(_curses_panel_panel_show), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__},
|
||||
{"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls);
|
||||
_curses_panel_panel_show_impl(PyCursesPanelObject *self);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_show(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_show(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
|
||||
PyErr_SetString(PyExc_TypeError, "show() takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return _curses_panel_panel_show_impl((PyCursesPanelObject *)self, cls);
|
||||
return _curses_panel_panel_show_impl((PyCursesPanelObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_panel_top__doc__,
|
||||
@ -82,19 +67,15 @@ PyDoc_STRVAR(_curses_panel_panel_top__doc__,
|
||||
"Push panel to the top of the stack.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_TOP_METHODDEF \
|
||||
{"top", _PyCFunction_CAST(_curses_panel_panel_top), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__},
|
||||
{"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls);
|
||||
_curses_panel_panel_top_impl(PyCursesPanelObject *self);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_top(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_top(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
|
||||
PyErr_SetString(PyExc_TypeError, "top() takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return _curses_panel_panel_top_impl((PyCursesPanelObject *)self, cls);
|
||||
return _curses_panel_panel_top_impl((PyCursesPanelObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_panel_above__doc__,
|
||||
@ -158,36 +139,19 @@ PyDoc_STRVAR(_curses_panel_panel_move__doc__,
|
||||
"Move the panel to the screen coordinates (y, x).");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_MOVE_METHODDEF \
|
||||
{"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__},
|
||||
{"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_FASTCALL, _curses_panel_panel_move__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
|
||||
int y, int x);
|
||||
_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_move(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_move(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
|
||||
#else
|
||||
# define KWTUPLE NULL
|
||||
#endif
|
||||
|
||||
static const char * const _keywords[] = {"", "", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "move",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[2];
|
||||
int y;
|
||||
int x;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
|
||||
/*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
||||
if (!args) {
|
||||
if (!_PyArg_CheckPositional("move", nargs, 2, 2)) {
|
||||
goto exit;
|
||||
}
|
||||
y = PyLong_AsInt(args[0]);
|
||||
@ -198,7 +162,7 @@ _curses_panel_panel_move(PyObject *self, PyTypeObject *cls, PyObject *const *arg
|
||||
if (x == -1 && PyErr_Occurred()) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _curses_panel_panel_move_impl((PyCursesPanelObject *)self, cls, y, x);
|
||||
return_value = _curses_panel_panel_move_impl((PyCursesPanelObject *)self, y, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
@ -229,44 +193,24 @@ PyDoc_STRVAR(_curses_panel_panel_replace__doc__,
|
||||
"Change the window associated with the panel to the window win.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \
|
||||
{"replace", _PyCFunction_CAST(_curses_panel_panel_replace), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__},
|
||||
{"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_replace_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls,
|
||||
PyCursesWindowObject *win);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_replace(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_replace(PyObject *self, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
|
||||
#else
|
||||
# define KWTUPLE NULL
|
||||
#endif
|
||||
|
||||
static const char * const _keywords[] = {"", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "replace",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyCursesWindowObject *win;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
|
||||
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
||||
if (!args) {
|
||||
if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) {
|
||||
_PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg);
|
||||
goto exit;
|
||||
}
|
||||
if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) {
|
||||
_PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]);
|
||||
goto exit;
|
||||
}
|
||||
win = (PyCursesWindowObject *)args[0];
|
||||
return_value = _curses_panel_panel_replace_impl((PyCursesPanelObject *)self, cls, win);
|
||||
win = (PyCursesWindowObject *)arg;
|
||||
return_value = _curses_panel_panel_replace_impl((PyCursesPanelObject *)self, win);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
@ -279,41 +223,19 @@ PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__,
|
||||
"Set the panel\'s user pointer to obj.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \
|
||||
{"set_userptr", _PyCFunction_CAST(_curses_panel_panel_set_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__},
|
||||
{"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls, PyObject *obj);
|
||||
PyObject *obj);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_set_userptr(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_set_userptr(PyObject *self, PyObject *obj)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
|
||||
#else
|
||||
# define KWTUPLE NULL
|
||||
#endif
|
||||
|
||||
static const char * const _keywords[] = {"", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "set_userptr",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject *obj;
|
||||
return_value = _curses_panel_panel_set_userptr_impl((PyCursesPanelObject *)self, obj);
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
|
||||
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
obj = args[0];
|
||||
return_value = _curses_panel_panel_set_userptr_impl((PyCursesPanelObject *)self, cls, obj);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@ -324,20 +246,15 @@ PyDoc_STRVAR(_curses_panel_panel_userptr__doc__,
|
||||
"Return the user pointer for the panel.");
|
||||
|
||||
#define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \
|
||||
{"userptr", _PyCFunction_CAST(_curses_panel_panel_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__},
|
||||
{"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__},
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
|
||||
PyTypeObject *cls);
|
||||
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self);
|
||||
|
||||
static PyObject *
|
||||
_curses_panel_panel_userptr(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_curses_panel_panel_userptr(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
|
||||
PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return _curses_panel_panel_userptr_impl((PyCursesPanelObject *)self, cls);
|
||||
return _curses_panel_panel_userptr_impl((PyCursesPanelObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_curses_panel_bottom_panel__doc__,
|
||||
@ -424,4 +341,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return _curses_panel_update_panels_impl(module);
|
||||
}
|
||||
/*[clinic end generated code: output=36853ecb4a979814 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=db2fe491582784aa input=a9049054013a1b77]*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user