vi: move key reading routine out of vi into llbbb
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 25 Oct 2008 23:23:00 +0000 (23:23 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 25 Oct 2008 23:23:00 +0000 (23:23 -0000)
function                                             old     new   delta
read_key                                               -     310    +310
....
static.esccmds                                       170      61    -109
readit                                               286      60    -226
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 9/10 up/down: 349/-367)         Total: -18 bytes

editors/vi.c
include/libbb.h
libbb/Kbuild

index 55154dcd7da18fd9a0cdc520f8e192b2a02a49ac..0e7b729fed24263c85fc9e770421cd2838ee5888 100644 (file)
@@ -57,34 +57,6 @@ enum {
        MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
 };
 
-// "Keycodes" that report an escape sequence.
-// We use something which fits into signed char,
-// yet doesn't represent any valid Unicode characher.
-enum {
-       VI_K_UP       = -1,     // cursor key Up
-       VI_K_DOWN     = -2,     // cursor key Down
-       VI_K_RIGHT    = -3,     // Cursor Key Right
-       VI_K_LEFT     = -4,     // cursor key Left
-       VI_K_HOME     = -5,     // Cursor Key Home
-       VI_K_END      = -6,     // Cursor Key End
-       VI_K_INSERT   = -7,     // Cursor Key Insert
-       VI_K_DELETE   = -8,     // Cursor Key Insert
-       VI_K_PAGEUP   = -9,     // Cursor Key Page Up
-       VI_K_PAGEDOWN = -10,    // Cursor Key Page Down
-       VI_K_FUN1     = -11,    // Function Key F1
-       VI_K_FUN2     = -12,    // Function Key F2
-       VI_K_FUN3     = -13,    // Function Key F3
-       VI_K_FUN4     = -14,    // Function Key F4
-       VI_K_FUN5     = -15,    // Function Key F5
-       VI_K_FUN6     = -16,    // Function Key F6
-       VI_K_FUN7     = -17,    // Function Key F7
-       VI_K_FUN8     = -18,    // Function Key F8
-       VI_K_FUN9     = -19,    // Function Key F9
-       VI_K_FUN10    = -20,    // Function Key F10
-       VI_K_FUN11    = -21,    // Function Key F11
-       VI_K_FUN12    = -22,    // Function Key F12
-};
-
 /* vt102 typical ESC sequence */
 /* terminal standout start/normal ESC sequence */
 static const char SOs[] ALIGN1 = "\033[7m";
@@ -179,6 +151,7 @@ struct globals {
        char erase_char;         // the users erase character
        char last_input_char;    // last char read from user
 
+       smalluint chars_to_parse;
 #if ENABLE_FEATURE_VI_DOT_CMD
        smallint adding2q;       // are we currently adding user input to q
        int lmc_len;             // length of last_modifying_cmd
@@ -193,7 +166,7 @@ struct globals {
 #if ENABLE_FEATURE_VI_SEARCH
        char *last_search_pattern; // last pattern from a '/' or '?' search
 #endif
-       int chars_to_parse;
+
        /* former statics */
 #if ENABLE_FEATURE_VI_YANKMARK
        char *edit_file__cur_line;
@@ -259,9 +232,10 @@ struct globals {
 #define screensize              (G.screensize         )
 #define screenbegin             (G.screenbegin        )
 #define tabstop                 (G.tabstop            )
+#define last_forward_char       (G.last_forward_char  )
 #define erase_char              (G.erase_char         )
 #define last_input_char         (G.last_input_char    )
-#define last_forward_char       (G.last_forward_char  )
+#define chars_to_parse          (G.chars_to_parse     )
 #if ENABLE_FEATURE_VI_READONLY
 #define readonly_mode           (G.readonly_mode      )
 #else
@@ -274,7 +248,6 @@ struct globals {
 #define last_row                (G.last_row           )
 #define my_pid                  (G.my_pid             )
 #define last_search_pattern     (G.last_search_pattern)
-#define chars_to_parse          (G.chars_to_parse     )
 
 #define edit_file__cur_line     (G.edit_file__cur_line)
 #define refresh__old_offset     (G.refresh__old_offset)
@@ -2200,130 +2173,14 @@ static int mysleep(int hund)   // sleep for 'h' 1/100 seconds
 static int readit(void) // read (maybe cursor) key from stdin
 {
        int c;
-       int n;
-
-       // Known escape sequences for cursor and function keys.
-       static const struct esc_cmds {
-               const char seq[4];
-               signed char val;
-       } esccmds[] = {
-               {"OA"  , VI_K_UP      },   // Cursor Key Up
-               {"OB"  , VI_K_DOWN    },   // Cursor Key Down
-               {"OC"  , VI_K_RIGHT   },   // Cursor Key Right
-               {"OD"  , VI_K_LEFT    },   // Cursor Key Left
-               {"OH"  , VI_K_HOME    },   // Cursor Key Home
-               {"OF"  , VI_K_END     },   // Cursor Key End
-               {"OP"  , VI_K_FUN1    },   // Function Key F1
-               {"OQ"  , VI_K_FUN2    },   // Function Key F2
-               {"OR"  , VI_K_FUN3    },   // Function Key F3
-               {"OS"  , VI_K_FUN4    },   // Function Key F4
-
-               {"[A"  , VI_K_UP      },   // Cursor Key Up
-               {"[B"  , VI_K_DOWN    },   // Cursor Key Down
-               {"[C"  , VI_K_RIGHT   },   // Cursor Key Right
-               {"[D"  , VI_K_LEFT    },   // Cursor Key Left
-               {"[H"  , VI_K_HOME    },   // Cursor Key Home
-               {"[F"  , VI_K_END     },   // Cursor Key End
-               {"[1~" , VI_K_HOME    },   // Cursor Key Home
-               {"[2~" , VI_K_INSERT  },   // Cursor Key Insert
-               {"[3~" , VI_K_DELETE  },   // Cursor Key Delete
-               {"[4~" , VI_K_END     },   // Cursor Key End
-               {"[5~" , VI_K_PAGEUP  },   // Cursor Key Page Up
-               {"[6~" , VI_K_PAGEDOWN},   // Cursor Key Page Down
-               // careful: these have no terminating NUL!
-               {"[11~", VI_K_FUN1    },   // Function Key F1
-               {"[12~", VI_K_FUN2    },   // Function Key F2
-               {"[13~", VI_K_FUN3    },   // Function Key F3
-               {"[14~", VI_K_FUN4    },   // Function Key F4
-               {"[15~", VI_K_FUN5    },   // Function Key F5
-               {"[17~", VI_K_FUN6    },   // Function Key F6
-               {"[18~", VI_K_FUN7    },   // Function Key F7
-               {"[19~", VI_K_FUN8    },   // Function Key F8
-               {"[20~", VI_K_FUN9    },   // Function Key F9
-               {"[21~", VI_K_FUN10   },   // Function Key F10
-               {"[23~", VI_K_FUN11   },   // Function Key F11
-               {"[24~", VI_K_FUN12   },   // Function Key F12
-       };
 
        fflush(stdout);
-
-       n = chars_to_parse;
-       if (n == 0) {
-               // If no data, block waiting for input.  (If we read more than the
-               // minimal ESC sequence size, the "n=0" below would instead have to
-               // figure out how much to keep, resulting in larger code.)
-               n = safe_read(0, readbuffer, 3);
-               if (n <= 0) {
- error:
-                       go_bottom_and_clear_to_eol();
-                       cookmode(); // terminal to "cooked"
-                       bb_error_msg_and_die("can't read user input");
-               }
-       }
-
-       // Grab character to return from buffer
-       c = (unsigned char)readbuffer[0];
-       // Returning NUL from this routine would be bad.
-       if (c == '\0')
-               c = ' ';
-       n--;
-       if (n) memmove(readbuffer, readbuffer + 1, n);
-
-       // If it's an escape sequence, loop through known matches.
-       if (c == 27) {
-               const struct esc_cmds *eindex;
-               struct pollfd pfd;
-
-               pfd.fd = STDIN_FILENO;
-               pfd.events = POLLIN;
-               for (eindex = esccmds; eindex < esccmds + ARRAY_SIZE(esccmds); eindex++)
-               {
-                       // n - position in sequence we did not read yet
-                       int i = 0; // position in sequence to compare
-
-                       // Loop through chars in this sequence
-                       for (;;) {
-                               // So far escape sequence matches up to [i-1]
-                               if (n <= i) {
-                                       // Need more chars, read another one if it wouldn't block.
-                                       // (Note that escape sequences come in as a unit,
-                                       // so if we would block it's not really an escape sequence.)
-
-                                       // Timeout is needed to reconnect escape sequences
-                                       // split up by transmission over a serial console.
-
-                                       if (safe_poll(&pfd, 1, 50)) {
-                                               if (safe_read(0, readbuffer + n, 1) <= 0)
-                                                       goto error;
-                                               n++;
-                                       } else {
-                                               // No more data!
-                                               // Array is sorted from shortest to longest,
-                                               // we can't match anything later in array,
-                                               // break out of both loops.
-                                               goto loop_out;
-                                       }
-                               }
-                               if (readbuffer[i] != eindex->seq[i])
-                                       break; // try next seq
-                               i++;
-                               if (i == 4 || !eindex->seq[i]) { // entire seq matched
-                                       c = eindex->val; // sign extended!
-                                       n = 0;
-                                       // n -= i; memmove(...);
-                                       // would be more correct,
-                                       // but we never read ahead that much,
-                                       // and n == i here.
-                                       goto loop_out;
-                               }
-                       }
-               }
-               // We did not find matching sequence, it was a bare ESC.
-               // We possibly read and stored more input in readbuffer by now.
+       c = read_key(STDIN_FILENO, &chars_to_parse, readbuffer);
+       if (c == -1) { // EOF/error
+               go_bottom_and_clear_to_eol();
+               cookmode(); // terminal to "cooked"
+               bb_error_msg_and_die("can't read user input");
        }
- loop_out:
-
-       chars_to_parse = n;
        return c;
 }
 
@@ -3013,21 +2870,21 @@ static void do_cmd(int c)
 
        /* if this is a cursor key, skip these checks */
        switch (c) {
-               case VI_K_UP:
-               case VI_K_DOWN:
-               case VI_K_LEFT:
-               case VI_K_RIGHT:
-               case VI_K_HOME:
-               case VI_K_END:
-               case VI_K_PAGEUP:
-               case VI_K_PAGEDOWN:
-               case VI_K_DELETE:
+               case KEYCODE_UP:
+               case KEYCODE_DOWN:
+               case KEYCODE_LEFT:
+               case KEYCODE_RIGHT:
+               case KEYCODE_HOME:
+               case KEYCODE_END:
+               case KEYCODE_PAGEUP:
+               case KEYCODE_PAGEDOWN:
+               case KEYCODE_DELETE:
                        goto key_cmd_mode;
        }
 
        if (cmd_mode == 2) {
                //  flip-flop Insert/Replace mode
-               if (c == VI_K_INSERT)
+               if (c == KEYCODE_INSERT)
                        goto dc_i;
                // we are 'R'eplacing the current *dot with new char
                if (*dot == '\n') {
@@ -3044,7 +2901,7 @@ static void do_cmd(int c)
        }
        if (cmd_mode == 1) {
                //  hitting "Insert" twice means "R" replace mode
-               if (c == VI_K_INSERT) goto dc5;
+               if (c == KEYCODE_INSERT) goto dc5;
                // insert the char c at "dot"
                if (1 <= c || Isprint(c)) {
                        dot = char_insert(dot, c);
@@ -3108,7 +2965,7 @@ static void do_cmd(int c)
        case 0x00:                      // nul- ignore
                break;
        case 2:                 // ctrl-B  scroll up   full screen
-       case VI_K_PAGEUP:       // Cursor Key Page Up
+       case KEYCODE_PAGEUP:    // Cursor Key Page Up
                dot_scroll(rows - 2, -1);
                break;
        case 4:                 // ctrl-D  scroll down half screen
@@ -3118,14 +2975,14 @@ static void do_cmd(int c)
                dot_scroll(1, 1);
                break;
        case 6:                 // ctrl-F  scroll down full screen
-       case VI_K_PAGEDOWN:     // Cursor Key Page Down
+       case KEYCODE_PAGEDOWN:  // Cursor Key Page Down
                dot_scroll(rows - 2, 1);
                break;
        case 7:                 // ctrl-G  show current status
                last_status_cksum = 0;  // force status update
                break;
        case 'h':                       // h- move left
-       case VI_K_LEFT: // cursor key Left
+       case KEYCODE_LEFT:      // cursor key Left
        case 8:         // ctrl-H- move left    (This may be ERASE char)
        case 0x7f:      // DEL- move left   (This may be ERASE char)
                if (cmdcnt-- > 1) {
@@ -3135,7 +2992,7 @@ static void do_cmd(int c)
                break;
        case 10:                        // Newline ^J
        case 'j':                       // j- goto next line, same col
-       case VI_K_DOWN: // cursor key Down
+       case KEYCODE_DOWN:      // cursor key Down
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
@@ -3174,7 +3031,7 @@ static void do_cmd(int c)
                break;
        case ' ':                       // move right
        case 'l':                       // move right
-       case VI_K_RIGHT:        // Cursor Key Right
+       case KEYCODE_RIGHT:     // Cursor Key Right
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
@@ -3259,7 +3116,7 @@ static void do_cmd(int c)
                break;
 #endif /* FEATURE_VI_YANKMARK */
        case '$':                       // $- goto end of line
-       case VI_K_END:          // Cursor Key End
+       case KEYCODE_END:               // Cursor Key End
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
@@ -3584,7 +3441,7 @@ static void do_cmd(int c)
                dot_skip_over_ws();
                //**** fall through to ... 'i'
        case 'i':                       // i- insert before current char
-       case VI_K_INSERT:       // Cursor Key Insert
+       case KEYCODE_INSERT:    // Cursor Key Insert
  dc_i:
                cmd_mode = 1;   // start insrting
                break;
@@ -3637,7 +3494,7 @@ static void do_cmd(int c)
  dc5:
                cmd_mode = 2;
                break;
-       case VI_K_DELETE:
+       case KEYCODE_DELETE:
                c = 'x';
                // fall through
        case 'X':                       // X- delete char before dot
@@ -3787,7 +3644,7 @@ static void do_cmd(int c)
                break;
        }
        case 'k':                       // k- goto prev line, same col
-       case VI_K_UP:           // cursor key Up
+       case KEYCODE_UP:                // cursor key Up
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
@@ -3852,23 +3709,25 @@ static void do_cmd(int c)
                end_cmd_q();    // stop adding to q
                break;
                //----- The Cursor and Function Keys -----------------------------
-       case VI_K_HOME: // Cursor Key Home
+       case KEYCODE_HOME:      // Cursor Key Home
                dot_begin();
                break;
                // The Fn keys could point to do_macro which could translate them
-       case VI_K_FUN1: // Function Key F1
-       case VI_K_FUN2: // Function Key F2
-       case VI_K_FUN3: // Function Key F3
-       case VI_K_FUN4: // Function Key F4
-       case VI_K_FUN5: // Function Key F5
-       case VI_K_FUN6: // Function Key F6
-       case VI_K_FUN7: // Function Key F7
-       case VI_K_FUN8: // Function Key F8
-       case VI_K_FUN9: // Function Key F9
-       case VI_K_FUN10:        // Function Key F10
-       case VI_K_FUN11:        // Function Key F11
-       case VI_K_FUN12:        // Function Key F12
+#if 0
+       case KEYCODE_FUN1:      // Function Key F1
+       case KEYCODE_FUN2:      // Function Key F2
+       case KEYCODE_FUN3:      // Function Key F3
+       case KEYCODE_FUN4:      // Function Key F4
+       case KEYCODE_FUN5:      // Function Key F5
+       case KEYCODE_FUN6:      // Function Key F6
+       case KEYCODE_FUN7:      // Function Key F7
+       case KEYCODE_FUN8:      // Function Key F8
+       case KEYCODE_FUN9:      // Function Key F9
+       case KEYCODE_FUN10:     // Function Key F10
+       case KEYCODE_FUN11:     // Function Key F11
+       case KEYCODE_FUN12:     // Function Key F12
                break;
+#endif
        }
 
  dc1:
index 5b92574ddfe9074fce85ff8b8622603c1237e6c3..93171096253c8f83502bf8c43a71820265c00262 100644 (file)
@@ -921,6 +921,39 @@ void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
 #endif
 
 
+/* "Keycodes" that report an escape sequence.
+ * We use something which fits into signed char,
+ * yet doesn't represent any valid Unicode characher.
+ * Also, -1 is reserved for error indication and we don't use it. */
+enum {
+       KEYCODE_UP       =  -2, 
+       KEYCODE_DOWN     =  -3,
+       KEYCODE_RIGHT    =  -4,
+       KEYCODE_LEFT     =  -5,
+       KEYCODE_HOME     =  -6,
+       KEYCODE_END      =  -7,
+       KEYCODE_INSERT   =  -8,
+       KEYCODE_DELETE   =  -9,
+       KEYCODE_PAGEUP   = -10,
+       KEYCODE_PAGEDOWN = -11,
+#if 0
+       KEYCODE_FUN1     = -12,
+       KEYCODE_FUN2     = -13,
+       KEYCODE_FUN3     = -14,
+       KEYCODE_FUN4     = -15,
+       KEYCODE_FUN5     = -16,
+       KEYCODE_FUN6     = -17,
+       KEYCODE_FUN7     = -18,
+       KEYCODE_FUN8     = -19,
+       KEYCODE_FUN9     = -20,
+       KEYCODE_FUN10    = -21,
+       KEYCODE_FUN11    = -22,
+       KEYCODE_FUN12    = -23,
+#endif
+};
+int read_key(int fd, smalluint *nbuffered, char *buffer) FAST_FUNC;
+
+
 /* Networking */
 int create_icmp_socket(void) FAST_FUNC;
 int create_icmp6_socket(void) FAST_FUNC;
index 7262006753de2f7a7b0a7151088c72813cbfdd80..786cbee801f0ba953b87368b57a1e68c7661067e 100644 (file)
@@ -75,6 +75,7 @@ lib-y += process_escape_sequence.o
 lib-y += procps.o
 lib-y += ptr_to_globals.o
 lib-y += read.o
+lib-y += read_key.o
 lib-y += recursive_action.o
 lib-y += remove_file.o
 lib-y += restricted_shell.o