All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	berrange@redhat.com, qemu-devel@nongnu.org,
	qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3 11/15] monitor: Split out monitor/hmp.c
Date: Fri, 14 Jun 2019 10:17:35 +0100	[thread overview]
Message-ID: <20190614091733.GA2785@work-vm> (raw)
In-Reply-To: <87y324fud1.fsf@dusky.pond.sub.org>

* Markus Armbruster (armbru@redhat.com) wrote:
> Kevin Wolf <kwolf@redhat.com> writes:
> 
> > Move HMP infrastructure from monitor/misc.c to monitor/hmp.c. This is
> > code that can be shared for all targets, so compile it only once.
> >
> > The amount of function and particularly extern variables in
> > monitor_int.h is probably a bit larger than it needs to be, but this way
> > no non-trivial code modifications are needed. The interfaces between HMP
> > and the monitor core can be cleaned up later.
> >
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > ---
> [...]
> > diff --git a/monitor/hmp.c b/monitor/hmp.c
> > new file mode 100644
> > index 0000000000..3621b195ed
> > --- /dev/null
> > +++ b/monitor/hmp.c
> > @@ -0,0 +1,1415 @@
> [...]
> > +static int64_t expr_unary(Monitor *mon)
> > +{
> > +    int64_t n;
> > +    char *p;
> > +    int ret;
> > +
> > +    switch (*pch) {
> > +    case '+':
> > +        next();
> > +        n = expr_unary(mon);
> > +        break;
> > +    case '-':
> > +        next();
> > +        n = -expr_unary(mon);
> > +        break;
> > +    case '~':
> > +        next();
> > +        n = ~expr_unary(mon);
> > +        break;
> > +    case '(':
> > +        next();
> > +        n = expr_sum(mon);
> > +        if (*pch != ')') {
> > +            expr_error(mon, "')' expected");
> > +        }
> > +        next();
> > +        break;
> > +    case '\'':
> > +        pch++;
> > +        if (*pch == '\0') {
> > +            expr_error(mon, "character constant expected");
> > +        }
> > +        n = *pch;
> > +        pch++;
> > +        if (*pch != '\'') {
> > +            expr_error(mon, "missing terminating \' character");
> > +        }
> > +        next();
> > +        break;
> > +    case '$':
> > +        {
> > +            char buf[128], *q;
> > +            int64_t reg = 0;
> > +
> > +            pch++;
> > +            q = buf;
> > +            while ((*pch >= 'a' && *pch <= 'z') ||
> > +                   (*pch >= 'A' && *pch <= 'Z') ||
> > +                   (*pch >= '0' && *pch <= '9') ||
> > +                   *pch == '_' || *pch == '.') {
> > +                if ((q - buf) < sizeof(buf) - 1) {
> > +                    *q++ = *pch;
> > +                }
> > +                pch++;
> > +            }
> > +            while (qemu_isspace(*pch)) {
> > +                pch++;
> > +            }
> > +            *q = 0;
> > +            ret = get_monitor_def(&reg, buf);
> > +            if (ret < 0) {
> > +                expr_error(mon, "unknown register");
> > +            }
> > +            n = reg;
> > +        }
> > +        break;
> > +    case '\0':
> > +        expr_error(mon, "unexpected end of expression");
> > +        n = 0;
> > +        break;
> > +    default:
> > +        errno = 0;
> > +        n = strtoull(pch, &p, 0);
> 
> checkpatch.pl gripes:
> 
>     ERROR: consider using qemu_strtoull in preference to strtoull
> 
> 
> Let's add a TODO comment.  
> 
> > +        if (errno == ERANGE) {
> > +            expr_error(mon, "number too large");
> > +        }
> > +        if (pch == p) {
> > +            expr_error(mon, "invalid char '%c' in expression", *p);
> > +        }
> > +        pch = p;
> > +        while (qemu_isspace(*pch)) {
> > +            pch++;
> > +        }
> > +        break;
> > +    }
> > +    return n;
> > +}
> [...]
> > +static void monitor_find_completion(void *opaque,
> > +                                    const char *cmdline)
> > +{
> > +    MonitorHMP *mon = opaque;
> > +    char *args[MAX_ARGS];
> > +    int nb_args, len;
> > +
> > +    /* 1. parse the cmdline */
> > +    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
> > +        return;
> > +    }
> > +
> > +    /* if the line ends with a space, it means we want to complete the
> > +     * next arg */
> 
> checkpatch.pl again:
> 
>     WARNING: Block comments use a leading /* on a separate line
>     WARNING: Block comments use a trailing */ on a separate line
> 
> Can touch up in my tree.

I wouldn't worry too much about fixing the existing problems here -
let's get the reorg done through kwolf's patches and then it's easier
to clean up later.

Dave

> > +    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, hmp_cmds, args, nb_args);
> > +
> > +cleanup:
> > +    free_cmdline_args(args, nb_args);
> > +}
> [...]
> > diff --git a/monitor/misc.c b/monitor/misc.c
> > index 368b8297d4..c8289959c0 100644
> > --- a/monitor/misc.c
> > +++ b/monitor/misc.c
> [...]
> > @@ -612,245 +580,27 @@ out:
> >      return output;
> >  }
> >  
> > -static int compare_cmd(const char *name, const char *list)
> > +/**
> > + * Is @name in the '|' separated list of names @list?
> > + */
> > +int hmp_compare_cmd(const char *name, const char *list)
> >  {
> >      const char *p, *pstart;
> >      int len;
> >      len = strlen(name);
> >      p = list;
> > -    for(;;) {
> > +    for (;;) {
> >          pstart = p;
> >          p = qemu_strchrnul(p, '|');
> > -        if ((p - pstart) == len && !memcmp(pstart, name, len))
> > +        if ((p - pstart) == len && !memcmp(pstart, name, len)) {
> >              return 1;
> 
> The diff gets confusing here.  The function remains unchanged.  Good.
> 
> > -        if (*p == '\0')
> > -            break;
> > -        p++;
> > -    }
> > -    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:
> > -                    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 != '\"') {
> > -            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
> > -
> > -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;
> > -    char buf[1024];
> > -
> > -    p = cmdline;
> > -    nb_args = 0;
> > -    for (;;) {
> > -        while (qemu_isspace(*p)) {
> > -            p++;
> >          }
> >          if (*p == '\0') {
> >              break;
> >          }
> > -        if (nb_args >= MAX_ARGS) {
> > -            goto fail;
> > -        }
> > -        ret = get_str(buf, sizeof(buf), &p);
> > -        if (ret < 0) {
> > -            goto fail;
> > -        }
> > -        args[nb_args] = g_strdup(buf);
> > -        nb_args++;
> > +        p++;
> >      }
> > -    *pnb_args = nb_args;
> >      return 0;
> > -
> > - fail:
> > -    free_cmdline_args(args, nb_args);
> > -    return -1;
> > -}
> > -
> > -/*
> > - * Can command @cmd be executed in preconfig state?
> > - */
> > -static bool cmd_can_preconfig(const HMPCommand *cmd)
> > -{
> > -    if (!cmd->flags) {
> > -        return false;
> > -    }
> > -
> > -    return strchr(cmd->flags, 'p');
> > -}
> > -
> > -static void help_cmd_dump_one(Monitor *mon,
> > -                              const HMPCommand *cmd,
> > -                              char **prefix_args,
> > -                              int prefix_args_nb)
> > -{
> > -    int i;
> > -
> > -    if (runstate_check(RUN_STATE_PRECONFIG) && !cmd_can_preconfig(cmd)) {
> > -        return;
> > -    }
> > -
> > -    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 HMPCommand *cmds,
> > -                          char **args, int nb_args, int arg_index)
> > -{
> > -    const HMPCommand *cmd;
> > -    size_t i;
> > -
> > -    /* 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) &&
> > -            ((!runstate_check(RUN_STATE_PRECONFIG) ||
> > -                cmd_can_preconfig(cmd)))) {
> > -            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);
> > -            }
> > -            return;
> > -        }
> > -    }
> > -
> > -    /* Command not found */
> > -    monitor_printf(mon, "unknown command: '");
> > -    for (i = 0; i <= arg_index; i++) {
> > -        monitor_printf(mon, "%s%s", args[i], i == arg_index ? "'\n" : " ");
> > -    }
> > -}
> > -
> > -static void help_cmd(Monitor *mon, const char *name)
> > -{
> > -    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, hmp_cmds, args, nb_args, 0);
> > -
> > -    free_cmdline_args(args, nb_args);
> >  }
> [...]
> 
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK


  reply	other threads:[~2019-06-14  9:21 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-13 15:33 [Qemu-devel] [PATCH v3 00/15] monitor: Split monitor.c in core/HMP/QMP/misc Kevin Wolf
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 01/15] monitor: Remove unused password prompting fields Kevin Wolf
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 02/15] monitor: Split monitor_init in HMP and QMP function Kevin Wolf
2019-06-14  8:51   ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 03/15] monitor: Make MonitorQMP a child class of Monitor Kevin Wolf
2019-06-14  8:54   ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 04/15] monitor: Create MonitorHMP with readline state Kevin Wolf
2019-06-14  8:55   ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 05/15] monitor: Remove Monitor.cmd_table indirection Kevin Wolf
2019-06-14  5:51   ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 06/15] monitor: Rename HMP command type and tables Kevin Wolf
2019-06-14  5:52   ` Markus Armbruster
2019-06-14  6:01   ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 07/15] Move monitor.c to monitor/misc.c Kevin Wolf
2019-06-14  6:04   ` Markus Armbruster
2019-06-14  6:25     ` Markus Armbruster
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 08/15] monitor: Move {hmp, qmp}.c to monitor/{hmp, qmp}-cmds.c Kevin Wolf
2019-06-13 15:33 ` [Qemu-devel] [PATCH v3 09/15] monitor: Create monitor-internal.h with common definitions Kevin Wolf
2019-06-14  6:37   ` Markus Armbruster
2019-06-14  8:47     ` Kevin Wolf
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 10/15] monitor: Split out monitor/qmp.c Kevin Wolf
2019-06-14  6:46   ` Markus Armbruster
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 11/15] monitor: Split out monitor/hmp.c Kevin Wolf
2019-06-14  8:23   ` Markus Armbruster
2019-06-14  9:17     ` Dr. David Alan Gilbert [this message]
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 12/15] monitor: Split out monitor/monitor.c Kevin Wolf
2019-06-14  8:29   ` Markus Armbruster
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 13/15] monitor: Split Monitor.flags into separate bools Kevin Wolf
2019-06-14  8:48   ` Markus Armbruster
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 14/15] monitor: Replace monitor_init() with monitor_init_{hmp, qmp}() Kevin Wolf
2019-06-14  8:50   ` Markus Armbruster
2019-06-13 15:34 ` [Qemu-devel] [PATCH v3 15/15] vl: Deprecate -mon pretty=... for HMP monitors Kevin Wolf
2019-06-14  9:01   ` Markus Armbruster
2019-06-14  9:13     ` Kevin Wolf
2019-06-14 11:14       ` Markus Armbruster
2019-06-13 17:31 ` [Qemu-devel] [PATCH v3 00/15] monitor: Split monitor.c in core/HMP/QMP/misc no-reply
2019-06-14  9:06 ` Markus Armbruster
2019-06-14  9:32   ` Kevin Wolf
2019-06-15 20:31     ` Markus Armbruster
2019-06-17  8:53       ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190614091733.GA2785@work-vm \
    --to=dgilbert@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.