Entering TAB in wgetnstr() no longer exceeds requested buffer size.

This commit is contained in:
Mark Hessling
2002-05-11 09:53:37 +00:00
parent 9efe8a0c20
commit 801bd98bbd

View File

@@ -17,33 +17,33 @@
* See the file maintain.er for details of the current maintainer.
***************************************************************************
*/
#define CURSES_LIBRARY 1
#define CURSES_LIBRARY 1
#ifdef HAVE_CONFIG_H
# include <config.h>
# include <config.h>
#endif
#include <curses.h>
/* undefine any macros for functions defined in this module */
#undef getstr
#undef wgetstr
#undef mvgetstr
#undef mvwgetstr
#undef ungetstr
#undef getnstr
#undef wgetnstr
#undef getstr
#undef wgetstr
#undef mvgetstr
#undef mvwgetstr
#undef ungetstr
#undef getnstr
#undef wgetnstr
/* undefine any macros for functions called by this module if in debug mode */
#ifdef PDCDEBUG
# undef wrefresh
# undef waddch
# undef wgetch
# undef cbreak
# undef move
# undef wmove
# undef wrefresh
# undef waddch
# undef wgetch
# undef cbreak
# undef move
# undef wmove
#endif
#ifdef PDCDEBUG
char *rcsid_getstr = "$Id: getstr.c,v 1.3 2002/05/11 08:53:19 mark Exp $";
char *rcsid_getstr = "$Id: getstr.c,v 1.4 2002/05/11 09:53:37 mark Exp $";
#endif
/*man-start*********************************************************************
@@ -51,40 +51,40 @@ char *rcsid_getstr = "$Id: getstr.c,v 1.3 2002/05/11 08:53:19 mark Exp $";
Name: getstr
Synopsis:
int getstr(char *str);
int wgetstr(WINDOW *win, char *str);
int mvgetstr(int y, int x, char *str);
int mvwgetstr(WINDOW *win, int y, int x, char *str);
int getnstr(char *str, int ch);
int wgetnstr(WINDOW *win, char *str, int ch);
int getstr(char *str);
int wgetstr(WINDOW *win, char *str);
int mvgetstr(int y, int x, char *str);
int mvwgetstr(WINDOW *win, int y, int x, char *str);
int getnstr(char *str, int ch);
int wgetnstr(WINDOW *win, char *str, int ch);
X/Open Description:
The effect of getstr() is as though a series of calls to getch()
were made, until a newline or carriage return is received. The
resulting value is placed in the area pointed to by *str. The user's
erase and kill characters are interpreted, as well as any special
keys; such as function keys.
The effect of getstr() is as though a series of calls to getch()
were made, until a newline or carriage return is received. The
resulting value is placed in the area pointed to by *str. The user's
erase and kill characters are interpreted, as well as any special
keys; such as function keys.
With wgetnstr(), a series of characters are read until a newline
or carriage return is received. The resulting value is placed
in the area pointed to by the character pointer str. The user's
erase and kill characters are interpreted. This differs from
wgetstr() in that the number of characters read is limited by a passed
argument.
With wgetnstr(), a series of characters are read until a newline
or carriage return is received. The resulting value is placed
in the area pointed to by the character pointer str. The user's
erase and kill characters are interpreted. This differs from
wgetstr() in that the number of characters read is limited by a passed
argument.
NOTE: getstr(), getnstr(), mvgetstr() and mvwgetstr() are
implemented as macros.
NOTE: getstr(), getnstr(), mvgetstr() and mvwgetstr() are
implemented as macros.
WARNING: There is no way to know how long the buffer passed to
wgetstr() is, so it is possible to overwrite wrong
memory or code!! This is the reason for the wgetnstr()
function :-)
WARNING: There is no way to know how long the buffer passed to
wgetstr() is, so it is possible to overwrite wrong
memory or code!! This is the reason for the wgetnstr()
function :-)
X/Open Return Value:
This functions return ERR on failure or any other value on success.
This functions return ERR on failure or any other value on success.
X/Open Errors:
No errors are defined for this function.
No errors are defined for this function.
Portability X/Open BSD SYS V
Dec '88
@@ -101,45 +101,45 @@ char *rcsid_getstr = "$Id: getstr.c,v 1.3 2002/05/11 08:53:19 mark Exp $";
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL getstr(char *str)
int PDC_CDECL getstr(char *str)
#else
int PDC_CDECL getstr(str)
int PDC_CDECL getstr(str)
char *str;
#endif
/***********************************************************************/
{
#ifdef PDCDEBUG
if (trace_on) PDC_debug("getstr() - called\n");
if (trace_on) PDC_debug("getstr() - called\n");
#endif
if (stdscr == (WINDOW *)NULL)
return (ERR);
return(wgetnstr(stdscr,str,MAXLINE));
if (stdscr == (WINDOW *)NULL)
return (ERR);
return(wgetnstr(stdscr,str,MAXLINE));
}
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL wgetstr(WINDOW *win, char *str)
int PDC_CDECL wgetstr(WINDOW *win, char *str)
#else
int PDC_CDECL wgetstr(win,str)
int PDC_CDECL wgetstr(win,str)
WINDOW *win;
char *str;
#endif
/***********************************************************************/
{
#ifdef PDCDEBUG
if (trace_on) PDC_debug("wgetstr() - called\n");
if (trace_on) PDC_debug("wgetstr() - called\n");
#endif
if (win == (WINDOW *)NULL)
return (ERR);
if (win == (WINDOW *)NULL)
return (ERR);
return(wgetnstr(win,str,MAXLINE));
return(wgetnstr(win,str,MAXLINE));
}
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL mvgetstr(int y, int x, char *str)
int PDC_CDECL mvgetstr(int y, int x, char *str)
#else
int PDC_CDECL mvgetstr(y,x,str)
int PDC_CDECL mvgetstr(y,x,str)
int y;
int x;
char *str;
@@ -147,20 +147,20 @@ char *str;
/***********************************************************************/
{
#ifdef PDCDEBUG
if (trace_on) PDC_debug("mvgetstr() - called\n");
if (trace_on) PDC_debug("mvgetstr() - called\n");
#endif
if (stdscr == (WINDOW *)NULL)
return (ERR);
if (move(y,x) == ERR)
return (ERR);
return(wgetnstr(stdscr,str,MAXLINE));
if (stdscr == (WINDOW *)NULL)
return (ERR);
if (move(y,x) == ERR)
return (ERR);
return(wgetnstr(stdscr,str,MAXLINE));
}
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL mvwgetstr(WINDOW *win, int y, int x, char *str)
int PDC_CDECL mvwgetstr(WINDOW *win, int y, int x, char *str)
#else
int PDC_CDECL mvwgetstr(win,y,x,str)
int PDC_CDECL mvwgetstr(win,y,x,str)
WINDOW *win;
int y;
int x;
@@ -169,181 +169,183 @@ char *str;
/***********************************************************************/
{
#ifdef PDCDEBUG
if (trace_on) PDC_debug("mvwgetstr() - called\n");
if (trace_on) PDC_debug("mvwgetstr() - called\n");
#endif
if (win == (WINDOW *)NULL)
return (ERR);
if (wmove(win,y,x) == ERR)
return (ERR);
return(wgetnstr(win,str,MAXLINE));
if (win == (WINDOW *)NULL)
return (ERR);
if (wmove(win,y,x) == ERR)
return (ERR);
return(wgetnstr(win,str,MAXLINE));
}
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL getnstr(char *str, int n)
int PDC_CDECL getnstr(char *str, int n)
#else
int PDC_CDECL getnstr(str,n)
int PDC_CDECL getnstr(str,n)
char *str;
int n;
#endif
/***********************************************************************/
{
#ifdef PDCDEBUG
if (trace_on) PDC_debug("getnstr() - called\n");
if (trace_on) PDC_debug("getnstr() - called\n");
#endif
if (stdscr == (WINDOW *)NULL)
return (ERR);
return(wgetnstr(stdscr,str,n));
if (stdscr == (WINDOW *)NULL)
return (ERR);
return(wgetnstr(stdscr,str,n));
}
/***********************************************************************/
#ifdef HAVE_PROTO
int PDC_CDECL wgetnstr(WINDOW *win, char *str, int n)
int PDC_CDECL wgetnstr(WINDOW *win, char *str, int n)
#else
int PDC_CDECL wgetnstr(win,str,n)
int PDC_CDECL wgetnstr(win,str,n)
WINDOW *win;
char *str;
int n;
#endif
/***********************************************************************/
{
int ch, i, num,chars=0;
int t = win->_tabsize;
int x = win->_curx;
char* p = str;
bool stop = FALSE;
bool oldecho;
bool oldcbreak;
bool oldnodelay;
int ch, i, num,chars=0;
int t = win->_tabsize;
int x = win->_curx;
char* p = str;
bool stop = FALSE;
bool oldecho;
bool oldcbreak;
bool oldnodelay;
#ifdef PDCDEBUG
if (trace_on) PDC_debug("wgetnstr() - called\n");
if (trace_on) PDC_debug("wgetnstr() - called\n");
#endif
if (win == (WINDOW *)NULL)
return (ERR);
if (win == (WINDOW *)NULL)
return (ERR);
#ifdef UNIX
/*
* this code is very dodgy
*
wrefresh(win);
wrefresh(win);
while ((*str = wgetch(win)) != ERR && *str != '\n')
;
if (*str == ERR) {
*str = '\0';
waddstr(win,p);
return ERR;
}
*str = '\0';
waddstr(win,p);
return OK;
while ((*str = wgetch(win)) != ERR && *str != '\n')
;
if (*str == ERR) {
*str = '\0';
waddstr(win,p);
return ERR;
}
*str = '\0';
waddstr(win,p);
return OK;
*/
#else
oldcbreak = SP->cbreak; /* remember states */
oldecho = SP->echo;
oldnodelay = win->_nodelay;
oldcbreak = SP->cbreak; /* remember states */
oldecho = SP->echo;
oldnodelay = win->_nodelay;
SP->echo = FALSE; /* we do echo ourselves */
cbreak(); /* ensure each key is returned immediately */
win->_nodelay = FALSE; /* don't return -1 */
SP->echo = FALSE; /* we do echo ourselves */
cbreak(); /* ensure each key is returned immediately */
win->_nodelay = FALSE; /* don't return -1 */
wrefresh (win);
wrefresh (win);
while (!stop)
{
ch = wgetch (win);
/* ignore modifier keys on their own */
if ( ch == KEY_SHIFT_L
|| ch == KEY_SHIFT_R
|| ch == KEY_CONTROL_L
|| ch == KEY_CONTROL_R
|| ch == KEY_ALT_L
|| ch == KEY_ALT_R )
continue;
ch = ch & A_CHARTEXT;
switch( ch )
{
case '\t':
ch = ' ';
num = t - (win->_curx - x)%t;
for (i=0; i<num; i++)
{
if (oldecho)
waddch (win, ch);
*p++ = ch;
}
chars += num;
break;
while (!stop)
{
ch = wgetch (win);
/* ignore modifier keys on their own */
if ( ch == KEY_SHIFT_L
|| ch == KEY_SHIFT_R
|| ch == KEY_CONTROL_L
|| ch == KEY_CONTROL_R
|| ch == KEY_ALT_L
|| ch == KEY_ALT_R )
continue;
ch = ch & A_CHARTEXT;
switch( ch )
{
case '\t':
ch = ' ';
num = t - (win->_curx - x)%t;
for (i=0; i<num; i++)
{
if (oldecho)
waddch (win, ch);
*p++ = ch;
chars ++;
if ( chars >= n )
break;
}
break;
case _ECHAR: /* CTRL-H */ /* Delete character */
if (p > str)
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
}
chars--;
break;
case _ECHAR: /* CTRL-H */ /* Delete character */
if (p > str)
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
}
chars--;
break;
case _DLCHAR: /* CTRL-U */ /* Delete line */
while (p > str)
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
}
chars = 0;
break;
case _DLCHAR: /* CTRL-U */ /* Delete line */
while (p > str)
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
}
chars = 0;
break;
case _DWCHAR: /* CTRL-W */ /* Delete word */
while ((p > str) && (*(p-1) == ' '))
{
if (oldecho)
waddstr (win, "\b \b");
--p; /* remove space */
chars--;
}
while ((p > str) && (*(p-1) != ' '))
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
chars--;
}
break;
case _DWCHAR: /* CTRL-W */ /* Delete word */
while ((p > str) && (*(p-1) == ' '))
{
if (oldecho)
waddstr (win, "\b \b");
--p; /* remove space */
chars--;
}
while ((p > str) && (*(p-1) != ' '))
{
if (oldecho)
waddstr (win, "\b \b");
ch = *--p;
if ((ch < ' ') && (oldecho))
waddstr (win, "\b \b");
chars--;
}
break;
case '\n':
case '\r':
stop = TRUE;
if (oldecho)
waddch (win, '\n');
break;
case '\n':
case '\r':
stop = TRUE;
if (oldecho)
waddch (win, '\n');
break;
default:
*p++ = ch;
if (oldecho)
waddch (win, ch);
chars ++;
break;
}
wrefresh (win);
if (chars >= n)
break;
}
*p = '\0';
default:
*p++ = ch;
if (oldecho)
waddch (win, ch);
chars ++;
break;
}
wrefresh (win);
if (chars >= n)
break;
}
*p = '\0';
SP->echo = oldecho; /* restore old settings */
SP->cbreak = oldcbreak;
win->_nodelay = oldnodelay;
SP->echo = oldecho; /* restore old settings */
SP->cbreak = oldcbreak;
win->_nodelay = oldnodelay;
return (OK);
return (OK);
#endif
}