Commit 4c36ba323582773a87e9d277b0ce8febcf2113fd
1 parent
bb806047
monitor: Introduce ReadLineState (Jan Kiszka)
As another step towards decoupled monitor terminals encapsulate the state of the readline processor in a separate data structure called ReadLineState and adapt all interfaces appropriately. For now the monitor continues to instantiate just a single readline state. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6714 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
249 additions
and
231 deletions
monitor.c
| @@ -81,6 +81,7 @@ static uint8_t term_outbuf[1024]; | @@ -81,6 +81,7 @@ static uint8_t term_outbuf[1024]; | ||
| 81 | static int term_outbuf_index; | 81 | static int term_outbuf_index; |
| 82 | static BlockDriverCompletionFunc *password_completion_cb; | 82 | static BlockDriverCompletionFunc *password_completion_cb; |
| 83 | static void *password_opaque; | 83 | static void *password_opaque; |
| 84 | +ReadLineState *rs; | ||
| 84 | 85 | ||
| 85 | Monitor *cur_mon = NULL; | 86 | Monitor *cur_mon = NULL; |
| 86 | 87 | ||
| @@ -91,7 +92,7 @@ static CPUState *mon_cpu = NULL; | @@ -91,7 +92,7 @@ static CPUState *mon_cpu = NULL; | ||
| 91 | static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, | 92 | static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, |
| 92 | void *opaque) | 93 | void *opaque) |
| 93 | { | 94 | { |
| 94 | - readline_start("Password: ", 1, readline_func, opaque); | 95 | + readline_start(rs, "Password: ", 1, readline_func, opaque); |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | void monitor_flush(Monitor *mon) | 98 | void monitor_flush(Monitor *mon) |
| @@ -366,7 +367,7 @@ static void do_info_history(Monitor *mon) | @@ -366,7 +367,7 @@ static void do_info_history(Monitor *mon) | ||
| 366 | 367 | ||
| 367 | i = 0; | 368 | i = 0; |
| 368 | for(;;) { | 369 | for(;;) { |
| 369 | - str = readline_get_history(i); | 370 | + str = readline_get_history(rs, i); |
| 370 | if (!str) | 371 | if (!str) |
| 371 | break; | 372 | break; |
| 372 | monitor_printf(mon, "%d: '%s'\n", i, str); | 373 | monitor_printf(mon, "%d: '%s'\n", i, str); |
| @@ -2687,7 +2688,7 @@ static void cmd_completion(const char *name, const char *list) | @@ -2687,7 +2688,7 @@ static void cmd_completion(const char *name, const char *list) | ||
| 2687 | memcpy(cmd, pstart, len); | 2688 | memcpy(cmd, pstart, len); |
| 2688 | cmd[len] = '\0'; | 2689 | cmd[len] = '\0'; |
| 2689 | if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { | 2690 | if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { |
| 2690 | - readline_add_completion(cmd); | 2691 | + readline_add_completion(rs, cmd); |
| 2691 | } | 2692 | } |
| 2692 | if (*p == '\0') | 2693 | if (*p == '\0') |
| 2693 | break; | 2694 | break; |
| @@ -2740,7 +2741,7 @@ static void file_completion(const char *input) | @@ -2740,7 +2741,7 @@ static void file_completion(const char *input) | ||
| 2740 | stat(file, &sb); | 2741 | stat(file, &sb); |
| 2741 | if(S_ISDIR(sb.st_mode)) | 2742 | if(S_ISDIR(sb.st_mode)) |
| 2742 | pstrcat(file, sizeof(file), "/"); | 2743 | pstrcat(file, sizeof(file), "/"); |
| 2743 | - readline_add_completion(file); | 2744 | + readline_add_completion(rs, file); |
| 2744 | } | 2745 | } |
| 2745 | } | 2746 | } |
| 2746 | closedir(ffs); | 2747 | closedir(ffs); |
| @@ -2753,7 +2754,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs) | @@ -2753,7 +2754,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs) | ||
| 2753 | 2754 | ||
| 2754 | if (input[0] == '\0' || | 2755 | if (input[0] == '\0' || |
| 2755 | !strncmp(name, (char *)input, strlen(input))) { | 2756 | !strncmp(name, (char *)input, strlen(input))) { |
| 2756 | - readline_add_completion(name); | 2757 | + readline_add_completion(rs, name); |
| 2757 | } | 2758 | } |
| 2758 | } | 2759 | } |
| 2759 | 2760 | ||
| @@ -2783,7 +2784,7 @@ static void parse_cmdline(const char *cmdline, | @@ -2783,7 +2784,7 @@ static void parse_cmdline(const char *cmdline, | ||
| 2783 | *pnb_args = nb_args; | 2784 | *pnb_args = nb_args; |
| 2784 | } | 2785 | } |
| 2785 | 2786 | ||
| 2786 | -void readline_find_completion(const char *cmdline) | 2787 | +static void monitor_find_completion(const char *cmdline) |
| 2787 | { | 2788 | { |
| 2788 | const char *cmdname; | 2789 | const char *cmdname; |
| 2789 | char *args[MAX_ARGS]; | 2790 | char *args[MAX_ARGS]; |
| @@ -2813,7 +2814,7 @@ void readline_find_completion(const char *cmdline) | @@ -2813,7 +2814,7 @@ void readline_find_completion(const char *cmdline) | ||
| 2813 | cmdname = ""; | 2814 | cmdname = ""; |
| 2814 | else | 2815 | else |
| 2815 | cmdname = args[0]; | 2816 | cmdname = args[0]; |
| 2816 | - readline_set_completion_index(strlen(cmdname)); | 2817 | + readline_set_completion_index(rs, strlen(cmdname)); |
| 2817 | for(cmd = mon_cmds; cmd->name != NULL; cmd++) { | 2818 | for(cmd = mon_cmds; cmd->name != NULL; cmd++) { |
| 2818 | cmd_completion(cmdname, cmd->name); | 2819 | cmd_completion(cmdname, cmd->name); |
| 2819 | } | 2820 | } |
| @@ -2837,23 +2838,23 @@ void readline_find_completion(const char *cmdline) | @@ -2837,23 +2838,23 @@ void readline_find_completion(const char *cmdline) | ||
| 2837 | switch(*ptype) { | 2838 | switch(*ptype) { |
| 2838 | case 'F': | 2839 | case 'F': |
| 2839 | /* file completion */ | 2840 | /* file completion */ |
| 2840 | - readline_set_completion_index(strlen(str)); | 2841 | + readline_set_completion_index(rs, strlen(str)); |
| 2841 | file_completion(str); | 2842 | file_completion(str); |
| 2842 | break; | 2843 | break; |
| 2843 | case 'B': | 2844 | case 'B': |
| 2844 | /* block device name completion */ | 2845 | /* block device name completion */ |
| 2845 | - readline_set_completion_index(strlen(str)); | 2846 | + readline_set_completion_index(rs, strlen(str)); |
| 2846 | bdrv_iterate(block_completion_it, (void *)str); | 2847 | bdrv_iterate(block_completion_it, (void *)str); |
| 2847 | break; | 2848 | break; |
| 2848 | case 's': | 2849 | case 's': |
| 2849 | /* XXX: more generic ? */ | 2850 | /* XXX: more generic ? */ |
| 2850 | if (!strcmp(cmd->name, "info")) { | 2851 | if (!strcmp(cmd->name, "info")) { |
| 2851 | - readline_set_completion_index(strlen(str)); | 2852 | + readline_set_completion_index(rs, strlen(str)); |
| 2852 | for(cmd = info_cmds; cmd->name != NULL; cmd++) { | 2853 | for(cmd = info_cmds; cmd->name != NULL; cmd++) { |
| 2853 | cmd_completion(str, cmd->name); | 2854 | cmd_completion(str, cmd->name); |
| 2854 | } | 2855 | } |
| 2855 | } else if (!strcmp(cmd->name, "sendkey")) { | 2856 | } else if (!strcmp(cmd->name, "sendkey")) { |
| 2856 | - readline_set_completion_index(strlen(str)); | 2857 | + readline_set_completion_index(rs, strlen(str)); |
| 2857 | for(key = key_defs; key->name != NULL; key++) { | 2858 | for(key = key_defs; key->name != NULL; key++) { |
| 2858 | cmd_completion(str, key->name); | 2859 | cmd_completion(str, key->name); |
| 2859 | } | 2860 | } |
| @@ -2876,8 +2877,8 @@ static void term_read(void *opaque, const uint8_t *buf, int size) | @@ -2876,8 +2877,8 @@ static void term_read(void *opaque, const uint8_t *buf, int size) | ||
| 2876 | { | 2877 | { |
| 2877 | int i; | 2878 | int i; |
| 2878 | 2879 | ||
| 2879 | - for (i = 0; i < size; i++) | ||
| 2880 | - readline_handle_byte(buf[i]); | 2880 | + for(i = 0; i < size; i++) |
| 2881 | + readline_handle_byte(rs, buf[i]); | ||
| 2881 | } | 2882 | } |
| 2882 | 2883 | ||
| 2883 | static int monitor_suspended; | 2884 | static int monitor_suspended; |
| @@ -2886,7 +2887,7 @@ static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque) | @@ -2886,7 +2887,7 @@ static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque) | ||
| 2886 | { | 2887 | { |
| 2887 | monitor_handle_command(mon, cmdline); | 2888 | monitor_handle_command(mon, cmdline); |
| 2888 | if (!monitor_suspended) | 2889 | if (!monitor_suspended) |
| 2889 | - readline_show_prompt(); | 2890 | + readline_show_prompt(rs); |
| 2890 | else | 2891 | else |
| 2891 | monitor_suspended = 2; | 2892 | monitor_suspended = 2; |
| 2892 | } | 2893 | } |
| @@ -2905,8 +2906,8 @@ void monitor_resume(Monitor *mon) | @@ -2905,8 +2906,8 @@ void monitor_resume(Monitor *mon) | ||
| 2905 | 2906 | ||
| 2906 | static void monitor_start_input(void) | 2907 | static void monitor_start_input(void) |
| 2907 | { | 2908 | { |
| 2908 | - readline_start("(qemu) ", 0, monitor_command_cb, NULL); | ||
| 2909 | - readline_show_prompt(); | 2909 | + readline_start(rs, "(qemu) ", 0, monitor_command_cb, NULL); |
| 2910 | + readline_show_prompt(rs); | ||
| 2910 | } | 2911 | } |
| 2911 | 2912 | ||
| 2912 | static void term_event(void *opaque, int event) | 2913 | static void term_event(void *opaque, int event) |
| @@ -2935,6 +2936,7 @@ void monitor_init(CharDriverState *chr) | @@ -2935,6 +2936,7 @@ void monitor_init(CharDriverState *chr) | ||
| 2935 | mon = qemu_mallocz(sizeof(*mon)); | 2936 | mon = qemu_mallocz(sizeof(*mon)); |
| 2936 | 2937 | ||
| 2937 | mon->chr = chr; | 2938 | mon->chr = chr; |
| 2939 | + rs = readline_init(mon, monitor_find_completion); | ||
| 2938 | 2940 | ||
| 2939 | qemu_chr_add_handlers(chr, term_can_read, term_read, term_event, mon); | 2941 | qemu_chr_add_handlers(chr, term_can_read, term_read, term_event, mon); |
| 2940 | 2942 | ||
| @@ -2942,7 +2944,7 @@ void monitor_init(CharDriverState *chr) | @@ -2942,7 +2944,7 @@ void monitor_init(CharDriverState *chr) | ||
| 2942 | if (!cur_mon) | 2944 | if (!cur_mon) |
| 2943 | cur_mon = mon; | 2945 | cur_mon = mon; |
| 2944 | 2946 | ||
| 2945 | - readline_start("", 0, monitor_command_cb, NULL); | 2947 | + readline_start(rs, "", 0, monitor_command_cb, NULL); |
| 2946 | } | 2948 | } |
| 2947 | 2949 | ||
| 2948 | static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) | 2950 | static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) |
readline.c
| @@ -24,148 +24,118 @@ | @@ -24,148 +24,118 @@ | ||
| 24 | #include "readline.h" | 24 | #include "readline.h" |
| 25 | #include "monitor.h" | 25 | #include "monitor.h" |
| 26 | 26 | ||
| 27 | -#define TERM_CMD_BUF_SIZE 4095 | ||
| 28 | -#define TERM_MAX_CMDS 64 | ||
| 29 | -#define NB_COMPLETIONS_MAX 256 | ||
| 30 | - | ||
| 31 | #define IS_NORM 0 | 27 | #define IS_NORM 0 |
| 32 | #define IS_ESC 1 | 28 | #define IS_ESC 1 |
| 33 | #define IS_CSI 2 | 29 | #define IS_CSI 2 |
| 34 | 30 | ||
| 35 | #define printf do_not_use_printf | 31 | #define printf do_not_use_printf |
| 36 | 32 | ||
| 37 | -static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1]; | ||
| 38 | -static int term_cmd_buf_index; | ||
| 39 | -static int term_cmd_buf_size; | ||
| 40 | - | ||
| 41 | -static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1]; | ||
| 42 | -static int term_last_cmd_buf_index; | ||
| 43 | -static int term_last_cmd_buf_size; | ||
| 44 | - | ||
| 45 | -static int term_esc_state; | ||
| 46 | -static int term_esc_param; | ||
| 47 | - | ||
| 48 | -static char *term_history[TERM_MAX_CMDS]; | ||
| 49 | -static int term_hist_entry = -1; | ||
| 50 | - | ||
| 51 | -static int nb_completions; | ||
| 52 | -static int completion_index; | ||
| 53 | -static char *completions[NB_COMPLETIONS_MAX]; | ||
| 54 | - | ||
| 55 | -static ReadLineFunc *term_readline_func; | ||
| 56 | -static int term_is_password; | ||
| 57 | -static char term_prompt[256]; | ||
| 58 | -static void *term_readline_opaque; | ||
| 59 | - | ||
| 60 | -void readline_show_prompt(void) | 33 | +void readline_show_prompt(ReadLineState *rs) |
| 61 | { | 34 | { |
| 62 | - Monitor *mon = cur_mon; | ||
| 63 | - | ||
| 64 | - monitor_printf(mon, "%s", term_prompt); | ||
| 65 | - monitor_flush(mon); | ||
| 66 | - term_last_cmd_buf_index = 0; | ||
| 67 | - term_last_cmd_buf_size = 0; | ||
| 68 | - term_esc_state = IS_NORM; | 35 | + monitor_printf(rs->mon, "%s", rs->prompt); |
| 36 | + monitor_flush(rs->mon); | ||
| 37 | + rs->last_cmd_buf_index = 0; | ||
| 38 | + rs->last_cmd_buf_size = 0; | ||
| 39 | + rs->esc_state = IS_NORM; | ||
| 69 | } | 40 | } |
| 70 | 41 | ||
| 71 | /* update the displayed command line */ | 42 | /* update the displayed command line */ |
| 72 | -static void term_update(void) | 43 | +static void readline_update(ReadLineState *rs) |
| 73 | { | 44 | { |
| 74 | - Monitor *mon = cur_mon; | ||
| 75 | int i, delta, len; | 45 | int i, delta, len; |
| 76 | 46 | ||
| 77 | - if (term_cmd_buf_size != term_last_cmd_buf_size || | ||
| 78 | - memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) { | ||
| 79 | - for(i = 0; i < term_last_cmd_buf_index; i++) { | ||
| 80 | - monitor_printf(mon, "\033[D"); | 47 | + if (rs->cmd_buf_size != rs->last_cmd_buf_size || |
| 48 | + memcmp(rs->cmd_buf, rs->last_cmd_buf, rs->cmd_buf_size) != 0) { | ||
| 49 | + for(i = 0; i < rs->last_cmd_buf_index; i++) { | ||
| 50 | + monitor_printf(rs->mon, "\033[D"); | ||
| 81 | } | 51 | } |
| 82 | - term_cmd_buf[term_cmd_buf_size] = '\0'; | ||
| 83 | - if (term_is_password) { | ||
| 84 | - len = strlen(term_cmd_buf); | 52 | + rs->cmd_buf[rs->cmd_buf_size] = '\0'; |
| 53 | + if (rs->read_password) { | ||
| 54 | + len = strlen(rs->cmd_buf); | ||
| 85 | for(i = 0; i < len; i++) | 55 | for(i = 0; i < len; i++) |
| 86 | - monitor_printf(mon, "*"); | 56 | + monitor_printf(rs->mon, "*"); |
| 87 | } else { | 57 | } else { |
| 88 | - monitor_printf(mon, "%s", term_cmd_buf); | 58 | + monitor_printf(rs->mon, "%s", rs->cmd_buf); |
| 89 | } | 59 | } |
| 90 | - monitor_printf(mon, "\033[K"); | ||
| 91 | - memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size); | ||
| 92 | - term_last_cmd_buf_size = term_cmd_buf_size; | ||
| 93 | - term_last_cmd_buf_index = term_cmd_buf_size; | 60 | + monitor_printf(rs->mon, "\033[K"); |
| 61 | + memcpy(rs->last_cmd_buf, rs->cmd_buf, rs->cmd_buf_size); | ||
| 62 | + rs->last_cmd_buf_size = rs->cmd_buf_size; | ||
| 63 | + rs->last_cmd_buf_index = rs->cmd_buf_size; | ||
| 94 | } | 64 | } |
| 95 | - if (term_cmd_buf_index != term_last_cmd_buf_index) { | ||
| 96 | - delta = term_cmd_buf_index - term_last_cmd_buf_index; | 65 | + if (rs->cmd_buf_index != rs->last_cmd_buf_index) { |
| 66 | + delta = rs->cmd_buf_index - rs->last_cmd_buf_index; | ||
| 97 | if (delta > 0) { | 67 | if (delta > 0) { |
| 98 | for(i = 0;i < delta; i++) { | 68 | for(i = 0;i < delta; i++) { |
| 99 | - monitor_printf(mon, "\033[C"); | 69 | + monitor_printf(rs->mon, "\033[C"); |
| 100 | } | 70 | } |
| 101 | } else { | 71 | } else { |
| 102 | delta = -delta; | 72 | delta = -delta; |
| 103 | for(i = 0;i < delta; i++) { | 73 | for(i = 0;i < delta; i++) { |
| 104 | - monitor_printf(mon, "\033[D"); | 74 | + monitor_printf(rs->mon, "\033[D"); |
| 105 | } | 75 | } |
| 106 | } | 76 | } |
| 107 | - term_last_cmd_buf_index = term_cmd_buf_index; | 77 | + rs->last_cmd_buf_index = rs->cmd_buf_index; |
| 108 | } | 78 | } |
| 109 | - monitor_flush(mon); | 79 | + monitor_flush(rs->mon); |
| 110 | } | 80 | } |
| 111 | 81 | ||
| 112 | -static void term_insert_char(int ch) | 82 | +static void readline_insert_char(ReadLineState *rs, int ch) |
| 113 | { | 83 | { |
| 114 | - if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) { | ||
| 115 | - memmove(term_cmd_buf + term_cmd_buf_index + 1, | ||
| 116 | - term_cmd_buf + term_cmd_buf_index, | ||
| 117 | - term_cmd_buf_size - term_cmd_buf_index); | ||
| 118 | - term_cmd_buf[term_cmd_buf_index] = ch; | ||
| 119 | - term_cmd_buf_size++; | ||
| 120 | - term_cmd_buf_index++; | 84 | + if (rs->cmd_buf_index < READLINE_CMD_BUF_SIZE) { |
| 85 | + memmove(rs->cmd_buf + rs->cmd_buf_index + 1, | ||
| 86 | + rs->cmd_buf + rs->cmd_buf_index, | ||
| 87 | + rs->cmd_buf_size - rs->cmd_buf_index); | ||
| 88 | + rs->cmd_buf[rs->cmd_buf_index] = ch; | ||
| 89 | + rs->cmd_buf_size++; | ||
| 90 | + rs->cmd_buf_index++; | ||
| 121 | } | 91 | } |
| 122 | } | 92 | } |
| 123 | 93 | ||
| 124 | -static void term_backward_char(void) | 94 | +static void readline_backward_char(ReadLineState *rs) |
| 125 | { | 95 | { |
| 126 | - if (term_cmd_buf_index > 0) { | ||
| 127 | - term_cmd_buf_index--; | 96 | + if (rs->cmd_buf_index > 0) { |
| 97 | + rs->cmd_buf_index--; | ||
| 128 | } | 98 | } |
| 129 | } | 99 | } |
| 130 | 100 | ||
| 131 | -static void term_forward_char(void) | 101 | +static void readline_forward_char(ReadLineState *rs) |
| 132 | { | 102 | { |
| 133 | - if (term_cmd_buf_index < term_cmd_buf_size) { | ||
| 134 | - term_cmd_buf_index++; | 103 | + if (rs->cmd_buf_index < rs->cmd_buf_size) { |
| 104 | + rs->cmd_buf_index++; | ||
| 135 | } | 105 | } |
| 136 | } | 106 | } |
| 137 | 107 | ||
| 138 | -static void term_delete_char(void) | 108 | +static void readline_delete_char(ReadLineState *rs) |
| 139 | { | 109 | { |
| 140 | - if (term_cmd_buf_index < term_cmd_buf_size) { | ||
| 141 | - memmove(term_cmd_buf + term_cmd_buf_index, | ||
| 142 | - term_cmd_buf + term_cmd_buf_index + 1, | ||
| 143 | - term_cmd_buf_size - term_cmd_buf_index - 1); | ||
| 144 | - term_cmd_buf_size--; | 110 | + if (rs->cmd_buf_index < rs->cmd_buf_size) { |
| 111 | + memmove(rs->cmd_buf + rs->cmd_buf_index, | ||
| 112 | + rs->cmd_buf + rs->cmd_buf_index + 1, | ||
| 113 | + rs->cmd_buf_size - rs->cmd_buf_index - 1); | ||
| 114 | + rs->cmd_buf_size--; | ||
| 145 | } | 115 | } |
| 146 | } | 116 | } |
| 147 | 117 | ||
| 148 | -static void term_backspace(void) | 118 | +static void readline_backspace(ReadLineState *rs) |
| 149 | { | 119 | { |
| 150 | - if (term_cmd_buf_index > 0) { | ||
| 151 | - term_backward_char(); | ||
| 152 | - term_delete_char(); | 120 | + if (rs->cmd_buf_index > 0) { |
| 121 | + readline_backward_char(rs); | ||
| 122 | + readline_delete_char(rs); | ||
| 153 | } | 123 | } |
| 154 | } | 124 | } |
| 155 | 125 | ||
| 156 | -static void term_backword(void) | 126 | +static void readline_backword(ReadLineState *rs) |
| 157 | { | 127 | { |
| 158 | int start; | 128 | int start; |
| 159 | 129 | ||
| 160 | - if (term_cmd_buf_index == 0 || term_cmd_buf_index > term_cmd_buf_size) { | 130 | + if (rs->cmd_buf_index == 0 || rs->cmd_buf_index > rs->cmd_buf_size) { |
| 161 | return; | 131 | return; |
| 162 | } | 132 | } |
| 163 | 133 | ||
| 164 | - start = term_cmd_buf_index - 1; | 134 | + start = rs->cmd_buf_index - 1; |
| 165 | 135 | ||
| 166 | /* find first word (backwards) */ | 136 | /* find first word (backwards) */ |
| 167 | while (start > 0) { | 137 | while (start > 0) { |
| 168 | - if (!qemu_isspace(term_cmd_buf[start])) { | 138 | + if (!qemu_isspace(rs->cmd_buf[start])) { |
| 169 | break; | 139 | break; |
| 170 | } | 140 | } |
| 171 | 141 | ||
| @@ -174,7 +144,7 @@ static void term_backword(void) | @@ -174,7 +144,7 @@ static void term_backword(void) | ||
| 174 | 144 | ||
| 175 | /* find first space (backwards) */ | 145 | /* find first space (backwards) */ |
| 176 | while (start > 0) { | 146 | while (start > 0) { |
| 177 | - if (qemu_isspace(term_cmd_buf[start])) { | 147 | + if (qemu_isspace(rs->cmd_buf[start])) { |
| 178 | ++start; | 148 | ++start; |
| 179 | break; | 149 | break; |
| 180 | } | 150 | } |
| @@ -183,61 +153,61 @@ static void term_backword(void) | @@ -183,61 +153,61 @@ static void term_backword(void) | ||
| 183 | } | 153 | } |
| 184 | 154 | ||
| 185 | /* remove word */ | 155 | /* remove word */ |
| 186 | - if (start < term_cmd_buf_index) { | ||
| 187 | - memmove(term_cmd_buf + start, | ||
| 188 | - term_cmd_buf + term_cmd_buf_index, | ||
| 189 | - term_cmd_buf_size - term_cmd_buf_index); | ||
| 190 | - term_cmd_buf_size -= term_cmd_buf_index - start; | ||
| 191 | - term_cmd_buf_index = start; | 156 | + if (start < rs->cmd_buf_index) { |
| 157 | + memmove(rs->cmd_buf + start, | ||
| 158 | + rs->cmd_buf + rs->cmd_buf_index, | ||
| 159 | + rs->cmd_buf_size - rs->cmd_buf_index); | ||
| 160 | + rs->cmd_buf_size -= rs->cmd_buf_index - start; | ||
| 161 | + rs->cmd_buf_index = start; | ||
| 192 | } | 162 | } |
| 193 | } | 163 | } |
| 194 | 164 | ||
| 195 | -static void term_bol(void) | 165 | +static void readline_bol(ReadLineState *rs) |
| 196 | { | 166 | { |
| 197 | - term_cmd_buf_index = 0; | 167 | + rs->cmd_buf_index = 0; |
| 198 | } | 168 | } |
| 199 | 169 | ||
| 200 | -static void term_eol(void) | 170 | +static void readline_eol(ReadLineState *rs) |
| 201 | { | 171 | { |
| 202 | - term_cmd_buf_index = term_cmd_buf_size; | 172 | + rs->cmd_buf_index = rs->cmd_buf_size; |
| 203 | } | 173 | } |
| 204 | 174 | ||
| 205 | -static void term_up_char(void) | 175 | +static void readline_up_char(ReadLineState *rs) |
| 206 | { | 176 | { |
| 207 | int idx; | 177 | int idx; |
| 208 | 178 | ||
| 209 | - if (term_hist_entry == 0) | 179 | + if (rs->hist_entry == 0) |
| 210 | return; | 180 | return; |
| 211 | - if (term_hist_entry == -1) { | 181 | + if (rs->hist_entry == -1) { |
| 212 | /* Find latest entry */ | 182 | /* Find latest entry */ |
| 213 | - for (idx = 0; idx < TERM_MAX_CMDS; idx++) { | ||
| 214 | - if (term_history[idx] == NULL) | 183 | + for (idx = 0; idx < READLINE_MAX_CMDS; idx++) { |
| 184 | + if (rs->history[idx] == NULL) | ||
| 215 | break; | 185 | break; |
| 216 | } | 186 | } |
| 217 | - term_hist_entry = idx; | 187 | + rs->hist_entry = idx; |
| 218 | } | 188 | } |
| 219 | - term_hist_entry--; | ||
| 220 | - if (term_hist_entry >= 0) { | ||
| 221 | - pstrcpy(term_cmd_buf, sizeof(term_cmd_buf), | ||
| 222 | - term_history[term_hist_entry]); | ||
| 223 | - term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf); | 189 | + rs->hist_entry--; |
| 190 | + if (rs->hist_entry >= 0) { | ||
| 191 | + pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf), | ||
| 192 | + rs->history[rs->hist_entry]); | ||
| 193 | + rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf); | ||
| 224 | } | 194 | } |
| 225 | } | 195 | } |
| 226 | 196 | ||
| 227 | -static void term_down_char(void) | 197 | +static void readline_down_char(ReadLineState *rs) |
| 228 | { | 198 | { |
| 229 | - if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1) | 199 | + if (rs->hist_entry == READLINE_MAX_CMDS - 1 || rs->hist_entry == -1) |
| 230 | return; | 200 | return; |
| 231 | - if (term_history[++term_hist_entry] != NULL) { | ||
| 232 | - pstrcpy(term_cmd_buf, sizeof(term_cmd_buf), | ||
| 233 | - term_history[term_hist_entry]); | 201 | + if (rs->history[++rs->hist_entry] != NULL) { |
| 202 | + pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf), | ||
| 203 | + rs->history[rs->hist_entry]); | ||
| 234 | } else { | 204 | } else { |
| 235 | - term_hist_entry = -1; | 205 | + rs->hist_entry = -1; |
| 236 | } | 206 | } |
| 237 | - term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf); | 207 | + rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf); |
| 238 | } | 208 | } |
| 239 | 209 | ||
| 240 | -static void term_hist_add(const char *cmdline) | 210 | +static void readline_hist_add(ReadLineState *rs, const char *cmdline) |
| 241 | { | 211 | { |
| 242 | char *hist_entry, *new_entry; | 212 | char *hist_entry, *new_entry; |
| 243 | int idx; | 213 | int idx; |
| @@ -245,99 +215,99 @@ static void term_hist_add(const char *cmdline) | @@ -245,99 +215,99 @@ static void term_hist_add(const char *cmdline) | ||
| 245 | if (cmdline[0] == '\0') | 215 | if (cmdline[0] == '\0') |
| 246 | return; | 216 | return; |
| 247 | new_entry = NULL; | 217 | new_entry = NULL; |
| 248 | - if (term_hist_entry != -1) { | 218 | + if (rs->hist_entry != -1) { |
| 249 | /* We were editing an existing history entry: replace it */ | 219 | /* We were editing an existing history entry: replace it */ |
| 250 | - hist_entry = term_history[term_hist_entry]; | ||
| 251 | - idx = term_hist_entry; | 220 | + hist_entry = rs->history[rs->hist_entry]; |
| 221 | + idx = rs->hist_entry; | ||
| 252 | if (strcmp(hist_entry, cmdline) == 0) { | 222 | if (strcmp(hist_entry, cmdline) == 0) { |
| 253 | goto same_entry; | 223 | goto same_entry; |
| 254 | } | 224 | } |
| 255 | } | 225 | } |
| 256 | /* Search cmdline in history buffers */ | 226 | /* Search cmdline in history buffers */ |
| 257 | - for (idx = 0; idx < TERM_MAX_CMDS; idx++) { | ||
| 258 | - hist_entry = term_history[idx]; | 227 | + for (idx = 0; idx < READLINE_MAX_CMDS; idx++) { |
| 228 | + hist_entry = rs->history[idx]; | ||
| 259 | if (hist_entry == NULL) | 229 | if (hist_entry == NULL) |
| 260 | break; | 230 | break; |
| 261 | if (strcmp(hist_entry, cmdline) == 0) { | 231 | if (strcmp(hist_entry, cmdline) == 0) { |
| 262 | same_entry: | 232 | same_entry: |
| 263 | new_entry = hist_entry; | 233 | new_entry = hist_entry; |
| 264 | /* Put this entry at the end of history */ | 234 | /* Put this entry at the end of history */ |
| 265 | - memmove(&term_history[idx], &term_history[idx + 1], | ||
| 266 | - (TERM_MAX_CMDS - idx + 1) * sizeof(char *)); | ||
| 267 | - term_history[TERM_MAX_CMDS - 1] = NULL; | ||
| 268 | - for (; idx < TERM_MAX_CMDS; idx++) { | ||
| 269 | - if (term_history[idx] == NULL) | 235 | + memmove(&rs->history[idx], &rs->history[idx + 1], |
| 236 | + (READLINE_MAX_CMDS - idx + 1) * sizeof(char *)); | ||
| 237 | + rs->history[READLINE_MAX_CMDS - 1] = NULL; | ||
| 238 | + for (; idx < READLINE_MAX_CMDS; idx++) { | ||
| 239 | + if (rs->history[idx] == NULL) | ||
| 270 | break; | 240 | break; |
| 271 | } | 241 | } |
| 272 | break; | 242 | break; |
| 273 | } | 243 | } |
| 274 | } | 244 | } |
| 275 | - if (idx == TERM_MAX_CMDS) { | 245 | + if (idx == READLINE_MAX_CMDS) { |
| 276 | /* Need to get one free slot */ | 246 | /* Need to get one free slot */ |
| 277 | - free(term_history[0]); | ||
| 278 | - memcpy(term_history, &term_history[1], | ||
| 279 | - (TERM_MAX_CMDS - 1) * sizeof(char *)); | ||
| 280 | - term_history[TERM_MAX_CMDS - 1] = NULL; | ||
| 281 | - idx = TERM_MAX_CMDS - 1; | 247 | + free(rs->history[0]); |
| 248 | + memcpy(rs->history, &rs->history[1], | ||
| 249 | + (READLINE_MAX_CMDS - 1) * sizeof(char *)); | ||
| 250 | + rs->history[READLINE_MAX_CMDS - 1] = NULL; | ||
| 251 | + idx = READLINE_MAX_CMDS - 1; | ||
| 282 | } | 252 | } |
| 283 | if (new_entry == NULL) | 253 | if (new_entry == NULL) |
| 284 | new_entry = strdup(cmdline); | 254 | new_entry = strdup(cmdline); |
| 285 | - term_history[idx] = new_entry; | ||
| 286 | - term_hist_entry = -1; | 255 | + rs->history[idx] = new_entry; |
| 256 | + rs->hist_entry = -1; | ||
| 287 | } | 257 | } |
| 288 | 258 | ||
| 289 | /* completion support */ | 259 | /* completion support */ |
| 290 | 260 | ||
| 291 | -void readline_add_completion(const char *str) | 261 | +void readline_add_completion(ReadLineState *rs, const char *str) |
| 292 | { | 262 | { |
| 293 | - if (nb_completions < NB_COMPLETIONS_MAX) { | ||
| 294 | - completions[nb_completions++] = qemu_strdup(str); | 263 | + if (rs->nb_completions < READLINE_MAX_COMPLETIONS) { |
| 264 | + rs->completions[rs->nb_completions++] = qemu_strdup(str); | ||
| 295 | } | 265 | } |
| 296 | } | 266 | } |
| 297 | 267 | ||
| 298 | -void readline_set_completion_index(int index) | 268 | +void readline_set_completion_index(ReadLineState *rs, int index) |
| 299 | { | 269 | { |
| 300 | - completion_index = index; | 270 | + rs->completion_index = index; |
| 301 | } | 271 | } |
| 302 | 272 | ||
| 303 | -static void term_completion(void) | 273 | +static void readline_completion(ReadLineState *rs) |
| 304 | { | 274 | { |
| 305 | Monitor *mon = cur_mon; | 275 | Monitor *mon = cur_mon; |
| 306 | int len, i, j, max_width, nb_cols, max_prefix; | 276 | int len, i, j, max_width, nb_cols, max_prefix; |
| 307 | char *cmdline; | 277 | char *cmdline; |
| 308 | 278 | ||
| 309 | - nb_completions = 0; | 279 | + rs->nb_completions = 0; |
| 310 | 280 | ||
| 311 | - cmdline = qemu_malloc(term_cmd_buf_index + 1); | ||
| 312 | - memcpy(cmdline, term_cmd_buf, term_cmd_buf_index); | ||
| 313 | - cmdline[term_cmd_buf_index] = '\0'; | ||
| 314 | - readline_find_completion(cmdline); | 281 | + cmdline = qemu_malloc(rs->cmd_buf_index + 1); |
| 282 | + memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index); | ||
| 283 | + cmdline[rs->cmd_buf_index] = '\0'; | ||
| 284 | + rs->completion_finder(cmdline); | ||
| 315 | qemu_free(cmdline); | 285 | qemu_free(cmdline); |
| 316 | 286 | ||
| 317 | /* no completion found */ | 287 | /* no completion found */ |
| 318 | - if (nb_completions <= 0) | 288 | + if (rs->nb_completions <= 0) |
| 319 | return; | 289 | return; |
| 320 | - if (nb_completions == 1) { | ||
| 321 | - len = strlen(completions[0]); | ||
| 322 | - for(i = completion_index; i < len; i++) { | ||
| 323 | - term_insert_char(completions[0][i]); | 290 | + if (rs->nb_completions == 1) { |
| 291 | + len = strlen(rs->completions[0]); | ||
| 292 | + for(i = rs->completion_index; i < len; i++) { | ||
| 293 | + readline_insert_char(rs, rs->completions[0][i]); | ||
| 324 | } | 294 | } |
| 325 | /* extra space for next argument. XXX: make it more generic */ | 295 | /* extra space for next argument. XXX: make it more generic */ |
| 326 | - if (len > 0 && completions[0][len - 1] != '/') | ||
| 327 | - term_insert_char(' '); | 296 | + if (len > 0 && rs->completions[0][len - 1] != '/') |
| 297 | + readline_insert_char(rs, ' '); | ||
| 328 | } else { | 298 | } else { |
| 329 | monitor_printf(mon, "\n"); | 299 | monitor_printf(mon, "\n"); |
| 330 | max_width = 0; | 300 | max_width = 0; |
| 331 | max_prefix = 0; | 301 | max_prefix = 0; |
| 332 | - for(i = 0; i < nb_completions; i++) { | ||
| 333 | - len = strlen(completions[i]); | 302 | + for(i = 0; i < rs->nb_completions; i++) { |
| 303 | + len = strlen(rs->completions[i]); | ||
| 334 | if (i==0) { | 304 | if (i==0) { |
| 335 | max_prefix = len; | 305 | max_prefix = len; |
| 336 | } else { | 306 | } else { |
| 337 | if (len < max_prefix) | 307 | if (len < max_prefix) |
| 338 | max_prefix = len; | 308 | max_prefix = len; |
| 339 | for(j=0; j<max_prefix; j++) { | 309 | for(j=0; j<max_prefix; j++) { |
| 340 | - if (completions[i][j] != completions[0][j]) | 310 | + if (rs->completions[i][j] != rs->completions[0][j]) |
| 341 | max_prefix = j; | 311 | max_prefix = j; |
| 342 | } | 312 | } |
| 343 | } | 313 | } |
| @@ -345,8 +315,8 @@ static void term_completion(void) | @@ -345,8 +315,8 @@ static void term_completion(void) | ||
| 345 | max_width = len; | 315 | max_width = len; |
| 346 | } | 316 | } |
| 347 | if (max_prefix > 0) | 317 | if (max_prefix > 0) |
| 348 | - for(i = completion_index; i < max_prefix; i++) { | ||
| 349 | - term_insert_char(completions[0][i]); | 318 | + for(i = rs->completion_index; i < max_prefix; i++) { |
| 319 | + readline_insert_char(rs, rs->completions[0][i]); | ||
| 350 | } | 320 | } |
| 351 | max_width += 2; | 321 | max_width += 2; |
| 352 | if (max_width < 10) | 322 | if (max_width < 10) |
| @@ -355,135 +325,147 @@ static void term_completion(void) | @@ -355,135 +325,147 @@ static void term_completion(void) | ||
| 355 | max_width = 80; | 325 | max_width = 80; |
| 356 | nb_cols = 80 / max_width; | 326 | nb_cols = 80 / max_width; |
| 357 | j = 0; | 327 | j = 0; |
| 358 | - for(i = 0; i < nb_completions; i++) { | ||
| 359 | - monitor_printf(mon, "%-*s", max_width, completions[i]); | ||
| 360 | - if (++j == nb_cols || i == (nb_completions - 1)) { | ||
| 361 | - monitor_printf(mon, "\n"); | 328 | + for(i = 0; i < rs->nb_completions; i++) { |
| 329 | + monitor_printf(rs->mon, "%-*s", max_width, rs->completions[i]); | ||
| 330 | + if (++j == nb_cols || i == (rs->nb_completions - 1)) { | ||
| 331 | + monitor_printf(rs->mon, "\n"); | ||
| 362 | j = 0; | 332 | j = 0; |
| 363 | } | 333 | } |
| 364 | } | 334 | } |
| 365 | - readline_show_prompt(); | 335 | + readline_show_prompt(rs); |
| 366 | } | 336 | } |
| 367 | } | 337 | } |
| 368 | 338 | ||
| 369 | /* return true if command handled */ | 339 | /* return true if command handled */ |
| 370 | -void readline_handle_byte(int ch) | 340 | +void readline_handle_byte(ReadLineState *rs, int ch) |
| 371 | { | 341 | { |
| 372 | - Monitor *mon = cur_mon; | ||
| 373 | - | ||
| 374 | - switch(term_esc_state) { | 342 | + switch(rs->esc_state) { |
| 375 | case IS_NORM: | 343 | case IS_NORM: |
| 376 | switch(ch) { | 344 | switch(ch) { |
| 377 | case 1: | 345 | case 1: |
| 378 | - term_bol(); | 346 | + readline_bol(rs); |
| 379 | break; | 347 | break; |
| 380 | case 4: | 348 | case 4: |
| 381 | - term_delete_char(); | 349 | + readline_delete_char(rs); |
| 382 | break; | 350 | break; |
| 383 | case 5: | 351 | case 5: |
| 384 | - term_eol(); | 352 | + readline_eol(rs); |
| 385 | break; | 353 | break; |
| 386 | case 9: | 354 | case 9: |
| 387 | - term_completion(); | 355 | + readline_completion(rs); |
| 388 | break; | 356 | break; |
| 389 | case 10: | 357 | case 10: |
| 390 | case 13: | 358 | case 13: |
| 391 | - term_cmd_buf[term_cmd_buf_size] = '\0'; | ||
| 392 | - if (!term_is_password) | ||
| 393 | - term_hist_add(term_cmd_buf); | ||
| 394 | - monitor_printf(mon, "\n"); | ||
| 395 | - term_cmd_buf_index = 0; | ||
| 396 | - term_cmd_buf_size = 0; | ||
| 397 | - term_last_cmd_buf_index = 0; | ||
| 398 | - term_last_cmd_buf_size = 0; | ||
| 399 | - /* NOTE: readline_start can be called here */ | ||
| 400 | - term_readline_func(mon, term_cmd_buf, term_readline_opaque); | 359 | + rs->cmd_buf[rs->cmd_buf_size] = '\0'; |
| 360 | + if (!rs->read_password) | ||
| 361 | + readline_hist_add(rs, rs->cmd_buf); | ||
| 362 | + monitor_printf(rs->mon, "\n"); | ||
| 363 | + rs->cmd_buf_index = 0; | ||
| 364 | + rs->cmd_buf_size = 0; | ||
| 365 | + rs->last_cmd_buf_index = 0; | ||
| 366 | + rs->last_cmd_buf_size = 0; | ||
| 367 | + rs->readline_func(rs->mon, rs->cmd_buf, rs->readline_opaque); | ||
| 401 | break; | 368 | break; |
| 402 | case 23: | 369 | case 23: |
| 403 | /* ^W */ | 370 | /* ^W */ |
| 404 | - term_backword(); | 371 | + readline_backword(rs); |
| 405 | break; | 372 | break; |
| 406 | case 27: | 373 | case 27: |
| 407 | - term_esc_state = IS_ESC; | 374 | + rs->esc_state = IS_ESC; |
| 408 | break; | 375 | break; |
| 409 | case 127: | 376 | case 127: |
| 410 | case 8: | 377 | case 8: |
| 411 | - term_backspace(); | 378 | + readline_backspace(rs); |
| 412 | break; | 379 | break; |
| 413 | case 155: | 380 | case 155: |
| 414 | - term_esc_state = IS_CSI; | 381 | + rs->esc_state = IS_CSI; |
| 415 | break; | 382 | break; |
| 416 | default: | 383 | default: |
| 417 | if (ch >= 32) { | 384 | if (ch >= 32) { |
| 418 | - term_insert_char(ch); | 385 | + readline_insert_char(rs, ch); |
| 419 | } | 386 | } |
| 420 | break; | 387 | break; |
| 421 | } | 388 | } |
| 422 | break; | 389 | break; |
| 423 | case IS_ESC: | 390 | case IS_ESC: |
| 424 | if (ch == '[') { | 391 | if (ch == '[') { |
| 425 | - term_esc_state = IS_CSI; | ||
| 426 | - term_esc_param = 0; | 392 | + rs->esc_state = IS_CSI; |
| 393 | + rs->esc_param = 0; | ||
| 427 | } else { | 394 | } else { |
| 428 | - term_esc_state = IS_NORM; | 395 | + rs->esc_state = IS_NORM; |
| 429 | } | 396 | } |
| 430 | break; | 397 | break; |
| 431 | case IS_CSI: | 398 | case IS_CSI: |
| 432 | switch(ch) { | 399 | switch(ch) { |
| 433 | case 'A': | 400 | case 'A': |
| 434 | case 'F': | 401 | case 'F': |
| 435 | - term_up_char(); | 402 | + readline_up_char(rs); |
| 436 | break; | 403 | break; |
| 437 | case 'B': | 404 | case 'B': |
| 438 | case 'E': | 405 | case 'E': |
| 439 | - term_down_char(); | 406 | + readline_down_char(rs); |
| 440 | break; | 407 | break; |
| 441 | case 'D': | 408 | case 'D': |
| 442 | - term_backward_char(); | 409 | + readline_backward_char(rs); |
| 443 | break; | 410 | break; |
| 444 | case 'C': | 411 | case 'C': |
| 445 | - term_forward_char(); | 412 | + readline_forward_char(rs); |
| 446 | break; | 413 | break; |
| 447 | case '0' ... '9': | 414 | case '0' ... '9': |
| 448 | - term_esc_param = term_esc_param * 10 + (ch - '0'); | 415 | + rs->esc_param = rs->esc_param * 10 + (ch - '0'); |
| 449 | goto the_end; | 416 | goto the_end; |
| 450 | case '~': | 417 | case '~': |
| 451 | - switch(term_esc_param) { | 418 | + switch(rs->esc_param) { |
| 452 | case 1: | 419 | case 1: |
| 453 | - term_bol(); | 420 | + readline_bol(rs); |
| 454 | break; | 421 | break; |
| 455 | case 3: | 422 | case 3: |
| 456 | - term_delete_char(); | 423 | + readline_delete_char(rs); |
| 457 | break; | 424 | break; |
| 458 | case 4: | 425 | case 4: |
| 459 | - term_eol(); | 426 | + readline_eol(rs); |
| 460 | break; | 427 | break; |
| 461 | } | 428 | } |
| 462 | break; | 429 | break; |
| 463 | default: | 430 | default: |
| 464 | break; | 431 | break; |
| 465 | } | 432 | } |
| 466 | - term_esc_state = IS_NORM; | 433 | + rs->esc_state = IS_NORM; |
| 467 | the_end: | 434 | the_end: |
| 468 | break; | 435 | break; |
| 469 | } | 436 | } |
| 470 | - term_update(); | 437 | + readline_update(rs); |
| 471 | } | 438 | } |
| 472 | 439 | ||
| 473 | -void readline_start(const char *prompt, int is_password, | 440 | +void readline_start(ReadLineState *rs, const char *prompt, int read_password, |
| 474 | ReadLineFunc *readline_func, void *opaque) | 441 | ReadLineFunc *readline_func, void *opaque) |
| 475 | { | 442 | { |
| 476 | - pstrcpy(term_prompt, sizeof(term_prompt), prompt); | ||
| 477 | - term_readline_func = readline_func; | ||
| 478 | - term_readline_opaque = opaque; | ||
| 479 | - term_is_password = is_password; | ||
| 480 | - term_cmd_buf_index = 0; | ||
| 481 | - term_cmd_buf_size = 0; | 443 | + pstrcpy(rs->prompt, sizeof(rs->prompt), prompt); |
| 444 | + rs->readline_func = readline_func; | ||
| 445 | + rs->readline_opaque = opaque; | ||
| 446 | + rs->read_password = read_password; | ||
| 447 | + rs->cmd_buf_index = 0; | ||
| 448 | + rs->cmd_buf_size = 0; | ||
| 482 | } | 449 | } |
| 483 | 450 | ||
| 484 | -const char *readline_get_history(unsigned int index) | 451 | +const char *readline_get_history(ReadLineState *rs, unsigned int index) |
| 485 | { | 452 | { |
| 486 | - if (index >= TERM_MAX_CMDS) | 453 | + if (index >= READLINE_MAX_CMDS) |
| 487 | return NULL; | 454 | return NULL; |
| 488 | - return term_history[index]; | 455 | + return rs->history[index]; |
| 456 | +} | ||
| 457 | + | ||
| 458 | +ReadLineState *readline_init(Monitor *mon, | ||
| 459 | + ReadLineCompletionFunc *completion_finder) | ||
| 460 | +{ | ||
| 461 | + ReadLineState *rs = qemu_mallocz(sizeof(*rs)); | ||
| 462 | + | ||
| 463 | + if (!rs) | ||
| 464 | + return NULL; | ||
| 465 | + | ||
| 466 | + rs->hist_entry = -1; | ||
| 467 | + rs->mon = mon; | ||
| 468 | + rs->completion_finder = completion_finder; | ||
| 469 | + | ||
| 470 | + return rs; | ||
| 489 | } | 471 | } |
readline.h
| @@ -3,18 +3,52 @@ | @@ -3,18 +3,52 @@ | ||
| 3 | 3 | ||
| 4 | #include "qemu-common.h" | 4 | #include "qemu-common.h" |
| 5 | 5 | ||
| 6 | +#define READLINE_CMD_BUF_SIZE 4095 | ||
| 7 | +#define READLINE_MAX_CMDS 64 | ||
| 8 | +#define READLINE_MAX_COMPLETIONS 256 | ||
| 9 | + | ||
| 6 | typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque); | 10 | typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque); |
| 11 | +typedef void ReadLineCompletionFunc(const char *cmdline); | ||
| 12 | + | ||
| 13 | +typedef struct ReadLineState { | ||
| 14 | + char cmd_buf[READLINE_CMD_BUF_SIZE + 1]; | ||
| 15 | + int cmd_buf_index; | ||
| 16 | + int cmd_buf_size; | ||
| 17 | + | ||
| 18 | + char last_cmd_buf[READLINE_CMD_BUF_SIZE + 1]; | ||
| 19 | + int last_cmd_buf_index; | ||
| 20 | + int last_cmd_buf_size; | ||
| 21 | + | ||
| 22 | + int esc_state; | ||
| 23 | + int esc_param; | ||
| 7 | 24 | ||
| 8 | -void readline_add_completion(const char *str); | ||
| 9 | -void readline_set_completion_index(int index); | ||
| 10 | -void readline_find_completion(const char *cmdline); | 25 | + char *history[READLINE_MAX_CMDS]; |
| 26 | + int hist_entry; | ||
| 11 | 27 | ||
| 12 | -const char *readline_get_history(unsigned int index); | 28 | + ReadLineCompletionFunc *completion_finder; |
| 29 | + char *completions[READLINE_MAX_COMPLETIONS]; | ||
| 30 | + int nb_completions; | ||
| 31 | + int completion_index; | ||
| 13 | 32 | ||
| 14 | -void readline_handle_byte(int ch); | 33 | + ReadLineFunc *readline_func; |
| 34 | + void *readline_opaque; | ||
| 35 | + int read_password; | ||
| 36 | + char prompt[256]; | ||
| 37 | + Monitor *mon; | ||
| 38 | +} ReadLineState; | ||
| 15 | 39 | ||
| 16 | -void readline_start(const char *prompt, int is_password, | 40 | +void readline_add_completion(ReadLineState *rs, const char *str); |
| 41 | +void readline_set_completion_index(ReadLineState *rs, int completion_index); | ||
| 42 | + | ||
| 43 | +const char *readline_get_history(ReadLineState *rs, unsigned int index); | ||
| 44 | + | ||
| 45 | +void readline_handle_byte(ReadLineState *rs, int ch); | ||
| 46 | + | ||
| 47 | +void readline_start(ReadLineState *rs, const char *prompt, int read_password, | ||
| 17 | ReadLineFunc *readline_func, void *opaque); | 48 | ReadLineFunc *readline_func, void *opaque); |
| 18 | -void readline_show_prompt(void); | 49 | +void readline_show_prompt(ReadLineState *rs); |
| 50 | + | ||
| 51 | +ReadLineState *readline_init(Monitor *mon, | ||
| 52 | + ReadLineCompletionFunc *completion_finder); | ||
| 19 | 53 | ||
| 20 | #endif /* !READLINE_H */ | 54 | #endif /* !READLINE_H */ |