]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/input.c
Imported Upstream version 1.5~pre1
[ap-utils.git] / lib / input.c
index 2e918ee83cf33b8324a0d0c64b6eabe079bcc89f..b77dd835bbaf5e85688c48c10c8fc9c01f1862d9 100644 (file)
 
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
 #include <unistd.h>
 #include <menu.h>
+#include <errno.h>
 #include "ap-utils.h"
-#include "ap-curses.h"
 
-extern WINDOW *main_sub, *win_for_help, *main_win;
+extern WINDOW *main_sub, *win_for_help;
 
 #define GEN_IV_MSG _("Invalid value. Press any key to continue.")
-#define OOR_IV_MSG _("Value must be in range %i - %i. Press any key to continue.")
+#define OOR_IV_MSG _("Value must be in range %u - %u. Press any key to continue.")
 
 #define MAC_LEN 12
 #define MAC_BYTES 6
@@ -103,14 +105,15 @@ get_mask_again:
  * value ....... this should keep the value, entered by the user,
  *              in ascii string notation
  * row
- * col ......... the begin coordinate, relative to the current window,
+ * col ......... the begin coordinates, relative to the current window,
  *              at which the string entered by the user will appear
  * len ......... maximum length of the entered string, including the
- *              tailing '\0' character
+ *              tailing '\0' character. Negative value along with
+ *              vt=ANY_STRING means that zero-length string is allowed.
  * vt .......... desired input value type (types INT_STRING, HEX_STRING,
  *              ANY_STRING)
  * minv, maxv .. min/max bounds in case of integer value input. Each can be
- *              of value 0 - maxint. If both are 0, it means no value bounds
+ *              of value 0-0xFFFFFFFF. If both are 0, it means no value bounds
  *              checking will be performed. Used only with vt=INT_STRING.
  * helpmsg ..... pointer to string that will be printed after OOR_IV_MSG
  *              message if the entered integer value is out of range.
@@ -120,17 +123,22 @@ get_mask_again:
  */
 void
 get_value(char *value, int row, int col, int len,
-         char vt, int minv, int maxv, char *helpmsg)
+         char vt, unsigned int minv, unsigned int maxv, char *helpmsg)
 {
-    int i;
+    unsigned int i;
     unsigned char c, acs;
-    char iv_msg[128];
+    char iv_msg[128], zerolen_perm = 0;
+
+    if (vt == ANY_STRING && len < 0) {
+       zerolen_perm = 1;
+       len = -len;
+    }
 
     echo();
     wattrset(main_sub, COLOR_PAIR(2));
 get_value_again:
     wmove(main_sub, row, col);
-    for (i = 0; i < len - 1; i++)
+    for (i = 0; i < (unsigned int)len - 1; i++)
        waddch(main_sub, ' ');
     curs_set(1);
     wmove(main_sub, row, col);
@@ -164,13 +172,13 @@ get_value_again:
            continue;
        } else if (c == 0x0D) {
            /* ENTER KEY */
-           if (i > 0)
+           if (i > 0 || zerolen_perm)
                break;
            continue;
        } else if (c == 0x1B) {
            /* ESCAPE KEY */
            continue;
-       } else if (acs && (i < len - 1)) {
+       } else if (acs && (i < (unsigned int)len - 1)) {
            value[i++] = c;
            wechochar(main_sub, c);
        }
@@ -179,8 +187,9 @@ get_value_again:
 
     noecho();
     if (vt == INT_STRING && (minv | maxv)) {
-       i = atoi(value);
-       if (i < minv || i > maxv) {
+       errno = 0;
+       i = strtoul(value, (char **)NULL, 10);
+       if (i < minv || i > maxv || errno == ERANGE) {
            if (helpmsg) {
                snprintf(iv_msg, sizeof(iv_msg) - 1, OOR_IV_MSG, minv, maxv);
                print_helperr(iv_msg);
@@ -194,7 +203,7 @@ get_value_again:
     curs_set(0);
     wattrset(main_sub, A_BOLD);
     wmove(main_sub, row, col);
-    for (i = 0; i < len - 1; i++)
+    for (i = 0; i < (unsigned int)len - 1; i++)
        waddch(main_sub, ' ');
     mvwaddstr(main_sub, row, col, value);
     wattrset(main_sub, A_NORMAL);
@@ -353,3 +362,59 @@ int menu_choose(int brow, int bcol, char **names, unsigned int num)
     }
 }
 
+/*
+ * Reads key by either getch() (WAIT_FOREVER mode) or select()
+ * (WAIT_TIMEOUT mode). Returns -1 upon error, 0 for timeout, or
+ * pressed key code.
+ */
+int wait_key()
+{
+    int i = 0;
+    fd_set rds;
+    struct timeval timeout;
+    extern int wait_mode;
+
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    FD_ZERO(&rds);
+    FD_SET(0, &rds);
+
+    if (wait_mode == WAIT_TIMEOUT) {
+       /*
+        * wait up to timeout until anything is avail. for reading
+        * on stdin
+        */
+       i = select(1, &rds, NULL, NULL, &timeout);
+
+       /* not timed out => anything avail. for reading in rds */
+       if (i > 0)
+           i = getc(stdin);
+
+       /* error occured */
+       if (i == -1) {
+           print_helperr(SELECT);
+           getch();
+       }
+
+       /* also happens: i = 0 => timeout => release */
+
+    } else { /* wait_mode = WAIT_FOREVER */
+       i = getch();
+    }
+
+    return i;
+}
+
+int help_ysn()
+{
+    char c;
+
+    print_help (_("Y - Yes; Any other key - No (it's safer to answer No)"));
+    c = getch();
+    clear_main(0);
+    if (c == 'y' || c == 'Y')
+       return 0;
+
+    return 1;
+}
+