qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/16] QMP queue
@ 2013-08-30 12:22 Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 01/16] monitor: Add missing attributes to local function Luiz Capitulino
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

The following changes since commit b5d54bd42158b90b239bb6ce9c13072eb3a53fd2:

  Merge remote-tracking branch 'qemu-kvm/uq/master' into stable-1.5 (2013-08-29 17:21:51 -0500)

are available in the git repository at:


  git://repo.or.cz/qemu/qmp-unstable.git queue/qmp

for you to fetch changes up to 7ca0e061044615e39eab2b22b8fc2791a4d77c34:

  monitor: improve auto complete of "help" for single command in sub group (2013-08-30 07:41:15 -0400)

----------------------------------------------------------------
Stefan Weil (1):
      monitor: Add missing attributes to local function

Wenchao Xia (15):
      monitor: avoid use of global *cur_mon in cmd_completion()
      monitor: avoid use of global *cur_mon in file_completion()
      monitor: avoid use of global *cur_mon in block_completion_it()
      monitor: avoid use of global *cur_mon in monitor_find_completion()
      monitor: avoid use of global *cur_mon in readline_completion()
      monitor: call sortcmdlist() only one time
      monitor: split off monitor_data_init()
      monitor: avoid direct use of global variable *mon_cmds
      monitor: code move for parse_cmdline()
      monitor: refine parse_cmdline()
      monitor: support sub command in help
      monitor: refine monitor_find_completion()
      monitor: support sub command in auto completion
      monitor: allow "help" show message for single command in sub group
      monitor: improve auto complete of "help" for single command in sub group

 hmp-commands.hx            |   2 +-
 include/monitor/readline.h |   3 +-
 monitor.c                  | 462 +++++++++++++++++++++++++++++----------------
 readline.c                 |   5 +-
 4 files changed, 305 insertions(+), 167 deletions(-)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 01/16] monitor: Add missing attributes to local function
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 02/16] monitor: avoid use of global *cur_mon in cmd_completion() Luiz Capitulino
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Stefan Weil <sw@weilnetz.de>

Function expr_error gets a format string and variable arguments like printf.
It also never returns. Add the necessary attributes.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/monitor.c b/monitor.c
index ee9744c..8c23e29 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3171,7 +3171,8 @@ static const MonitorDef monitor_defs[] = {
     { NULL },
 };
 
-static void expr_error(Monitor *mon, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN
+expr_error(Monitor *mon, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 02/16] monitor: avoid use of global *cur_mon in cmd_completion()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 01/16] monitor: Add missing attributes to local function Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 03/16] monitor: avoid use of global *cur_mon in file_completion() Luiz Capitulino
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

A new local variable *mon is added in monitor_find_completion()
to make compile pass, which will be removed later in
conversion patch for monitor_find_completion().

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/monitor.c b/monitor.c
index 8c23e29..770ab6e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4009,7 +4009,7 @@ out:
     QDECREF(qdict);
 }
 
-static void cmd_completion(const char *name, const char *list)
+static void cmd_completion(Monitor *mon, const char *name, const char *list)
 {
     const char *p, *pstart;
     char cmd[128];
@@ -4027,7 +4027,7 @@ static void cmd_completion(const char *name, const char *list)
         memcpy(cmd, pstart, len);
         cmd[len] = '\0';
         if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
-            readline_add_completion(cur_mon->rs, cmd);
+            readline_add_completion(mon->rs, cmd);
         }
         if (*p == '\0')
             break;
@@ -4141,6 +4141,7 @@ static void monitor_find_completion(const char *cmdline)
     int nb_args, i, len;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
+    Monitor *mon = cur_mon;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4166,7 +4167,7 @@ static void monitor_find_completion(const char *cmdline)
             cmdname = args[0];
         readline_set_completion_index(cur_mon->rs, strlen(cmdname));
         for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-            cmd_completion(cmdname, cmd->name);
+            cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
@@ -4207,7 +4208,7 @@ static void monitor_find_completion(const char *cmdline)
             if (!strcmp(cmd->name, "info")) {
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(str, cmd->name);
+                    cmd_completion(mon, str, cmd->name);
                 }
             } else if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
@@ -4215,12 +4216,12 @@ static void monitor_find_completion(const char *cmdline)
                     str = sep + 1;
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
-                    cmd_completion(str, QKeyCode_lookup[i]);
+                    cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(str, cmd->name);
+                    cmd_completion(mon, str, cmd->name);
                 }
             }
             break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 03/16] monitor: avoid use of global *cur_mon in file_completion()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 01/16] monitor: Add missing attributes to local function Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 02/16] monitor: avoid use of global *cur_mon in cmd_completion() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 04/16] monitor: avoid use of global *cur_mon in block_completion_it() Luiz Capitulino
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 770ab6e..3a0b40c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4035,7 +4035,7 @@ static void cmd_completion(Monitor *mon, const char *name, const char *list)
     }
 }
 
-static void file_completion(const char *input)
+static void file_completion(Monitor *mon, const char *input)
 {
     DIR *ffs;
     struct dirent *d;
@@ -4058,7 +4058,7 @@ static void file_completion(const char *input)
         pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
     }
 #ifdef DEBUG_COMPLETION
-    monitor_printf(cur_mon, "input='%s' path='%s' prefix='%s'\n",
+    monitor_printf(mon, "input='%s' path='%s' prefix='%s'\n",
                    input, path, file_prefix);
 #endif
     ffs = opendir(path);
@@ -4085,7 +4085,7 @@ static void file_completion(const char *input)
             if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
                 pstrcat(file, sizeof(file), "/");
             }
-            readline_add_completion(cur_mon->rs, file);
+            readline_add_completion(mon->rs, file);
         }
     }
     closedir(ffs);
@@ -4196,7 +4196,7 @@ static void monitor_find_completion(const char *cmdline)
         case 'F':
             /* file completion */
             readline_set_completion_index(cur_mon->rs, strlen(str));
-            file_completion(str);
+            file_completion(mon, str);
             break;
         case 'B':
             /* block device name completion */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 04/16] monitor: avoid use of global *cur_mon in block_completion_it()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (2 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 03/16] monitor: avoid use of global *cur_mon in file_completion() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 05/16] monitor: avoid use of global *cur_mon in monitor_find_completion() Luiz Capitulino
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 3a0b40c..d01aa62 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4091,14 +4091,21 @@ static void file_completion(Monitor *mon, const char *input)
     closedir(ffs);
 }
 
+typedef struct MonitorBlockComplete {
+    Monitor *mon;
+    const char *input;
+} MonitorBlockComplete;
+
 static void block_completion_it(void *opaque, BlockDriverState *bs)
 {
     const char *name = bdrv_get_device_name(bs);
-    const char *input = opaque;
+    MonitorBlockComplete *mbc = opaque;
+    Monitor *mon = mbc->mon;
+    const char *input = mbc->input;
 
     if (input[0] == '\0' ||
         !strncmp(name, (char *)input, strlen(input))) {
-        readline_add_completion(cur_mon->rs, name);
+        readline_add_completion(mon->rs, name);
     }
 }
 
@@ -4142,6 +4149,7 @@ static void monitor_find_completion(const char *cmdline)
     const char *ptype, *str;
     const mon_cmd_t *cmd;
     Monitor *mon = cur_mon;
+    MonitorBlockComplete mbs;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4200,8 +4208,10 @@ static void monitor_find_completion(const char *cmdline)
             break;
         case 'B':
             /* block device name completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
-            bdrv_iterate(block_completion_it, (void *)str);
+            mbs.mon = mon;
+            mbs.input = str;
+            readline_set_completion_index(mon->rs, strlen(str));
+            bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
             /* XXX: more generic ? */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 05/16] monitor: avoid use of global *cur_mon in monitor_find_completion()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (3 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 04/16] monitor: avoid use of global *cur_mon in block_completion_it() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 06/16] monitor: avoid use of global *cur_mon in readline_completion() Luiz Capitulino
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Parameter *mon is added, and local variable *mon added in previous patch
is removed. The caller readline_completion(), pass rs->mon as value, which
should be initialized in readline_init() called by monitor_init().

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 include/monitor/readline.h |  3 ++-
 monitor.c                  | 18 +++++++++---------
 readline.c                 |  2 +-
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/include/monitor/readline.h b/include/monitor/readline.h
index fc9806e..0faf6e1 100644
--- a/include/monitor/readline.h
+++ b/include/monitor/readline.h
@@ -8,7 +8,8 @@
 #define READLINE_MAX_COMPLETIONS 256
 
 typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque);
-typedef void ReadLineCompletionFunc(const char *cmdline);
+typedef void ReadLineCompletionFunc(Monitor *mon,
+                                    const char *cmdline);
 
 typedef struct ReadLineState {
     char cmd_buf[READLINE_CMD_BUF_SIZE + 1];
diff --git a/monitor.c b/monitor.c
index d01aa62..b8f79a5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4141,20 +4141,20 @@ static const char *next_arg_type(const char *typestr)
     return (p != NULL ? ++p : typestr);
 }
 
-static void monitor_find_completion(const char *cmdline)
+static void monitor_find_completion(Monitor *mon,
+                                    const char *cmdline)
 {
     const char *cmdname;
     char *args[MAX_ARGS];
     int nb_args, i, len;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
-    Monitor *mon = cur_mon;
     MonitorBlockComplete mbs;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
-    for(i = 0; i < nb_args; i++) {
-        monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]);
+    for (i = 0; i < nb_args; i++) {
+        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
     }
 #endif
 
@@ -4173,7 +4173,7 @@ static void monitor_find_completion(const char *cmdline)
             cmdname = "";
         else
             cmdname = args[0];
-        readline_set_completion_index(cur_mon->rs, strlen(cmdname));
+        readline_set_completion_index(mon->rs, strlen(cmdname));
         for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
@@ -4203,7 +4203,7 @@ static void monitor_find_completion(const char *cmdline)
         switch(*ptype) {
         case 'F':
             /* file completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
+            readline_set_completion_index(mon->rs, strlen(str));
             file_completion(mon, str);
             break;
         case 'B':
@@ -4216,7 +4216,7 @@ static void monitor_find_completion(const char *cmdline)
         case 's':
             /* XXX: more generic ? */
             if (!strcmp(cmd->name, "info")) {
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
@@ -4224,12 +4224,12 @@ static void monitor_find_completion(const char *cmdline)
                 char *sep = strrchr(str, '-');
                 if (sep)
                     str = sep + 1;
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
                     cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
diff --git a/readline.c b/readline.c
index 1c0f7ee..c91b324 100644
--- a/readline.c
+++ b/readline.c
@@ -285,7 +285,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(cmdline);
+    rs->completion_finder(rs->mon, cmdline);
     g_free(cmdline);
 
     /* no completion found */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 06/16] monitor: avoid use of global *cur_mon in readline_completion()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (4 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 05/16] monitor: avoid use of global *cur_mon in monitor_find_completion() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 07/16] monitor: call sortcmdlist() only one time Luiz Capitulino
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Now all completion functions do not use *cur_mon any more, instead
they use rs->mon. In short, structure ReadLineState decide where
the complete action would be taken now.

Tested with the case that qemu have two telnet monitors, auto
completion function works normal.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 readline.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/readline.c b/readline.c
index c91b324..abf27dd 100644
--- a/readline.c
+++ b/readline.c
@@ -276,7 +276,6 @@ void readline_set_completion_index(ReadLineState *rs, int index)
 
 static void readline_completion(ReadLineState *rs)
 {
-    Monitor *mon = cur_mon;
     int len, i, j, max_width, nb_cols, max_prefix;
     char *cmdline;
 
@@ -300,7 +299,7 @@ static void readline_completion(ReadLineState *rs)
         if (len > 0 && rs->completions[0][len - 1] != '/')
             readline_insert_char(rs, ' ');
     } else {
-        monitor_printf(mon, "\n");
+        monitor_printf(rs->mon, "\n");
         max_width = 0;
         max_prefix = 0;	
         for(i = 0; i < rs->nb_completions; i++) {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 07/16] monitor: call sortcmdlist() only one time
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (5 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 06/16] monitor: avoid use of global *cur_mon in readline_completion() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 08/16] monitor: split off monitor_data_init() Luiz Capitulino
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

It doesn't need to be done for every monitor, so change it.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/monitor.c b/monitor.c
index b8f79a5..457948d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4763,6 +4763,7 @@ void monitor_init(CharDriverState *chr, int flags)
 
     if (is_first_init) {
         monitor_protocol_event_init();
+        sortcmdlist();
         is_first_init = 0;
     }
 
@@ -4792,8 +4793,6 @@ void monitor_init(CharDriverState *chr, int flags)
     QLIST_INSERT_HEAD(&mon_list, mon, entry);
     if (!default_mon || (flags & MONITOR_IS_DEFAULT))
         default_mon = mon;
-
-    sortcmdlist();
 }
 
 static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 08/16] monitor: split off monitor_data_init()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (6 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 07/16] monitor: call sortcmdlist() only one time Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 09/16] monitor: avoid direct use of global variable *mon_cmds Luiz Capitulino
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

In qmp_human_monitor_command(), the monitor need to initialized for
basic functionalities, and later more init code will be added, so
split off this function. Note that it is different with QMP mode
monitor which accept json string from monitor's input,
qmp_human_monitor_command() retrieve the human style command from
QMP input, then send the command to a normal mode monitor.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 457948d..1f645e1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -683,14 +683,24 @@ static int do_qmp_capabilities(Monitor *mon, const QDict *params,
 
 static void handle_user_command(Monitor *mon, const char *cmdline);
 
+static void monitor_data_init(Monitor *mon)
+{
+    memset(mon, 0, sizeof(Monitor));
+    mon->outbuf = qstring_new();
+}
+
+static void monitor_data_destroy(Monitor *mon)
+{
+    QDECREF(mon->outbuf);
+}
+
 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
                                 int64_t cpu_index, Error **errp)
 {
     char *output = NULL;
     Monitor *old_mon, hmp;
 
-    memset(&hmp, 0, sizeof(hmp));
-    hmp.outbuf = qstring_new();
+    monitor_data_init(&hmp);
     hmp.skip_flush = true;
 
     old_mon = cur_mon;
@@ -716,7 +726,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
     }
 
 out:
-    QDECREF(hmp.outbuf);
+    monitor_data_destroy(&hmp);
     return output;
 }
 
@@ -4767,8 +4777,8 @@ void monitor_init(CharDriverState *chr, int flags)
         is_first_init = 0;
     }
 
-    mon = g_malloc0(sizeof(*mon));
-    mon->outbuf = qstring_new();
+    mon = g_malloc(sizeof(*mon));
+    monitor_data_init(mon);
 
     mon->chr = chr;
     mon->flags = flags;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 09/16] monitor: avoid direct use of global variable *mon_cmds
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (7 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 08/16] monitor: split off monitor_data_init() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 10/16] monitor: code move for parse_cmdline() Luiz Capitulino
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

New member *cmd_table is added in structure Monitor to avoid direct usage of
*mon_cmds. Now monitor have an associated command table, when global variable
*info_cmds is also discarded, structure Monitor would gain full control about
how to deal with user input.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 1f645e1..ce2a1ee 100644
--- a/monitor.c
+++ b/monitor.c
@@ -195,6 +195,7 @@ struct Monitor {
     CPUState *mon_cpu;
     BlockDriverCompletionFunc *password_completion_cb;
     void *password_opaque;
+    mon_cmd_t *cmd_table;
     QError *error;
     QLIST_HEAD(,mon_fd_t) fds;
     QLIST_ENTRY(Monitor) entry;
@@ -687,6 +688,8 @@ static void monitor_data_init(Monitor *mon)
 {
     memset(mon, 0, sizeof(Monitor));
     mon->outbuf = qstring_new();
+    /* Use *mon_cmds by default. */
+    mon->cmd_table = mon_cmds;
 }
 
 static void monitor_data_destroy(Monitor *mon)
@@ -767,7 +770,7 @@ static void help_cmd(Monitor *mon, const char *name)
     if (name && !strcmp(name, "info")) {
         help_cmd_dump(mon, info_cmds, "info ", NULL);
     } else {
-        help_cmd_dump(mon, mon_cmds, "", name);
+        help_cmd_dump(mon, mon->cmd_table, "", name);
         if (name && !strcmp(name, "log")) {
             const QEMULogItem *item;
             monitor_printf(mon, "Log items (comma separated):\n");
@@ -3995,7 +3998,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
 
     qdict = qdict_new();
 
-    cmd = monitor_parse_command(mon, cmdline, 0, mon_cmds, qdict);
+    cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
     if (!cmd)
         goto out;
 
@@ -4184,12 +4187,12 @@ static void monitor_find_completion(Monitor *mon,
         else
             cmdname = args[0];
         readline_set_completion_index(mon->rs, strlen(cmdname));
-        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
+        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
-        for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
             if (compare_cmd(args[0], cmd->name)) {
                 break;
             }
@@ -4240,7 +4243,7 @@ static void monitor_find_completion(Monitor *mon,
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+                for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
             }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 10/16] monitor: code move for parse_cmdline()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (8 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 09/16] monitor: avoid direct use of global variable *mon_cmds Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 11/16] monitor: refine parse_cmdline() Luiz Capitulino
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

help_cmd() need this function later, so move it. get_str() is called by
parse_cmdline() so it is moved also. Some code style error reported by
check script, is also fixed.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 191 ++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 98 insertions(+), 93 deletions(-)

diff --git a/monitor.c b/monitor.c
index ce2a1ee..7612147 100644
--- a/monitor.c
+++ b/monitor.c
@@ -753,6 +753,104 @@ static int compare_cmd(const char *name, const char *list)
     return 0;
 }
 
+static int get_str(char *buf, int buf_size, const char **pp)
+{
+    const char *p;
+    char *q;
+    int c;
+
+    q = buf;
+    p = *pp;
+    while (qemu_isspace(*p)) {
+        p++;
+    }
+    if (*p == '\0') {
+    fail:
+        *q = '\0';
+        *pp = p;
+        return -1;
+    }
+    if (*p == '\"') {
+        p++;
+        while (*p != '\0' && *p != '\"') {
+            if (*p == '\\') {
+                p++;
+                c = *p++;
+                switch (c) {
+                case 'n':
+                    c = '\n';
+                    break;
+                case 'r':
+                    c = '\r';
+                    break;
+                case '\\':
+                case '\'':
+                case '\"':
+                    break;
+                default:
+                    qemu_printf("unsupported escape code: '\\%c'\n", c);
+                    goto fail;
+                }
+                if ((q - buf) < buf_size - 1) {
+                    *q++ = c;
+                }
+            } else {
+                if ((q - buf) < buf_size - 1) {
+                    *q++ = *p;
+                }
+                p++;
+            }
+        }
+        if (*p != '\"') {
+            qemu_printf("unterminated string\n");
+            goto fail;
+        }
+        p++;
+    } else {
+        while (*p != '\0' && !qemu_isspace(*p)) {
+            if ((q - buf) < buf_size - 1) {
+                *q++ = *p;
+            }
+            p++;
+        }
+    }
+    *q = '\0';
+    *pp = p;
+    return 0;
+}
+
+#define MAX_ARGS 16
+
+/* NOTE: this parser is an approximate form of the real command parser */
+static void parse_cmdline(const char *cmdline,
+                          int *pnb_args, char **args)
+{
+    const char *p;
+    int nb_args, ret;
+    char buf[1024];
+
+    p = cmdline;
+    nb_args = 0;
+    for (;;) {
+        while (qemu_isspace(*p)) {
+            p++;
+        }
+        if (*p == '\0') {
+            break;
+        }
+        if (nb_args >= MAX_ARGS) {
+            break;
+        }
+        ret = get_str(buf, sizeof(buf), &p);
+        args[nb_args] = g_strdup(buf);
+        nb_args++;
+        if (ret < 0) {
+            break;
+        }
+    }
+    *pnb_args = nb_args;
+}
+
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
                           const char *prefix, const char *name)
 {
@@ -3434,71 +3532,6 @@ static int get_double(Monitor *mon, double *pval, const char **pp)
     return 0;
 }
 
-static int get_str(char *buf, int buf_size, const char **pp)
-{
-    const char *p;
-    char *q;
-    int c;
-
-    q = buf;
-    p = *pp;
-    while (qemu_isspace(*p))
-        p++;
-    if (*p == '\0') {
-    fail:
-        *q = '\0';
-        *pp = p;
-        return -1;
-    }
-    if (*p == '\"') {
-        p++;
-        while (*p != '\0' && *p != '\"') {
-            if (*p == '\\') {
-                p++;
-                c = *p++;
-                switch(c) {
-                case 'n':
-                    c = '\n';
-                    break;
-                case 'r':
-                    c = '\r';
-                    break;
-                case '\\':
-                case '\'':
-                case '\"':
-                    break;
-                default:
-                    qemu_printf("unsupported escape code: '\\%c'\n", c);
-                    goto fail;
-                }
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = c;
-                }
-            } else {
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = *p;
-                }
-                p++;
-            }
-        }
-        if (*p != '\"') {
-            qemu_printf("unterminated string\n");
-            goto fail;
-        }
-        p++;
-    } else {
-        while (*p != '\0' && !qemu_isspace(*p)) {
-            if ((q - buf) < buf_size - 1) {
-                *q++ = *p;
-            }
-            p++;
-        }
-    }
-    *q = '\0';
-    *pp = p;
-    return 0;
-}
-
 /*
  * Store the command-name in cmdname, and return a pointer to
  * the remaining of the command string.
@@ -3555,8 +3588,6 @@ static char *key_get_info(const char *type, char **key)
 static int default_fmt_format = 'x';
 static int default_fmt_size = 4;
 
-#define MAX_ARGS 16
-
 static int is_valid_option(const char *c, const char *typestr)
 {
     char option[3];
@@ -4122,32 +4153,6 @@ static void block_completion_it(void *opaque, BlockDriverState *bs)
     }
 }
 
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
-                         int *pnb_args, char **args)
-{
-    const char *p;
-    int nb_args, ret;
-    char buf[1024];
-
-    p = cmdline;
-    nb_args = 0;
-    for(;;) {
-        while (qemu_isspace(*p))
-            p++;
-        if (*p == '\0')
-            break;
-        if (nb_args >= MAX_ARGS)
-            break;
-        ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = g_strdup(buf);
-        nb_args++;
-        if (ret < 0)
-            break;
-    }
-    *pnb_args = nb_args;
-}
-
 static const char *next_arg_type(const char *typestr)
 {
     const char *p = strchr(typestr, ':');
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 11/16] monitor: refine parse_cmdline()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (9 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 10/16] monitor: code move for parse_cmdline() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 12/16] monitor: support sub command in help Luiz Capitulino
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Since this function will be used by help_cmd() later, so improve
it to make it more generic and easier to use. free_cmdline_args()
is added too as paired function to free the result.

One change of this function is that, when the valid args in input
exceed the limit of MAX_ARGS, it fails now, instead of return with
MAX_ARGS of parsed args in old code. This should not impact much
since it is rare that user input many args in monitor's "help" and
auto complete scenario.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 51 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/monitor.c b/monitor.c
index 7612147..aae1bab 100644
--- a/monitor.c
+++ b/monitor.c
@@ -821,9 +821,33 @@ static int get_str(char *buf, int buf_size, const char **pp)
 
 #define MAX_ARGS 16
 
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
-                          int *pnb_args, char **args)
+static void free_cmdline_args(char **args, int nb_args)
+{
+    int i;
+
+    assert(nb_args <= MAX_ARGS);
+
+    for (i = 0; i < nb_args; i++) {
+        g_free(args[i]);
+    }
+
+}
+
+/*
+ * Parse the command line to get valid args.
+ * @cmdline: command line to be parsed.
+ * @pnb_args: location to store the number of args, must NOT be NULL.
+ * @args: location to store the args, which should be freed by caller, must
+ *        NOT be NULL.
+ *
+ * Returns 0 on success, negative on failure.
+ *
+ * NOTE: this parser is an approximate form of the real command parser. Number
+ *       of args have a limit of MAX_ARGS. If cmdline contains more, it will
+ *       return with failure.
+ */
+static int parse_cmdline(const char *cmdline,
+                         int *pnb_args, char **args)
 {
     const char *p;
     int nb_args, ret;
@@ -839,16 +863,21 @@ static void parse_cmdline(const char *cmdline,
             break;
         }
         if (nb_args >= MAX_ARGS) {
-            break;
+            goto fail;
         }
         ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = g_strdup(buf);
-        nb_args++;
         if (ret < 0) {
-            break;
+            goto fail;
         }
+        args[nb_args] = g_strdup(buf);
+        nb_args++;
     }
     *pnb_args = nb_args;
+    return 0;
+
+ fail:
+    free_cmdline_args(args, nb_args);
+    return -1;
 }
 
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
@@ -4169,7 +4198,9 @@ static void monitor_find_completion(Monitor *mon,
     const mon_cmd_t *cmd;
     MonitorBlockComplete mbs;
 
-    parse_cmdline(cmdline, &nb_args, args);
+    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
+        return;
+    }
 #ifdef DEBUG_COMPLETION
     for (i = 0; i < nb_args; i++) {
         monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
@@ -4259,9 +4290,7 @@ static void monitor_find_completion(Monitor *mon,
     }
 
 cleanup:
-    for (i = 0; i < nb_args; i++) {
-        g_free(args[i]);
-    }
+    free_cmdline_args(args, nb_args);
 }
 
 static int monitor_can_read(void *opaque)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 12/16] monitor: support sub command in help
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (10 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 11/16] monitor: refine parse_cmdline() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 13/16] monitor: refine monitor_find_completion() Luiz Capitulino
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

The old code in help_cmd() uses global 'info_cmds' and treats it as a
special case. Actually 'info_cmds' is a sub command group of 'mon_cmds',
in order to avoid direct use of it, help_cmd() needs to change its work
mechanism to support sub command and not treat it as a special case
any more.

To support sub command, help_cmd() will first parse the input and then call
help_cmd_dump(), which works as a reentrant function. When it meets a sub
command, it simply enters the function again. Since help dumping needs to
know whole input to printf full help message include prefix, for example,
"help info block" need to printf prefix "info", so help_cmd_dump() takes all
args from input and extra parameter arg_index to identify the progress.
Another function help_cmd_dump_one() is introduced to printf the prefix
and command's help message.

Now help supports sub command, so later if another sub command group is
added in any depth, help will automatically work for it. Still "help info
block" will show error since command parser reject additional parameter,
which can be improved later. "log" is still treated as a special case.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 52 insertions(+), 10 deletions(-)

diff --git a/monitor.c b/monitor.c
index aae1bab..39c8753 100644
--- a/monitor.c
+++ b/monitor.c
@@ -880,33 +880,75 @@ static int parse_cmdline(const char *cmdline,
     return -1;
 }
 
+static void help_cmd_dump_one(Monitor *mon,
+                              const mon_cmd_t *cmd,
+                              char **prefix_args,
+                              int prefix_args_nb)
+{
+    int i;
+
+    for (i = 0; i < prefix_args_nb; i++) {
+        monitor_printf(mon, "%s ", prefix_args[i]);
+    }
+    monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
+}
+
+/* @args[@arg_index] is the valid command need to find in @cmds */
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
-                          const char *prefix, const char *name)
+                          char **args, int nb_args, int arg_index)
 {
     const mon_cmd_t *cmd;
 
-    for(cmd = cmds; cmd->name != NULL; cmd++) {
-        if (!name || !strcmp(name, cmd->name))
-            monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name,
-                           cmd->params, cmd->help);
+    /* No valid arg need to compare with, dump all in *cmds */
+    if (arg_index >= nb_args) {
+        for (cmd = cmds; cmd->name != NULL; cmd++) {
+            help_cmd_dump_one(mon, cmd, args, arg_index);
+        }
+        return;
+    }
+
+    /* Find one entry to dump */
+    for (cmd = cmds; cmd->name != NULL; cmd++) {
+        if (compare_cmd(args[arg_index], cmd->name)) {
+            if (cmd->sub_table) {
+                /* continue with next arg */
+                help_cmd_dump(mon, cmd->sub_table,
+                              args, nb_args, arg_index + 1);
+            } else {
+                help_cmd_dump_one(mon, cmd, args, arg_index);
+            }
+            break;
+        }
     }
 }
 
 static void help_cmd(Monitor *mon, const char *name)
 {
-    if (name && !strcmp(name, "info")) {
-        help_cmd_dump(mon, info_cmds, "info ", NULL);
-    } else {
-        help_cmd_dump(mon, mon->cmd_table, "", name);
-        if (name && !strcmp(name, "log")) {
+    char *args[MAX_ARGS];
+    int nb_args = 0;
+
+    /* 1. parse user input */
+    if (name) {
+        /* special case for log, directly dump and return */
+        if (!strcmp(name, "log")) {
             const QEMULogItem *item;
             monitor_printf(mon, "Log items (comma separated):\n");
             monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
             for (item = qemu_log_items; item->mask != 0; item++) {
                 monitor_printf(mon, "%-10s %s\n", item->name, item->help);
             }
+            return;
+        }
+
+        if (parse_cmdline(name, &nb_args, args) < 0) {
+            return;
         }
     }
+
+    /* 2. dump the contents according to parsed args */
+    help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0);
+
+    free_cmdline_args(args, nb_args);
 }
 
 static void do_help_cmd(Monitor *mon, const QDict *qdict)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 13/16] monitor: refine monitor_find_completion()
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (11 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 12/16] monitor: support sub command in help Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 14/16] monitor: support sub command in auto completion Luiz Capitulino
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

In order to support sub command in auto completion, a reentrant function
is needed, so monitor_find_completion() is split into two parts. The
first part does parsing of user input which need to be done only once,
the second part does the auto completion job according to the parsing
result, which contains the necessary code to support sub command and
works as the reentrant function. The global "info_cmds" is still used
in second part, which will be replaced by sub command code later.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 65 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/monitor.c b/monitor.c
index 39c8753..424d30c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4230,34 +4230,17 @@ static const char *next_arg_type(const char *typestr)
     return (p != NULL ? ++p : typestr);
 }
 
-static void monitor_find_completion(Monitor *mon,
-                                    const char *cmdline)
+static void monitor_find_completion_by_table(Monitor *mon,
+                                             const mon_cmd_t *cmd_table,
+                                             char **args,
+                                             int nb_args)
 {
     const char *cmdname;
-    char *args[MAX_ARGS];
-    int nb_args, i, len;
+    int i;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
     MonitorBlockComplete mbs;
 
-    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
-        return;
-    }
-#ifdef DEBUG_COMPLETION
-    for (i = 0; i < nb_args; i++) {
-        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
-    }
-#endif
-
-    /* if the line ends with a space, it means we want to complete the
-       next arg */
-    len = strlen(cmdline);
-    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
-        if (nb_args >= MAX_ARGS) {
-            goto cleanup;
-        }
-        args[nb_args++] = g_strdup("");
-    }
     if (nb_args <= 1) {
         /* command completion */
         if (nb_args == 0)
@@ -4265,18 +4248,18 @@ static void monitor_find_completion(Monitor *mon,
         else
             cmdname = args[0];
         readline_set_completion_index(mon->rs, strlen(cmdname));
-        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+        for (cmd = cmd_table; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
-        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+        for (cmd = cmd_table; cmd->name != NULL; cmd++) {
             if (compare_cmd(args[0], cmd->name)) {
                 break;
             }
         }
         if (!cmd->name) {
-            goto cleanup;
+            return;
         }
 
         ptype = next_arg_type(cmd->args_type);
@@ -4321,7 +4304,7 @@ static void monitor_find_completion(Monitor *mon,
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+                for (cmd = cmd_table; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
             }
@@ -4330,6 +4313,36 @@ static void monitor_find_completion(Monitor *mon,
             break;
         }
     }
+}
+
+static void monitor_find_completion(Monitor *mon,
+                                    const char *cmdline)
+{
+    char *args[MAX_ARGS];
+    int nb_args, len;
+
+    /* 1. parse the cmdline */
+    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
+        return;
+    }
+#ifdef DEBUG_COMPLETION
+    for (i = 0; i < nb_args; i++) {
+        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
+    }
+#endif
+
+    /* if the line ends with a space, it means we want to complete the
+       next arg */
+    len = strlen(cmdline);
+    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
+        if (nb_args >= MAX_ARGS) {
+            goto cleanup;
+        }
+        args[nb_args++] = g_strdup("");
+    }
+
+    /* 2. auto complete according to args */
+    monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);
 
 cleanup:
     free_cmdline_args(args, nb_args);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 14/16] monitor: support sub command in auto completion
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (12 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 13/16] monitor: refine monitor_find_completion() Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 15/16] monitor: allow "help" show message for single command in sub group Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 16/16] monitor: improve auto complete of "help" " Luiz Capitulino
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

This patch allows auto completion work normal for sub command case,
"info block [DEVICE]" can auto complete now, by re-enter the completion
function. In original code "info" is treated as a special case, now it
is treated as a sub command group, global variable info_cmds is not used
any more.

"help" command is still treated as a special case, since it is not a sub
command group but want to auto complete command in root command table.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/monitor.c b/monitor.c
index 424d30c..c44c711 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4262,6 +4262,12 @@ static void monitor_find_completion_by_table(Monitor *mon,
             return;
         }
 
+        if (cmd->sub_table) {
+            /* do the job again */
+            return monitor_find_completion_by_table(mon, cmd->sub_table,
+                                                    &args[1], nb_args - 1);
+        }
+
         ptype = next_arg_type(cmd->args_type);
         for(i = 0; i < nb_args - 2; i++) {
             if (*ptype != '\0') {
@@ -4288,13 +4294,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
             bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
-            /* XXX: more generic ? */
-            if (!strcmp(cmd->name, "info")) {
-                readline_set_completion_index(mon->rs, strlen(str));
-                for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(mon, str, cmd->name);
-                }
-            } else if (!strcmp(cmd->name, "sendkey")) {
+            if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
                 if (sep)
                     str = sep + 1;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 15/16] monitor: allow "help" show message for single command in sub group
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (13 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 14/16] monitor: support sub command in auto completion Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  2013-08-30 12:22 ` [Qemu-devel] [PULL 16/16] monitor: improve auto complete of "help" " Luiz Capitulino
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

A new parameter type 'S' is introduced to allow user input any string.
"help info block" works normal now.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hmp-commands.hx |  2 +-
 monitor.c       | 27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8c6b91a..c161fe9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -11,7 +11,7 @@ ETEXI
 
     {
         .name       = "help|?",
-        .args_type  = "name:s?",
+        .args_type  = "name:S?",
         .params     = "[cmd]",
         .help       = "show the help",
         .mhandler.cmd = do_help_cmd,
diff --git a/monitor.c b/monitor.c
index c44c711..721c74d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -83,6 +83,7 @@
  * 'F'          filename
  * 'B'          block device name
  * 's'          string (accept optional quote)
+ * 'S'          it just appends the rest of the string (accept optional quote)
  * 'O'          option string of the form NAME=VALUE,...
  *              parsed according to QemuOptsList given by its name
  *              Example: 'device:O' uses qemu_device_opts.
@@ -4047,6 +4048,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
                 }
             }
             break;
+        case 'S':
+            {
+                /* package all remaining string */
+                int len;
+
+                while (qemu_isspace(*p)) {
+                    p++;
+                }
+                if (*typestr == '?') {
+                    typestr++;
+                    if (*p == '\0') {
+                        /* no remaining string: NULL argument */
+                        break;
+                    }
+                }
+                len = strlen(p);
+                if (len <= 0) {
+                    monitor_printf(mon, "%s: string expected\n",
+                                   cmdname);
+                    break;
+                }
+                qdict_put(qdict, key, qstring_from_str(p));
+                p += len;
+            }
+            break;
         default:
         bad_type:
             monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
@@ -4294,6 +4320,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
             bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
+        case 'S':
             if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
                 if (sep)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PULL 16/16] monitor: improve auto complete of "help" for single command in sub group
  2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
                   ` (14 preceding siblings ...)
  2013-08-30 12:22 ` [Qemu-devel] [PULL 15/16] monitor: allow "help" show message for single command in sub group Luiz Capitulino
@ 2013-08-30 12:22 ` Luiz Capitulino
  15 siblings, 0 replies; 17+ messages in thread
From: Luiz Capitulino @ 2013-08-30 12:22 UTC (permalink / raw)
  To: anthony; +Cc: qemu-devel

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>

Now special case "help *" in auto completion can work with sub commands,
such as "help info u*".

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 721c74d..0aeaf6c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4330,10 +4330,8 @@ static void monitor_find_completion_by_table(Monitor *mon,
                     cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
-                readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = cmd_table; cmd->name != NULL; cmd++) {
-                    cmd_completion(mon, str, cmd->name);
-                }
+                monitor_find_completion_by_table(mon, cmd_table,
+                                                 &args[1], nb_args - 1);
             }
             break;
         default:
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-08-30 12:23 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-30 12:22 [Qemu-devel] [PULL 00/16] QMP queue Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 01/16] monitor: Add missing attributes to local function Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 02/16] monitor: avoid use of global *cur_mon in cmd_completion() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 03/16] monitor: avoid use of global *cur_mon in file_completion() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 04/16] monitor: avoid use of global *cur_mon in block_completion_it() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 05/16] monitor: avoid use of global *cur_mon in monitor_find_completion() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 06/16] monitor: avoid use of global *cur_mon in readline_completion() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 07/16] monitor: call sortcmdlist() only one time Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 08/16] monitor: split off monitor_data_init() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 09/16] monitor: avoid direct use of global variable *mon_cmds Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 10/16] monitor: code move for parse_cmdline() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 11/16] monitor: refine parse_cmdline() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 12/16] monitor: support sub command in help Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 13/16] monitor: refine monitor_find_completion() Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 14/16] monitor: support sub command in auto completion Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 15/16] monitor: allow "help" show message for single command in sub group Luiz Capitulino
2013-08-30 12:22 ` [Qemu-devel] [PULL 16/16] monitor: improve auto complete of "help" " Luiz Capitulino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).