diff options
Diffstat (limited to 'Modules/_cursesmodule.c')
-rw-r--r-- | Modules/_cursesmodule.c | 535 |
1 files changed, 355 insertions, 180 deletions
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index cd185bc2b02..ab63fdbe45d 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -211,18 +211,116 @@ static int curses_start_color_called = FALSE; static const char *curses_screen_encoding = NULL; +/* Utility Error Procedures */ + +static void +_curses_format_error(cursesmodule_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_set_error(cursesmodule_state *state, + const char *curses_funcname, + const char *python_funcname) +{ + _curses_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 inline void +_curses_set_null_error(cursesmodule_state *state, + const char *curses_funcname, + const char *python_funcname) +{ + _curses_format_error(state, curses_funcname, python_funcname, + "NULL", catchall_NULL); +} + +/* Same as _curses_set_error() for a module object. */ +static void +curses_set_error(PyObject *module, + const char *curses_funcname, + const char *python_funcname) +{ + cursesmodule_state *state = get_cursesmodule_state(module); + _curses_set_error(state, curses_funcname, python_funcname); +} + +/* Same as _curses_set_null_error() for a module object. */ +static void +curses_set_null_error(PyObject *module, + const char *curses_funcname, + const char *python_funcname) +{ + cursesmodule_state *state = get_cursesmodule_state(module); + _curses_set_null_error(state, curses_funcname, python_funcname); +} + +/* Same as _curses_set_error() for a Window object. */ +static void +curses_window_set_error(PyCursesWindowObject *win, + const char *curses_funcname, + const char *python_funcname) +{ + cursesmodule_state *state = get_cursesmodule_state_by_win(win); + _curses_set_error(state, curses_funcname, python_funcname); +} + +/* Same as _curses_set_null_error() for a Window object. */ +static void +curses_window_set_null_error(PyCursesWindowObject *win, + const char *curses_funcname, + const char *python_funcname) +{ + cursesmodule_state *state = get_cursesmodule_state_by_win(win); + _curses_set_null_error(state, curses_funcname, python_funcname); +} + /* Utility Checking Procedures */ /* * Function to check that 'funcname' has been called by testing - * the 'called' boolean. If an error occurs, a PyCursesError is + * the 'called' boolean. If an error occurs, an exception is * set and this returns 0. Otherwise, this returns 1. * * Since this function can be called in functions that do not * have a direct access to the module's state, '_curses.error' * is imported on demand. + * + * Use _PyCursesStatefulCheckFunction() if the module is given. */ -static inline int +static int _PyCursesCheckFunction(int called, const char *funcname) { if (called == TRUE) { @@ -230,7 +328,7 @@ _PyCursesCheckFunction(int called, const char *funcname) } PyObject *exc = PyImport_ImportModuleAttrString("_curses", "error"); if (exc != NULL) { - PyErr_Format(exc, "must call %s() first", funcname); + PyErr_Format(exc, CURSES_ERROR_MUST_CALL_FORMAT, funcname); Py_DECREF(exc); } assert(PyErr_Occurred()); @@ -244,14 +342,15 @@ _PyCursesCheckFunction(int called, const char *funcname) * * The exception type is obtained from the 'module' state. */ -static inline int -_PyCursesStatefulCheckFunction(PyObject *module, int called, const char *funcname) +static int +_PyCursesStatefulCheckFunction(PyObject *module, + int called, const char *funcname) { if (called == TRUE) { return 1; } cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_Format(state->error, "must call %s() first", funcname); + PyErr_Format(state->error, CURSES_ERROR_MUST_CALL_FORMAT, funcname); return 0; } @@ -287,44 +386,41 @@ _PyCursesStatefulCheckFunction(PyObject *module, int called, const char *funcnam /* Utility Functions */ -static inline void -_PyCursesSetError(cursesmodule_state *state, const char *funcname) -{ - if (funcname == NULL) { - PyErr_SetString(state->error, catchall_ERR); - } - else { - PyErr_Format(state->error, "%s() returned ERR", funcname); - } -} - /* - * 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 OK. Otherwise, set an exception + * using curses_set_error() and the remaining arguments, and + * return NULL. + */ static PyObject * -PyCursesCheckERR(PyObject *module, int code, const char *fname) +curses_check_err(PyObject *module, int code, + const char *curses_funcname, + const char *python_funcname) { if (code != ERR) { + assert(code == OK); Py_RETURN_NONE; - } else { - cursesmodule_state *state = get_cursesmodule_state(module); - _PyCursesSetError(state, fname); - return NULL; } + curses_set_error(module, curses_funcname, python_funcname); + return NULL; } +/* Same as curses_check_err() for a Window object. */ static PyObject * -PyCursesCheckERR_ForWin(PyCursesWindowObject *win, int code, const char *fname) +curses_window_check_err(PyCursesWindowObject *win, int code, + const char *curses_funcname, + const char *python_funcname) { if (code != ERR) { + assert(code == OK); Py_RETURN_NONE; - } else { - cursesmodule_state *state = get_cursesmodule_state_by_win(win); - _PyCursesSetError(state, fname); - return NULL; } + curses_window_set_error(win, curses_funcname, python_funcname); + return NULL; } /* Convert an object to a byte (an integer of type chtype): @@ -650,13 +746,16 @@ class component_converter(CConverter): The Window Object ******************************************************************************/ -/* Function prototype macros for Window object - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing -*/ +/* + * Macros for creating a PyCursesWindowObject object's method. + * + * Parameters + * + * X The name of the curses C function or macro to invoke. + * TYPE The function parameter(s) type. + * ERGSTR The format string for construction of the return value. + * PARSESTR The format string for argument parsing. + */ #define Window_NoArgNoReturnFunction(X) \ static PyObject *PyCursesWindow_ ## X \ @@ -664,7 +763,7 @@ class component_converter(CConverter): { \ PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); \ int code = X(self->win); \ - return PyCursesCheckERR_ForWin(self, code, # X); \ + return curses_window_check_err(self, code, # X, NULL); \ } #define Window_NoArgTrueFalseFunction(X) \ @@ -717,7 +816,7 @@ class component_converter(CConverter): } \ PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); \ int code = X(self->win, arg1); \ - return PyCursesCheckERR_ForWin(self, code, # X); \ + return curses_window_check_err(self, code, # X, NULL); \ } #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ @@ -730,7 +829,7 @@ class component_converter(CConverter): } \ PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); \ int code = X(self->win, arg1, arg2); \ - return PyCursesCheckERR_ForWin(self, code, # X); \ + return curses_window_check_err(self, code, # X, NULL); \ } /* ------------- WINDOW routines --------------- */ @@ -903,13 +1002,15 @@ _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, #ifdef HAVE_NCURSESW type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr); if (type == 2) { - funcname = "add_wch"; wstr[1] = L'\0'; setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL); - if (coordinates_group) + if (coordinates_group) { rtn = mvwadd_wch(self->win,y,x, &wcval); + funcname = "mvwadd_wch"; + } else { rtn = wadd_wch(self->win, &wcval); + funcname = "wadd_wch"; } } else @@ -917,17 +1018,19 @@ _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, type = PyCurses_ConvertToCchar_t(self, ch, &cch); #endif if (type == 1) { - funcname = "addch"; - if (coordinates_group) + if (coordinates_group) { rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr); + funcname = "mvwaddch"; + } else { rtn = waddch(self->win, cch | (attr_t) attr); + funcname = "waddch"; } } else { return NULL; } - return PyCursesCheckERR_ForWin(self, rtn, funcname); + return curses_window_check_err(self, rtn, funcname, "addch"); } /*[clinic input] @@ -987,27 +1090,33 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, } #ifdef HAVE_NCURSESW if (strtype == 2) { - funcname = "addwstr"; - if (use_xy) + if (use_xy) { rtn = mvwaddwstr(self->win,y,x,wstr); - else + funcname = "mvwaddwstr"; + } + else { rtn = waddwstr(self->win,wstr); + funcname = "waddwstr"; + } PyMem_Free(wstr); } else #endif { const char *str = PyBytes_AS_STRING(bytesobj); - funcname = "addstr"; - if (use_xy) + if (use_xy) { rtn = mvwaddstr(self->win,y,x,str); - else + funcname = "mvwaddstr"; + } + else { rtn = waddstr(self->win,str); + funcname = "waddstr"; + } Py_DECREF(bytesobj); } if (use_attr) (void)wattrset(self->win,attr_old); - return PyCursesCheckERR_ForWin(self, rtn, funcname); + return curses_window_check_err(self, rtn, funcname, "addstr"); } /*[clinic input] @@ -1070,27 +1179,33 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, } #ifdef HAVE_NCURSESW if (strtype == 2) { - funcname = "addnwstr"; - if (use_xy) + if (use_xy) { rtn = mvwaddnwstr(self->win,y,x,wstr,n); - else + funcname = "mvwaddnwstr"; + } + else { rtn = waddnwstr(self->win,wstr,n); + funcname = "waddnwstr"; + } PyMem_Free(wstr); } else #endif { const char *str = PyBytes_AS_STRING(bytesobj); - funcname = "addnstr"; - if (use_xy) + if (use_xy) { rtn = mvwaddnstr(self->win,y,x,str,n); - else + funcname = "mvwaddnstr"; + } + else { rtn = waddnstr(self->win,str,n); + funcname = "waddnstr"; + } Py_DECREF(bytesobj); } if (use_attr) (void)wattrset(self->win,attr_old); - return PyCursesCheckERR_ForWin(self, rtn, funcname); + return curses_window_check_err(self, rtn, funcname, "addnstr"); } /*[clinic input] @@ -1114,7 +1229,8 @@ _curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr) if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) return NULL; - return PyCursesCheckERR_ForWin(self, wbkgd(self->win, bkgd | attr), "bkgd"); + int rtn = wbkgd(self->win, bkgd | attr); + return curses_window_check_err(self, rtn, "wbkgd", "bkgd"); } /*[clinic input] @@ -1130,7 +1246,8 @@ static PyObject * _curses_window_attroff_impl(PyCursesWindowObject *self, long attr) /*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/ { - return PyCursesCheckERR_ForWin(self, wattroff(self->win, (attr_t)attr), "attroff"); + int rtn = wattroff(self->win, (attr_t)attr); + return curses_window_check_err(self, rtn, "wattroff", "attroff"); } /*[clinic input] @@ -1146,7 +1263,8 @@ static PyObject * _curses_window_attron_impl(PyCursesWindowObject *self, long attr) /*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/ { - return PyCursesCheckERR_ForWin(self, wattron(self->win, (attr_t)attr), "attron"); + int rtn = wattron(self->win, (attr_t)attr); + return curses_window_check_err(self, rtn, "wattron", "attron"); } /*[clinic input] @@ -1162,7 +1280,8 @@ static PyObject * _curses_window_attrset_impl(PyCursesWindowObject *self, long attr) /*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/ { - return PyCursesCheckERR_ForWin(self, wattrset(self->win, (attr_t)attr), "attrset"); + int rtn = wattrset(self->win, (attr_t)attr); + return curses_window_check_err(self, rtn, "wattrset", "attrset"); } /*[clinic input] @@ -1188,7 +1307,7 @@ _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, return NULL; wbkgdset(self->win, bkgd | attr); - return PyCursesCheckERR_ForWin(self, 0, "bkgdset"); + Py_RETURN_NONE; } /*[clinic input] @@ -1344,6 +1463,7 @@ PyCursesWindow_ChgAt(PyObject *op, PyObject *args) PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); int rtn; + const char *funcname; int x, y; int num = -1; short color; @@ -1385,12 +1505,14 @@ PyCursesWindow_ChgAt(PyObject *op, PyObject *args) if (use_xy) { rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); touchline(self->win,y,1); + funcname = "mvwchgat"; } else { getyx(self->win,y,x); rtn = wchgat(self->win,num,attr,color,NULL); touchline(self->win,y,1); + funcname = "wchgat"; } - return PyCursesCheckERR_ForWin(self, rtn, "chgat"); + return curses_window_check_err(self, rtn, funcname, "chgat"); } #endif @@ -1413,12 +1535,17 @@ _curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, int y, int x) /*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/ { + int rtn; + const char *funcname; if (!group_right_1) { - return PyCursesCheckERR_ForWin(self, wdelch(self->win), "wdelch"); + rtn = wdelch(self->win); + funcname = "wdelch"; } else { - return PyCursesCheckERR_ForWin(self, py_mvwdelch(self->win, y, x), "mvwdelch"); + rtn = py_mvwdelch(self->win, y, x); + funcname = "mvwdelch"; } + return curses_window_check_err(self, rtn, funcname, "delch"); } /*[clinic input] @@ -1453,8 +1580,7 @@ _curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, win = derwin(self->win,nlines,ncols,begin_y,begin_x); if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state_by_win(self); - PyErr_SetString(state->error, catchall_NULL); + curses_window_set_error(self, "derwin", NULL); return NULL; } @@ -1485,17 +1611,20 @@ _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + int rtn; + const char *funcname; #ifdef py_is_pad if (py_is_pad(self->win)) { - return PyCursesCheckERR_ForWin(self, - pechochar(self->win, ch_ | (attr_t)attr), - "echochar"); + rtn = pechochar(self->win, ch_ | (attr_t)attr); + funcname = "pechochar"; } else #endif - return PyCursesCheckERR_ForWin(self, - wechochar(self->win, ch_ | (attr_t)attr), - "echochar"); + { + rtn = wechochar(self->win, ch_ | (attr_t)attr); + funcname = "wechochar"; + } + return curses_window_check_err(self, rtn, funcname, "echochar"); } #ifdef NCURSES_MOUSE_VERSION @@ -1608,7 +1737,8 @@ _curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, PyErr_CheckSignals(); if (!PyErr_Occurred()) { cursesmodule_state *state = get_cursesmodule_state_by_win(self); - PyErr_SetString(state->error, "no input"); + const char *funcname = group_right_1 ? "mvwgetch" : "wgetch"; + PyErr_Format(state->error, "getkey(): %s(): no input", funcname); } return NULL; } else if (rtn <= 255) { @@ -1668,7 +1798,8 @@ _curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, /* get_wch() returns ERR in nodelay mode */ cursesmodule_state *state = get_cursesmodule_state_by_win(self); - PyErr_SetString(state->error, "no input"); + const char *funcname = group_right_1 ? "mvwget_wch" : "wget_wch"; + PyErr_Format(state->error, "get_wch(): %s(): no input", funcname); return NULL; } if (ct == KEY_CODE_YES) @@ -1794,10 +1925,12 @@ _curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, return NULL; if (group_left_1) { if (wmove(self->win, y, x) == ERR) { - return PyCursesCheckERR_ForWin(self, ERR, "wmove"); + curses_window_set_error(self, "wmove", "hline"); + return NULL; } } - return PyCursesCheckERR_ForWin(self, whline(self->win, ch_ | (attr_t)attr, n), "hline"); + int rtn = whline(self->win, ch_ | (attr_t)attr, n); + return curses_window_check_err(self, rtn, "whline", "hline"); } /*[clinic input] @@ -1837,14 +1970,17 @@ _curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + const char *funcname; if (!group_left_1) { rtn = winsch(self->win, ch_ | (attr_t)attr); + funcname = "winsch"; } else { rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr); + funcname = "mvwwinsch"; } - return PyCursesCheckERR_ForWin(self, rtn, "insch"); + return curses_window_check_err(self, rtn, funcname, "insch"); } /*[clinic input] @@ -2003,27 +2139,33 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, } #ifdef HAVE_NCURSESW if (strtype == 2) { - funcname = "inswstr"; - if (use_xy) + if (use_xy) { rtn = mvwins_wstr(self->win,y,x,wstr); - else + funcname = "mvwins_wstr"; + } + else { rtn = wins_wstr(self->win,wstr); + funcname = "wins_wstr"; + } PyMem_Free(wstr); } else #endif { const char *str = PyBytes_AS_STRING(bytesobj); - funcname = "insstr"; - if (use_xy) + if (use_xy) { rtn = mvwinsstr(self->win,y,x,str); - else + funcname = "mvwinsstr"; + } + else { rtn = winsstr(self->win,str); + funcname = "winsstr"; + } Py_DECREF(bytesobj); } if (use_attr) (void)wattrset(self->win,attr_old); - return PyCursesCheckERR_ForWin(self, rtn, funcname); + return curses_window_check_err(self, rtn, funcname, "insstr"); } /*[clinic input] @@ -2088,27 +2230,33 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, } #ifdef HAVE_NCURSESW if (strtype == 2) { - funcname = "insn_wstr"; - if (use_xy) + if (use_xy) { rtn = mvwins_nwstr(self->win,y,x,wstr,n); - else + funcname = "mvwins_nwstr"; + } + else { rtn = wins_nwstr(self->win,wstr,n); + funcname = "wins_nwstr"; + } PyMem_Free(wstr); } else #endif { const char *str = PyBytes_AS_STRING(bytesobj); - funcname = "insnstr"; - if (use_xy) + if (use_xy) { rtn = mvwinsnstr(self->win,y,x,str,n); - else + funcname = "mvwinsnstr"; + } + else { rtn = winsnstr(self->win,str,n); + funcname = "winsnstr"; + } Py_DECREF(bytesobj); } if (use_attr) (void)wattrset(self->win,attr_old); - return PyCursesCheckERR_ForWin(self, rtn, funcname); + return curses_window_check_err(self, rtn, funcname, "insnstr"); } /*[clinic input] @@ -2130,8 +2278,7 @@ _curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line) int erg; erg = is_linetouched(self->win, line); if (erg == ERR) { - PyErr_SetString(PyExc_TypeError, - "is_linetouched: line number outside of boundaries"); + curses_window_set_error(self, "is_linetouched", NULL); return NULL; } return PyBool_FromLong(erg); @@ -2195,7 +2342,8 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject *self) rtn = pnoutrefresh(self->win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); Py_END_ALLOW_THREADS - return PyCursesCheckERR_ForWin(self, rtn, "pnoutrefresh"); + return curses_window_check_err(self, rtn, + "pnoutrefresh", "noutrefresh"); } if (group_right_1) { PyErr_SetString(PyExc_TypeError, @@ -2206,7 +2354,7 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject *self) Py_BEGIN_ALLOW_THREADS rtn = wnoutrefresh(self->win); Py_END_ALLOW_THREADS - return PyCursesCheckERR_ForWin(self, rtn, "wnoutrefresh"); + return curses_window_check_err(self, rtn, "wnoutrefresh", "noutrefresh"); } /*[clinic input] @@ -2248,11 +2396,11 @@ _curses_window_overlay_impl(PyCursesWindowObject *self, if (group_right_1) { rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, TRUE); - return PyCursesCheckERR_ForWin(self, rtn, "copywin"); + return curses_window_check_err(self, rtn, "copywin", "overlay"); } else { rtn = overlay(self->win, destwin->win); - return PyCursesCheckERR_ForWin(self, rtn, "overlay"); + return curses_window_check_err(self, rtn, "overlay", NULL); } } @@ -2296,11 +2444,11 @@ _curses_window_overwrite_impl(PyCursesWindowObject *self, if (group_right_1) { rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, FALSE); - return PyCursesCheckERR_ForWin(self, rtn, "copywin"); + return curses_window_check_err(self, rtn, "copywin", "overwrite"); } else { rtn = overwrite(self->win, destwin->win); - return PyCursesCheckERR_ForWin(self, rtn, "overwrite"); + return curses_window_check_err(self, rtn, "overwrite", NULL); } } @@ -2329,7 +2477,7 @@ _curses_window_putwin_impl(PyCursesWindowObject *self, PyObject *file) return PyErr_SetFromErrno(PyExc_OSError); if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto exit; - res = PyCursesCheckERR_ForWin(self, putwin(self->win, fp), "putwin"); + res = curses_window_check_err(self, putwin(self->win, fp), "putwin", NULL); if (res == NULL) goto exit; fseek(fp, 0, 0); @@ -2368,7 +2516,8 @@ static PyObject * _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num) /*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/ { - return PyCursesCheckERR_ForWin(self, wredrawln(self->win,beg,num), "redrawln"); + int rtn = wredrawln(self->win,beg, num); + return curses_window_check_err(self, rtn, "wredrawln", "redrawln"); } /*[clinic input] @@ -2419,7 +2568,7 @@ _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, rtn = prefresh(self->win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); Py_END_ALLOW_THREADS - return PyCursesCheckERR_ForWin(self, rtn, "prefresh"); + return curses_window_check_err(self, rtn, "prefresh", "refresh"); } #endif if (group_right_1) { @@ -2430,7 +2579,7 @@ _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, Py_BEGIN_ALLOW_THREADS rtn = wrefresh(self->win); Py_END_ALLOW_THREADS - return PyCursesCheckERR_ForWin(self, rtn, "prefresh"); + return curses_window_check_err(self, rtn, "wrefresh", "refresh"); } /*[clinic input] @@ -2452,7 +2601,8 @@ _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, int bottom) /*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/ { - return PyCursesCheckERR_ForWin(self, wsetscrreg(self->win, top, bottom), "wsetscrreg"); + int rtn = wsetscrreg(self->win, top, bottom); + return curses_window_check_err(self, rtn, "wsetscrreg", "setscrreg"); } /*[clinic input] @@ -2482,19 +2632,23 @@ _curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, /*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/ { WINDOW *win; + const char *funcname; /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ #ifdef py_is_pad if (py_is_pad(self->win)) { win = subpad(self->win, nlines, ncols, begin_y, begin_x); + funcname = "subpad"; } else #endif + { win = subwin(self->win, nlines, ncols, begin_y, begin_x); + funcname = "subwin"; + } if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state_by_win(self); - PyErr_SetString(state->error, catchall_NULL); + curses_window_set_null_error(self, funcname, "subwin"); return NULL; } @@ -2521,12 +2675,17 @@ _curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, int lines) /*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/ { + int rtn; + const char *funcname; if (!group_right_1) { - return PyCursesCheckERR_ForWin(self, scroll(self->win), "scroll"); + rtn = scroll(self->win); + funcname = "scroll"; } else { - return PyCursesCheckERR_ForWin(self, wscrl(self->win, lines), "scroll"); + rtn = wscrl(self->win, lines); + funcname = "wscrl"; } + return curses_window_check_err(self, rtn, funcname, "scroll"); } /*[clinic input] @@ -2550,12 +2709,17 @@ _curses_window_touchline_impl(PyCursesWindowObject *self, int start, int count, int group_right_1, int changed) /*[clinic end generated code: output=65d05b3f7438c61d input=a98aa4f79b6be845]*/ { + int rtn; + const char *funcname; if (!group_right_1) { - return PyCursesCheckERR_ForWin(self, touchline(self->win, start, count), "touchline"); + rtn = touchline(self->win, start, count); + funcname = "touchline"; } else { - return PyCursesCheckERR_ForWin(self, wtouchln(self->win, start, count, changed), "touchline"); + rtn = wtouchln(self->win, start, count, changed); + funcname = "wtouchln"; } + return curses_window_check_err(self, rtn, funcname, "touchline"); } /*[clinic input] @@ -2593,10 +2757,13 @@ _curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; if (group_left_1) { - if (wmove(self->win, y, x) == ERR) - return PyCursesCheckERR_ForWin(self, ERR, "wmove"); + if (wmove(self->win, y, x) == ERR) { + curses_window_set_error(self, "wmove", "vline"); + return NULL; + } } - return PyCursesCheckERR_ForWin(self, wvline(self->win, ch_ | (attr_t)attr, n), "vline"); + int rtn = wvline(self->win, ch_ | (attr_t)attr, n); + return curses_window_check_err(self, rtn, "wvline", "vline"); } static PyObject * @@ -2761,26 +2928,39 @@ static PyType_Spec PyCursesWindow_Type_spec = { /* -------------------------------------------------------*/ -/* Function Body Macros - They are ugly but very, very useful. ;-) - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing - */ +/* + * Macros for implementing simple module's methods. + * + * Parameters + * + * X The name of the curses C function or macro to invoke. + * FLAG When false, prefixes the function name with 'no' at runtime, + * This parameter is present in the signature and auto-generated + * by Argument Clinic. + * + * These macros should only be used for generating the body of + * the module's methods since they need a module reference. + */ #define NoArgNoReturnFunctionBody(X) \ { \ PyCursesStatefulInitialised(module); \ - return PyCursesCheckERR(module, X(), # X); } - -#define NoArgOrFlagNoReturnFunctionBody(X, flag) \ -{ \ - PyCursesStatefulInitialised(module); \ - if (flag) \ - return PyCursesCheckERR(module, X(), # X); \ - else \ - return PyCursesCheckERR(module, no ## X(), # X); \ + return curses_check_err(module, X(), # X, NULL); } + +#define NoArgOrFlagNoReturnFunctionBody(X, FLAG) \ +{ \ + PyCursesStatefulInitialised(module); \ + int rtn; \ + const char *funcname; \ + if (FLAG) { \ + rtn = X(); \ + funcname = # X; \ + } \ + else { \ + rtn = no ## X(); \ + funcname = "no" # X; \ + } \ + return curses_check_err(module, rtn, funcname, # X); \ } #define NoArgReturnIntFunctionBody(X) \ @@ -2788,7 +2968,6 @@ static PyType_Spec PyCursesWindow_Type_spec = { PyCursesStatefulInitialised(module); \ return PyLong_FromLong((long) X()); } - #define NoArgReturnStringFunctionBody(X) \ { \ PyCursesStatefulInitialised(module); \ @@ -2903,9 +3082,8 @@ _curses_color_content_impl(PyObject *module, int color_number) PyCursesStatefulInitialisedColor(module); if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) == ERR) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_Format(state->error, "%s() returned ERR", - Py_STRINGIFY(_COLOR_CONTENT_FUNC)); + const char *funcname = Py_STRINGIFY(_COLOR_CONTENT_FUNC); + curses_set_error(module, funcname, "color_content"); return NULL; } @@ -2959,7 +3137,10 @@ _curses_curs_set_impl(PyObject *module, int visibility) PyCursesStatefulInitialised(module); erg = curs_set(visibility); - if (erg == ERR) return PyCursesCheckERR(module, erg, "curs_set"); + if (erg == ERR) { + curses_set_error(module, "curs_set", NULL); + return NULL; + } return PyLong_FromLong((long) erg); } @@ -3010,7 +3191,7 @@ _curses_delay_output_impl(PyObject *module, int ms) { PyCursesStatefulInitialised(module); - return PyCursesCheckERR(module, delay_output(ms), "delay_output"); + return curses_check_err(module, delay_output(ms), "delay_output", NULL); } /*[clinic input] @@ -3143,8 +3324,7 @@ _curses_getmouse_impl(PyObject *module) rtn = getmouse( &event ); if (rtn == ERR) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, "getmouse() returned ERR"); + curses_set_error(module, "getmouse", NULL); return NULL; } return Py_BuildValue("(hiiik)", @@ -3182,7 +3362,7 @@ _curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, event.y = y; event.z = z; event.bstate = bstate; - return PyCursesCheckERR(module, ungetmouse(&event), "ungetmouse"); + return curses_check_err(module, ungetmouse(&event), "ungetmouse", NULL); } #endif @@ -3238,8 +3418,7 @@ _curses_getwin(PyObject *module, PyObject *file) fseek(fp, 0, 0); win = getwin(fp); if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, catchall_NULL); + curses_set_null_error(module, "getwin", NULL); goto error; } cursesmodule_state *state = get_cursesmodule_state(module); @@ -3268,7 +3447,7 @@ _curses_halfdelay_impl(PyObject *module, unsigned char tenths) { PyCursesStatefulInitialised(module); - return PyCursesCheckERR(module, halfdelay(tenths), "halfdelay"); + return curses_check_err(module, halfdelay(tenths), "halfdelay", NULL); } /*[clinic input] @@ -3353,9 +3532,10 @@ _curses_init_color_impl(PyObject *module, int color_number, short r, short g, PyCursesStatefulInitialised(module); PyCursesStatefulInitialisedColor(module); - return PyCursesCheckERR(module, + return curses_check_err(module, _CURSES_INIT_COLOR_FUNC(color_number, r, g, b), - Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC)); + Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC), + NULL); } /*[clinic input] @@ -3389,9 +3569,8 @@ _curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg) COLOR_PAIRS - 1); } else { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_Format(state->error, "%s() returned ERR", - Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC)); + const char *funcname = Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC); + curses_set_error(module, funcname, "init_pair"); } return NULL; } @@ -3422,8 +3601,7 @@ _curses_initscr_impl(PyObject *module) win = initscr(); if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, catchall_NULL); + curses_set_null_error(module, "initscr", NULL); return NULL; } @@ -3628,7 +3806,7 @@ _curses_set_escdelay_impl(PyObject *module, int ms) return NULL; } - return PyCursesCheckERR(module, set_escdelay(ms), "set_escdelay"); + return curses_check_err(module, set_escdelay(ms), "set_escdelay", NULL); } /*[clinic input] @@ -3667,7 +3845,7 @@ _curses_set_tabsize_impl(PyObject *module, int size) return NULL; } - return PyCursesCheckERR(module, set_tabsize(size), "set_tabsize"); + return curses_check_err(module, set_tabsize(size), "set_tabsize", NULL); } #endif @@ -3685,7 +3863,7 @@ _curses_intrflush_impl(PyObject *module, int flag) { PyCursesStatefulInitialised(module); - return PyCursesCheckERR(module, intrflush(NULL, flag), "intrflush"); + return curses_check_err(module, intrflush(NULL, flag), "intrflush", NULL); } /*[clinic input] @@ -3798,7 +3976,7 @@ _curses_meta_impl(PyObject *module, int yes) { PyCursesStatefulInitialised(module); - return PyCursesCheckERR(module, meta(stdscr, yes), "meta"); + return curses_check_err(module, meta(stdscr, yes), "meta", NULL); } #ifdef NCURSES_MOUSE_VERSION @@ -3821,8 +3999,12 @@ _curses_mouseinterval_impl(PyObject *module, int interval) /*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/ { PyCursesStatefulInitialised(module); - - return PyCursesCheckERR(module, mouseinterval(interval), "mouseinterval"); + int value = mouseinterval(interval); + if (value == ERR) { + curses_set_error(module, "mouseinterval", NULL); + return NULL; + } + return PyLong_FromLong(value); } /*[clinic input] @@ -3898,8 +4080,7 @@ _curses_newpad_impl(PyObject *module, int nlines, int ncols) win = newpad(nlines, ncols); if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, catchall_NULL); + curses_set_null_error(module, "newpad", NULL); return NULL; } @@ -3939,8 +4120,7 @@ _curses_newwin_impl(PyObject *module, int nlines, int ncols, win = newwin(nlines,ncols,begin_y,begin_x); if (win == NULL) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, catchall_NULL); + curses_set_null_error(module, "newwin", NULL); return NULL; } @@ -4059,9 +4239,8 @@ _curses_pair_content_impl(PyObject *module, int pair_number) COLOR_PAIRS - 1); } else { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_Format(state->error, "%s() returned ERR", - Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC)); + const char *funcname = Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC); + curses_set_error(module, funcname, "pair_content"); } return NULL; } @@ -4105,7 +4284,7 @@ static PyObject * _curses_putp_impl(PyObject *module, const char *string) /*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/ { - return PyCursesCheckERR(module, putp(string), "putp"); + return curses_check_err(module, putp(string), "putp", NULL); } /*[clinic input] @@ -4279,10 +4458,12 @@ _curses_resizeterm_impl(PyObject *module, short nlines, short ncols) /*[clinic end generated code: output=4de3abab50c67f02 input=414e92a63e3e9899]*/ { PyObject *result; + int code; PyCursesStatefulInitialised(module); - result = PyCursesCheckERR(module, resizeterm(nlines, ncols), "resizeterm"); + code = resizeterm(nlines, ncols); + result = curses_check_err(module, code, "resizeterm", NULL); if (!result) return NULL; if (!update_lines_cols(module)) { @@ -4318,10 +4499,12 @@ _curses_resize_term_impl(PyObject *module, short nlines, short ncols) /*[clinic end generated code: output=46c6d749fa291dbd input=276afa43d8ea7091]*/ { PyObject *result; + int code; PyCursesStatefulInitialised(module); - result = PyCursesCheckERR(module, resize_term(nlines, ncols), "resize_term"); + code = resize_term(nlines, ncols); + result = curses_check_err(module, code, "resize_term", NULL); if (!result) return NULL; if (!update_lines_cols(module)) { @@ -4390,8 +4573,7 @@ _curses_start_color_impl(PyObject *module) PyCursesStatefulInitialised(module); if (start_color() == ERR) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, "start_color() returned ERR"); + curses_set_error(module, "start_color", NULL); return NULL; } @@ -4543,8 +4725,7 @@ _curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9); if (!result) { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, "tparm() returned NULL"); + curses_set_null_error(module, "tparm", NULL); return NULL; } @@ -4570,7 +4751,7 @@ _curses_typeahead_impl(PyObject *module, int fd) { PyCursesStatefulInitialised(module); - return PyCursesCheckERR(module, typeahead( fd ), "typeahead"); + return curses_check_err(module, typeahead(fd), "typeahead", NULL); } #endif @@ -4620,7 +4801,7 @@ _curses_ungetch(PyObject *module, PyObject *ch) if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) return NULL; - return PyCursesCheckERR(module, ungetch(ch_), "ungetch"); + return curses_check_err(module, ungetch(ch_), "ungetch", NULL); } #ifdef HAVE_NCURSESW @@ -4690,7 +4871,7 @@ _curses_unget_wch(PyObject *module, PyObject *ch) if (!PyCurses_ConvertToWchar_t(ch, &wch)) return NULL; - return PyCursesCheckERR(module, unget_wch(wch), "unget_wch"); + return curses_check_err(module, unget_wch(wch), "unget_wch", NULL); } #endif @@ -4739,13 +4920,7 @@ _curses_use_default_colors_impl(PyObject *module) PyCursesStatefulInitialisedColor(module); code = use_default_colors(); - if (code != ERR) { - Py_RETURN_NONE; - } else { - cursesmodule_state *state = get_cursesmodule_state(module); - PyErr_SetString(state->error, "use_default_colors() returned ERR"); - return NULL; - } + return curses_check_err(module, code, "use_default_colors", NULL); } /*[clinic input] |