qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/9] QMP: First half of the new argument checkin


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH 3/9] QMP: First half of the new argument checking code
Date: Wed, 02 Jun 2010 08:59:11 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Luiz Capitulino <address@hidden> writes:

> This commit introduces the first half of qmp_check_client_args(),
> which is the new client argument checker.
>
> It's introduced on top of the existing code, so that there are
> no regressions during the transition.
>
> It works this way: the command's args_type field (from
> qemu-monitor.hx) is transformed into a qdict. Then we iterate
> over it checking whether each mandatory argument has been
> provided by the client.
>
> All comunication between the iterator and its caller is done
> via the new QMPArgCheckRes type.
>
> Next commit adds the second half of this work: type checking
> and invalid argument detection.
>
> Signed-off-by: Luiz Capitulino <address@hidden>
> ---
>  monitor.c |  107 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 107 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index bc3cc18..47a0da8 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -4259,6 +4259,108 @@ static int invalid_qmp_mode(const Monitor *mon, const 
> char *cmd_name)
>      return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
>  }
>  
> +typedef struct QMPArgCheckRes {
> +    int result;
> +    int skip;

skip is write-only in this patch.

> +    QDict *qdict;
> +} QMPArgCheckRes;
> +
> +/*
> + * Check if client passed all mandatory args
> + */
> +static void check_mandatory_args(const char *cmd_arg_name,
> +                                 QObject *obj, void *opaque)
> +{
> +    QString *type;
> +    QMPArgCheckRes *res = opaque;
> +
> +    if (res->result < 0) {
> +        /* report only the first error */
> +        return;
> +    }

This is a sign that the iterator needs a way to break the loop.

> +
> +    type = qobject_to_qstring(obj);
> +    assert(type != NULL);
> +
> +    if (qstring_get_str(type)[0] == 'O') {
> +        QemuOptsList *opts_list = qemu_find_opts(cmd_arg_name);
> +        assert(opts_list);
> +        res->result = check_opts(opts_list, res->qdict);

I doubt this is the right place for calling check_opts.

Right now, it's only implemented for QemuOptsList with empty desc.  A
more complete version is in my tree (blockdev needs it).  Looks like
this:

static int check_opts(QemuOptsList *opts_list, QDict *args)
{
    QemuOptDesc *desc;
    CmdArgs cmd_args;

    for (desc = opts_list->desc; desc->name; desc++) {
        cmd_args_init(&cmd_args);
        cmd_args.optional = 1;
        switch (desc->type) {
        case QEMU_OPT_STRING:
            cmd_args.type = 's';
            break;
        case QEMU_OPT_BOOL:
            cmd_args.type = '-';
            break;
        case QEMU_OPT_NUMBER:
        case QEMU_OPT_SIZE:
            cmd_args.type = 'l';
            break;
        }
        qstring_append(cmd_args.name, desc->name);
        if (check_arg(&cmd_args, args) < 0) {
            QDECREF(cmd_args.name);
            return -1;
        }
        QDECREF(cmd_args.name);
    }
    return 0;
}

> +        res->skip = 1;
> +    } else if (qstring_get_str(type)[0] != '-' &&
> +               qstring_get_str(type)[1] != '?' &&
> +               !qdict_haskey(res->qdict, cmd_arg_name)) {
> +        res->result = -1;
> +        qerror_report(QERR_MISSING_PARAMETER, cmd_arg_name);
> +    }
> +}
[...]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]