pdcurses/getstr.c

changeset 97
2d43f05b284c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pdcurses/getstr.c	Thu Jul 23 18:07:39 2015 +0300
@@ -0,0 +1,471 @@
+/* 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

mercurial