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 */ |