Change-Id: Iffed3602456f5306711c65f06c873c58d4086e11 Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: http://review.coreboot.org/363 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
		
			
				
	
	
		
			472 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			472 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Public Domain Curses */
 | 
						|
 | 
						|
#include <curspriv.h>
 | 
						|
 | 
						|
RCSID("$Id: getstr.c,v 1.51 2008/07/14 04:24:51 wmcbrine Exp $")
 | 
						|
 | 
						|
/*man-start**************************************************************
 | 
						|
 | 
						|
  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 n);
 | 
						|
        int wgetnstr(WINDOW *win, char *str, int n);
 | 
						|
        int mvgetnstr(int y, int x, char *str, int n);
 | 
						|
        int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n);
 | 
						|
 | 
						|
        int get_wstr(wint_t *wstr);
 | 
						|
        int wget_wstr(WINDOW *win, wint_t *wstr);
 | 
						|
        int mvget_wstr(int y, int x, wint_t *wstr);
 | 
						|
        int mvwget_wstr(WINDOW *win, int, int, wint_t *wstr);
 | 
						|
        int getn_wstr(wint_t *wstr, int n);
 | 
						|
        int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
 | 
						|
        int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
 | 
						|
        int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
 | 
						|
 | 
						|
  Description:
 | 
						|
        These routines call wgetch() repeatedly to build a string,
 | 
						|
        interpreting erase and kill characters along the way, until a
 | 
						|
        newline or carriage return is received. When PDCurses is built
 | 
						|
        with wide-character support enabled, the narrow-character
 | 
						|
        functions convert the wgetch()'d values into a multibyte string
 | 
						|
        in the current locale before returning it. The resulting string
 | 
						|
        is placed in the area pointed to by *str. The routines with n as
 | 
						|
        the last argument read at most n characters.
 | 
						|
 | 
						|
        Note that there's no way to know how long the buffer passed to
 | 
						|
        wgetstr() is, so use wgetnstr() to avoid buffer overflows.
 | 
						|
 | 
						|
  Return Value:
 | 
						|
        This functions return ERR on failure or any other value on
 | 
						|
        success.
 | 
						|
 | 
						|
  Portability                                X/Open    BSD    SYS V
 | 
						|
        getstr                                  Y       Y       Y
 | 
						|
        wgetstr                                 Y       Y       Y
 | 
						|
        mvgetstr                                Y       Y       Y
 | 
						|
        mvwgetstr                               Y       Y       Y
 | 
						|
        getnstr                                 Y       -      4.0
 | 
						|
        wgetnstr                                Y       -      4.0
 | 
						|
        mvgetnstr                               Y       -       -
 | 
						|
        mvwgetnstr                              Y       -       -
 | 
						|
        get_wstr                                Y
 | 
						|
        wget_wstr                               Y
 | 
						|
        mvget_wstr                              Y
 | 
						|
        mvwget_wstr                             Y
 | 
						|
        getn_wstr                               Y
 | 
						|
        wgetn_wstr                              Y
 | 
						|
        mvgetn_wstr                             Y
 | 
						|
        mvwgetn_wstr                            Y
 | 
						|
 | 
						|
**man-end****************************************************************/
 | 
						|
 | 
						|
#define MAXLINE 255
 | 
						|
 | 
						|
int wgetnstr(WINDOW *win, char *str, int n)
 | 
						|
{
 | 
						|
#ifdef PDC_WIDE
 | 
						|
    wchar_t wstr[MAXLINE + 1];
 | 
						|
 | 
						|
    if (n < 0 || n > MAXLINE)
 | 
						|
        n = MAXLINE;
 | 
						|
 | 
						|
    if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return PDC_wcstombs(str, wstr, n);
 | 
						|
#else
 | 
						|
    int ch, i, num, x, chars;
 | 
						|
    char *p;
 | 
						|
    bool stop, oldecho, oldcbreak, oldnodelay;
 | 
						|
 | 
						|
    PDC_LOG(("wgetnstr() - called\n"));
 | 
						|
 | 
						|
    if (!win || !str)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    chars = 0;
 | 
						|
    p = str;
 | 
						|
    stop = FALSE;
 | 
						|
 | 
						|
    x = win->_curx;
 | 
						|
 | 
						|
    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 */
 | 
						|
 | 
						|
    wrefresh(win);
 | 
						|
 | 
						|
    while (!stop)
 | 
						|
    {
 | 
						|
        ch = wgetch(win);
 | 
						|
 | 
						|
        switch (ch)
 | 
						|
        {
 | 
						|
 | 
						|
        case '\t':
 | 
						|
            ch = ' ';
 | 
						|
            num = TABSIZE - (win->_curx - x) % TABSIZE;
 | 
						|
            for (i = 0; i < num; i++)
 | 
						|
            {
 | 
						|
                if (chars < n)
 | 
						|
                {
 | 
						|
                    if (oldecho)
 | 
						|
                        waddch(win, ch);
 | 
						|
                    *p++ = ch;
 | 
						|
                    ++chars;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                    beep();
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
        case _ECHAR:        /* CTRL-H -- Delete character */
 | 
						|
            if (p > str)
 | 
						|
            {
 | 
						|
                if (oldecho)
 | 
						|
                    waddstr(win, "\b \b");
 | 
						|
                ch = (unsigned char)(*--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 = (unsigned char)(*--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 = (unsigned char)(*--p);
 | 
						|
                if ((ch < ' ') && (oldecho))
 | 
						|
                    waddstr(win, "\b \b");
 | 
						|
                chars--;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
        case '\n':
 | 
						|
        case '\r':
 | 
						|
            stop = TRUE;
 | 
						|
            if (oldecho)
 | 
						|
                waddch(win, '\n');
 | 
						|
            break;
 | 
						|
 | 
						|
        default:
 | 
						|
            if (chars < n)
 | 
						|
            {
 | 
						|
                if (!SP->key_code && ch < 0x100)
 | 
						|
                {
 | 
						|
                    *p++ = ch;
 | 
						|
                    if (oldecho)
 | 
						|
                        waddch(win, ch);
 | 
						|
                    chars++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
                beep();
 | 
						|
 | 
						|
            break;
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        wrefresh(win);
 | 
						|
    }
 | 
						|
 | 
						|
    *p = '\0';
 | 
						|
 | 
						|
    SP->echo = oldecho;     /* restore old settings */
 | 
						|
    SP->cbreak = oldcbreak;
 | 
						|
    win->_nodelay = oldnodelay;
 | 
						|
 | 
						|
    return OK;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
int getstr(char *str)
 | 
						|
{
 | 
						|
    PDC_LOG(("getstr() - called\n"));
 | 
						|
 | 
						|
    return wgetnstr(stdscr, str, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int wgetstr(WINDOW *win, char *str)
 | 
						|
{
 | 
						|
    PDC_LOG(("wgetstr() - called\n"));
 | 
						|
 | 
						|
    return wgetnstr(win, str, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int mvgetstr(int y, int x, char *str)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvgetstr() - called\n"));
 | 
						|
 | 
						|
    if (move(y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetnstr(stdscr, str, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int mvwgetstr(WINDOW *win, int y, int x, char *str)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvwgetstr() - called\n"));
 | 
						|
 | 
						|
    if (wmove(win, y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetnstr(win, str, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int getnstr(char *str, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("getnstr() - called\n"));
 | 
						|
 | 
						|
    return wgetnstr(stdscr, str, n);
 | 
						|
}
 | 
						|
 | 
						|
int mvgetnstr(int y, int x, char *str, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvgetnstr() - called\n"));
 | 
						|
 | 
						|
    if (move(y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetnstr(stdscr, str, n);
 | 
						|
}
 | 
						|
 | 
						|
int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvwgetnstr() - called\n"));
 | 
						|
 | 
						|
    if (wmove(win, y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetnstr(win, str, n);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef PDC_WIDE
 | 
						|
int wgetn_wstr(WINDOW *win, wint_t *wstr, int n)
 | 
						|
{
 | 
						|
    int ch, i, num, x, chars;
 | 
						|
    wint_t *p;
 | 
						|
    bool stop, oldecho, oldcbreak, oldnodelay;
 | 
						|
 | 
						|
    PDC_LOG(("wgetn_wstr() - called\n"));
 | 
						|
 | 
						|
    if (!win || !wstr)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    chars = 0;
 | 
						|
    p = wstr;
 | 
						|
    stop = FALSE;
 | 
						|
 | 
						|
    x = win->_curx;
 | 
						|
 | 
						|
    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 */
 | 
						|
 | 
						|
    wrefresh(win);
 | 
						|
 | 
						|
    while (!stop)
 | 
						|
    {
 | 
						|
        ch = wgetch(win);
 | 
						|
 | 
						|
        switch (ch)
 | 
						|
        {
 | 
						|
 | 
						|
        case '\t':
 | 
						|
            ch = ' ';
 | 
						|
            num = TABSIZE - (win->_curx - x) % TABSIZE;
 | 
						|
            for (i = 0; i < num; i++)
 | 
						|
            {
 | 
						|
                if (chars < n)
 | 
						|
                {
 | 
						|
                    if (oldecho)
 | 
						|
                        waddch(win, ch);
 | 
						|
                    *p++ = ch;
 | 
						|
                    ++chars;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                    beep();
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
        case _ECHAR:        /* CTRL-H -- Delete character */
 | 
						|
            if (p > wstr)
 | 
						|
            {
 | 
						|
                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 > wstr)
 | 
						|
            {
 | 
						|
                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 > wstr) && (*(p - 1) == ' '))
 | 
						|
            {
 | 
						|
                if (oldecho)
 | 
						|
                    waddstr(win, "\b \b");
 | 
						|
 | 
						|
                --p;        /* remove space */
 | 
						|
                chars--;
 | 
						|
            }
 | 
						|
            while ((p > wstr) && (*(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;
 | 
						|
 | 
						|
        default:
 | 
						|
            if (chars < n)
 | 
						|
            {
 | 
						|
                if (!SP->key_code)
 | 
						|
                {
 | 
						|
                    *p++ = ch;
 | 
						|
                    if (oldecho)
 | 
						|
                        waddch(win, ch);
 | 
						|
                    chars++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
                beep();
 | 
						|
 | 
						|
            break;
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        wrefresh(win);
 | 
						|
    }
 | 
						|
 | 
						|
    *p = '\0';
 | 
						|
 | 
						|
    SP->echo = oldecho;     /* restore old settings */
 | 
						|
    SP->cbreak = oldcbreak;
 | 
						|
    win->_nodelay = oldnodelay;
 | 
						|
 | 
						|
    return OK;
 | 
						|
}
 | 
						|
 | 
						|
int get_wstr(wint_t *wstr)
 | 
						|
{
 | 
						|
    PDC_LOG(("get_wstr() - called\n"));
 | 
						|
 | 
						|
    return wgetn_wstr(stdscr, wstr, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int wget_wstr(WINDOW *win, wint_t *wstr)
 | 
						|
{
 | 
						|
    PDC_LOG(("wget_wstr() - called\n"));
 | 
						|
 | 
						|
    return wgetn_wstr(win, wstr, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int mvget_wstr(int y, int x, wint_t *wstr)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvget_wstr() - called\n"));
 | 
						|
 | 
						|
    if (move(y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetn_wstr(stdscr, wstr, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvwget_wstr() - called\n"));
 | 
						|
 | 
						|
    if (wmove(win, y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetn_wstr(win, wstr, MAXLINE);
 | 
						|
}
 | 
						|
 | 
						|
int getn_wstr(wint_t *wstr, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("getn_wstr() - called\n"));
 | 
						|
 | 
						|
    return wgetn_wstr(stdscr, wstr, n);
 | 
						|
}
 | 
						|
 | 
						|
int mvgetn_wstr(int y, int x, wint_t *wstr, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvgetn_wstr() - called\n"));
 | 
						|
 | 
						|
    if (move(y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetn_wstr(stdscr, wstr, n);
 | 
						|
}
 | 
						|
 | 
						|
int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n)
 | 
						|
{
 | 
						|
    PDC_LOG(("mvwgetn_wstr() - called\n"));
 | 
						|
 | 
						|
    if (wmove(win, y, x) == ERR)
 | 
						|
        return ERR;
 | 
						|
 | 
						|
    return wgetn_wstr(win, wstr, n);
 | 
						|
}
 | 
						|
#endif
 |