Commit 4142b011 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2019-09-24' into staging



QAPI patches for 2019-09-24

# gpg: Signature made Tue 24 Sep 2019 13:10:36 BST
# gpg:                using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg:                issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-qapi-2019-09-24: (37 commits)
  qapi: Assert .visit() and .check_clash() run only after .check()
  qapi: Fix excessive QAPISchemaEntity.check() recursion
  qapi: Fix to .check() empty structs just once
  qapi: Delete useless check_exprs() code for simple union kind
  qapi: Clean up around check_known_keys()
  qapi: Simplify check_keys()
  qapi: Normalize 'if' in check_exprs(), like other sugar
  qapi: Fix missing 'if' checks in struct, union, alternate 'data'
  qapi: Reject blank 'if' conditions in addition to empty ones
  qapi: Fix broken discriminator error messages
  qapi: Remove null from schema language
  qapi: Improve reporting of lexical errors
  qapi: Use quotes more consistently in frontend error messages
  tests/qapi-schema: Demonstrate suboptimal lexical errors
  tests/qapi-schema: Demonstrate insufficient 'if' checking
  tests/qapi-schema: Demonstrate broken discriminator errors
  tests/qapi-schema: Demonstrate misleading optional tag error
  tests/qapi-schema: Delete two redundant tests
  tests/qapi-schema: Cover unknown pragma
  qapi: Tweak code to match docs/devel/qapi-code-gen.txt
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 240ab11f 56176412
Loading
Loading
Loading
Loading
+618 −449

File changed.

Preview size limit exceeded, changes collapsed.

+4 −4
Original line number Diff line number Diff line
@@ -364,10 +364,10 @@ void visit_start_list(Visitor *v, const char *name, GenericList **list,
 * @tail must not be NULL; on the first call, @tail is the value of
 * *list after visit_start_list(), and on subsequent calls @tail must
 * be the previously returned value.  Should be called in a loop until
 * a NULL return or error occurs; for each non-NULL return, the caller
 * then calls the appropriate visit_type_*() for the element type of
 * the list, with that function's name parameter set to NULL and obj
 * set to the address of @tail->value.
 * a NULL return; for each non-NULL return, the caller then calls the
 * appropriate visit_type_*() for the element type of the list, with
 * that function's name parameter set to NULL and obj set to the
 * address of @tail->value.
 */
GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);

+22 −4
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ enum ListMode
{
    LM_NONE,             /* not traversing a list of repeated options */

    LM_IN_PROGRESS,      /* opts_next_list() ready to be called.
    LM_IN_PROGRESS,      /*
                          * opts_next_list() ready to be called.
                          *
                          * Generating the next list link will consume the most
                          * recently parsed QemuOpt instance of the repeated
@@ -36,7 +37,8 @@ enum ListMode
                          * LM_UNSIGNED_INTERVAL.
                          */

    LM_SIGNED_INTERVAL,  /* opts_next_list() has been called.
    LM_SIGNED_INTERVAL,  /*
                          * opts_next_list() has been called.
                          *
                          * Generating the next list link will consume the most
                          * recently stored element from the signed interval,
@@ -48,7 +50,14 @@ enum ListMode
                          * next element of the signed interval.
                          */

    LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */
    LM_UNSIGNED_INTERVAL, /* Same as above, only for an unsigned interval. */

    LM_TRAVERSED          /*
                           * opts_next_list() has been called.
                           *
                           * No more QemuOpt instance in the list.
                           * The traversal has been completed.
                           */
};

typedef enum ListMode ListMode;
@@ -238,6 +247,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
    OptsVisitor *ov = to_ov(v);

    switch (ov->list_mode) {
    case LM_TRAVERSED:
        return NULL;
    case LM_SIGNED_INTERVAL:
    case LM_UNSIGNED_INTERVAL:
        if (ov->list_mode == LM_SIGNED_INTERVAL) {
@@ -258,6 +269,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
        opt = g_queue_pop_head(ov->repeated_opts);
        if (g_queue_is_empty(ov->repeated_opts)) {
            g_hash_table_remove(ov->unprocessed_opts, opt->name);
            ov->repeated_opts = NULL;
            ov->list_mode = LM_TRAVERSED;
            return NULL;
        }
        break;
@@ -289,7 +302,8 @@ opts_end_list(Visitor *v, void **obj)

    assert(ov->list_mode == LM_IN_PROGRESS ||
           ov->list_mode == LM_SIGNED_INTERVAL ||
           ov->list_mode == LM_UNSIGNED_INTERVAL);
           ov->list_mode == LM_UNSIGNED_INTERVAL ||
           ov->list_mode == LM_TRAVERSED);
    ov->repeated_opts = NULL;
    ov->list_mode = LM_NONE;
}
@@ -306,6 +320,10 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
        list = lookup_distinct(ov, name, errp);
        return list ? g_queue_peek_tail(list) : NULL;
    }
    if (ov->list_mode == LM_TRAVERSED) {
        error_setg(errp, "Fewer list elements than expected");
        return NULL;
    }
    assert(ov->list_mode == LM_IN_PROGRESS);
    return g_queue_peek_head(ov->repeated_opts);
}
+2 −2
Original line number Diff line number Diff line
@@ -19,11 +19,11 @@ Makefile*
*.mak

# qapi schema
*.json
qapi/*.json
qga/*.json

# headers
*.h

# code
*.c
+2 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ def gen_call(name, arg_type, boxed, ret_type):

    argstr = ''
    if boxed:
        assert arg_type and not arg_type.is_empty()
        assert arg_type
        argstr = '&arg, '
    elif arg_type:
        assert not arg_type.variants
@@ -96,7 +96,7 @@ def gen_marshal_decl(name):


def gen_marshal(name, arg_type, boxed, ret_type):
    have_args = arg_type and not arg_type.is_empty()
    have_args = boxed or (arg_type and not arg_type.is_empty())

    ret = mcgen('''

Loading