[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 13/93] readline: decouple readline from the monitor
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 13/93] readline: decouple readline from the monitor |
Date: |
Fri, 24 Jan 2014 18:20:56 +0100 |
From: Stefan Hajnoczi <address@hidden>
Make the readline.c functionality reusable. Instead of calling
monitor_printf() and monitor_flush() directly, invoke function pointers
provided by the user.
This way readline.c does not know about Monitor and other users will be
able to make use of readline.c.
Note that there is already an "opaque" argument to the ReadLineFunc
callback. Consistently call it "readline_opaque" from now on to
distinguish from the ReadLinePrintfFunc/ReadLineFlushFunc "opaque"
argument.
I also dropped the printf macro trickery since it's now highly unlikely
that anyone modifying readline.c would call printf(3) directly. We no
longer need this protection.
Signed-off-by: Stefan Hajnoczi <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
hmp.c | 6 +++---
include/monitor/readline.h | 20 +++++++++++++-------
monitor.c | 39 ++++++++++++++++++++++++++++++++-------
readline.c | 44 +++++++++++++++++++++++---------------------
4 files changed, 71 insertions(+), 38 deletions(-)
diff --git a/hmp.c b/hmp.c
index 79f9c7d..468f97d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1092,11 +1092,11 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &err);
}
-static void hmp_change_read_arg(Monitor *mon, const char *password,
- void *opaque)
+static void hmp_change_read_arg(void *opaque, const char *password,
+ void *readline_opaque)
{
qmp_change_vnc_password(password, NULL);
- monitor_read_command(mon, 1);
+ monitor_read_command(opaque, 1);
}
void hmp_change(Monitor *mon, const QDict *qdict)
diff --git a/include/monitor/readline.h b/include/monitor/readline.h
index 0faf6e1..a89fe4a 100644
--- a/include/monitor/readline.h
+++ b/include/monitor/readline.h
@@ -1,14 +1,15 @@
#ifndef READLINE_H
#define READLINE_H
-#include "qemu-common.h"
-
#define READLINE_CMD_BUF_SIZE 4095
#define READLINE_MAX_CMDS 64
#define READLINE_MAX_COMPLETIONS 256
-typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque);
-typedef void ReadLineCompletionFunc(Monitor *mon,
+typedef void ReadLinePrintfFunc(void *opaque, const char *fmt, ...);
+typedef void ReadLineFlushFunc(void *opaque);
+typedef void ReadLineFunc(void *opaque, const char *str,
+ void *readline_opaque);
+typedef void ReadLineCompletionFunc(void *opaque,
const char *cmdline);
typedef struct ReadLineState {
@@ -35,7 +36,10 @@ typedef struct ReadLineState {
void *readline_opaque;
int read_password;
char prompt[256];
- Monitor *mon;
+
+ ReadLinePrintfFunc *printf_func;
+ ReadLineFlushFunc *flush_func;
+ void *opaque;
} ReadLineState;
void readline_add_completion(ReadLineState *rs, const char *str);
@@ -46,11 +50,13 @@ const char *readline_get_history(ReadLineState *rs,
unsigned int index);
void readline_handle_byte(ReadLineState *rs, int ch);
void readline_start(ReadLineState *rs, const char *prompt, int read_password,
- ReadLineFunc *readline_func, void *opaque);
+ ReadLineFunc *readline_func, void *readline_opaque);
void readline_restart(ReadLineState *rs);
void readline_show_prompt(ReadLineState *rs);
-ReadLineState *readline_init(Monitor *mon,
+ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
+ ReadLineFlushFunc *flush_func,
+ void *opaque,
ReadLineCompletionFunc *completion_finder);
#endif /* !READLINE_H */
diff --git a/monitor.c b/monitor.c
index 845f608..32d0264 100644
--- a/monitor.c
+++ b/monitor.c
@@ -217,8 +217,8 @@ static const mon_cmd_t qmp_cmds[];
Monitor *cur_mon;
Monitor *default_mon;
-static void monitor_command_cb(Monitor *mon, const char *cmdline,
- void *opaque);
+static void monitor_command_cb(void *opaque, const char *cmdline,
+ void *readline_opaque);
static inline int qmp_cmd_mode(const Monitor *mon)
{
@@ -4338,9 +4338,10 @@ static void monitor_find_completion_by_table(Monitor
*mon,
}
}
-static void monitor_find_completion(Monitor *mon,
+static void monitor_find_completion(void *opaque,
const char *cmdline)
{
+ Monitor *mon = opaque;
char *args[MAX_ARGS];
int nb_args, len;
@@ -4751,8 +4752,11 @@ static void monitor_read(void *opaque, const uint8_t
*buf, int size)
cur_mon = old_mon;
}
-static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
+static void monitor_command_cb(void *opaque, const char *cmdline,
+ void *readline_opaque)
{
+ Monitor *mon = opaque;
+
monitor_suspend(mon);
handle_user_command(mon, cmdline);
monitor_resume(mon);
@@ -4881,6 +4885,22 @@ static void sortcmdlist(void)
* End:
*/
+/* These functions just adapt the readline interface in a typesafe way. We
+ * could cast function pointers but that discards compiler checks.
+ */
+static void monitor_readline_printf(void *opaque, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ monitor_vprintf(opaque, fmt, ap);
+ va_end(ap);
+}
+
+static void monitor_readline_flush(void *opaque)
+{
+ monitor_flush(opaque);
+}
+
void monitor_init(CharDriverState *chr, int flags)
{
static int is_first_init = 1;
@@ -4898,7 +4918,10 @@ void monitor_init(CharDriverState *chr, int flags)
mon->chr = chr;
mon->flags = flags;
if (flags & MONITOR_USE_READLINE) {
- mon->rs = readline_init(mon, monitor_find_completion);
+ mon->rs = readline_init(monitor_readline_printf,
+ monitor_readline_flush,
+ mon,
+ monitor_find_completion);
monitor_read_command(mon, 0);
}
@@ -4920,9 +4943,11 @@ void monitor_init(CharDriverState *chr, int flags)
default_mon = mon;
}
-static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
+static void bdrv_password_cb(void *opaque, const char *password,
+ void *readline_opaque)
{
- BlockDriverState *bs = opaque;
+ Monitor *mon = opaque;
+ BlockDriverState *bs = readline_opaque;
int ret = 0;
if (bdrv_set_key(bs, password) != 0) {
diff --git a/readline.c b/readline.c
index abf27dd..ca894d1 100644
--- a/readline.c
+++ b/readline.c
@@ -21,21 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
+#include "qemu-common.h"
#include "monitor/readline.h"
-#include "monitor/monitor.h"
#define IS_NORM 0
#define IS_ESC 1
#define IS_CSI 2
#define IS_SS3 3
-#undef printf
-#define printf do_not_use_printf
-
void readline_show_prompt(ReadLineState *rs)
{
- monitor_printf(rs->mon, "%s", rs->prompt);
- monitor_flush(rs->mon);
+ rs->printf_func(rs->opaque, "%s", rs->prompt);
+ rs->flush_func(rs->opaque);
rs->last_cmd_buf_index = 0;
rs->last_cmd_buf_size = 0;
rs->esc_state = IS_NORM;
@@ -49,17 +47,17 @@ static void readline_update(ReadLineState *rs)
if (rs->cmd_buf_size != rs->last_cmd_buf_size ||
memcmp(rs->cmd_buf, rs->last_cmd_buf, rs->cmd_buf_size) != 0) {
for(i = 0; i < rs->last_cmd_buf_index; i++) {
- monitor_printf(rs->mon, "\033[D");
+ rs->printf_func(rs->opaque, "\033[D");
}
rs->cmd_buf[rs->cmd_buf_size] = '\0';
if (rs->read_password) {
len = strlen(rs->cmd_buf);
for(i = 0; i < len; i++)
- monitor_printf(rs->mon, "*");
+ rs->printf_func(rs->opaque, "*");
} else {
- monitor_printf(rs->mon, "%s", rs->cmd_buf);
+ rs->printf_func(rs->opaque, "%s", rs->cmd_buf);
}
- monitor_printf(rs->mon, "\033[K");
+ rs->printf_func(rs->opaque, "\033[K");
memcpy(rs->last_cmd_buf, rs->cmd_buf, rs->cmd_buf_size);
rs->last_cmd_buf_size = rs->cmd_buf_size;
rs->last_cmd_buf_index = rs->cmd_buf_size;
@@ -68,17 +66,17 @@ static void readline_update(ReadLineState *rs)
delta = rs->cmd_buf_index - rs->last_cmd_buf_index;
if (delta > 0) {
for(i = 0;i < delta; i++) {
- monitor_printf(rs->mon, "\033[C");
+ rs->printf_func(rs->opaque, "\033[C");
}
} else {
delta = -delta;
for(i = 0;i < delta; i++) {
- monitor_printf(rs->mon, "\033[D");
+ rs->printf_func(rs->opaque, "\033[D");
}
}
rs->last_cmd_buf_index = rs->cmd_buf_index;
}
- monitor_flush(rs->mon);
+ rs->flush_func(rs->opaque);
}
static void readline_insert_char(ReadLineState *rs, int ch)
@@ -284,7 +282,7 @@ static void readline_completion(ReadLineState *rs)
cmdline = g_malloc(rs->cmd_buf_index + 1);
memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index);
cmdline[rs->cmd_buf_index] = '\0';
- rs->completion_finder(rs->mon, cmdline);
+ rs->completion_finder(rs->opaque, cmdline);
g_free(cmdline);
/* no completion found */
@@ -299,7 +297,7 @@ static void readline_completion(ReadLineState *rs)
if (len > 0 && rs->completions[0][len - 1] != '/')
readline_insert_char(rs, ' ');
} else {
- monitor_printf(rs->mon, "\n");
+ rs->printf_func(rs->opaque, "\n");
max_width = 0;
max_prefix = 0;
for(i = 0; i < rs->nb_completions; i++) {
@@ -329,9 +327,9 @@ static void readline_completion(ReadLineState *rs)
nb_cols = 80 / max_width;
j = 0;
for(i = 0; i < rs->nb_completions; i++) {
- monitor_printf(rs->mon, "%-*s", max_width, rs->completions[i]);
+ rs->printf_func(rs->opaque, "%-*s", max_width, rs->completions[i]);
if (++j == nb_cols || i == (rs->nb_completions - 1)) {
- monitor_printf(rs->mon, "\n");
+ rs->printf_func(rs->opaque, "\n");
j = 0;
}
}
@@ -365,12 +363,12 @@ void readline_handle_byte(ReadLineState *rs, int ch)
rs->cmd_buf[rs->cmd_buf_size] = '\0';
if (!rs->read_password)
readline_hist_add(rs, rs->cmd_buf);
- monitor_printf(rs->mon, "\n");
+ rs->printf_func(rs->opaque, "\n");
rs->cmd_buf_index = 0;
rs->cmd_buf_size = 0;
rs->last_cmd_buf_index = 0;
rs->last_cmd_buf_size = 0;
- rs->readline_func(rs->mon, rs->cmd_buf, rs->readline_opaque);
+ rs->readline_func(rs->opaque, rs->cmd_buf, rs->readline_opaque);
break;
case 23:
/* ^W */
@@ -480,13 +478,17 @@ const char *readline_get_history(ReadLineState *rs,
unsigned int index)
return rs->history[index];
}
-ReadLineState *readline_init(Monitor *mon,
+ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
+ ReadLineFlushFunc *flush_func,
+ void *opaque,
ReadLineCompletionFunc *completion_finder)
{
ReadLineState *rs = g_malloc0(sizeof(*rs));
rs->hist_entry = -1;
- rs->mon = mon;
+ rs->opaque = opaque;
+ rs->printf_func = printf_func;
+ rs->flush_func = flush_func;
rs->completion_finder = completion_finder;
return rs;
--
1.8.1.4
- [Qemu-devel] [PULL 03/93] qemu-iotests: Add _unsupported_imgopts for vmdk subformats, (continued)
- [Qemu-devel] [PULL 03/93] qemu-iotests: Add _unsupported_imgopts for vmdk subformats, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 05/93] block/iscsi: return -ENOMEM if an async call fails immediately, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 04/93] qemu-iotests: Clean up all extents for vmdk, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 08/93] gluster: Add support for creating zero-filled image, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 06/93] gluster: Convert aio routines into coroutines, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 09/93] sheepdog: fix clone operation by 'qemu-img create -b', Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 07/93] gluster: Implement .bdrv_co_write_zeroes for gluster, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 10/93] qtest: Fix the bug about disable vnc causes "make check" fail, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 11/93] docs: qcow2 compat=1.1 is now the default, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 12/93] vmdk: Fix big flat extent IO, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 13/93] readline: decouple readline from the monitor,
Kevin Wolf <=
- [Qemu-devel] [PULL 14/93] readline: move readline to a generic location, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 15/93] osdep: add qemu_set_tty_echo(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 16/93] qemu-io: use readline.c, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 17/93] qemu-io: add command completion, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 18/93] blkdebug: Use errp for read_config(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 19/93] blkdebug: Don't require sophisticated filename, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 20/93] qdict: Add qdict_array_split(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 21/93] qapi: extend qdict_flatten() for QLists, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 22/93] qemu-option: Add qemu_config_parse_qdict(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 23/93] blkdebug: Always call read_config(), Kevin Wolf, 2014/01/24