Commit 5cfffc30 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-02-19' into staging



QAPI patches for 2016-02-19

# gpg: Signature made Fri 19 Feb 2016 10:10:18 GMT using RSA key ID EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>"

* remotes/armbru/tags/pull-qapi-2016-02-19:
  qapi: Change visit_start_implicit_struct to visit_start_alternate
  qapi: Don't box branches of flat unions
  qapi: Don't box struct branch of alternate
  qapi-visit: Use common idiom in gen_visit_fields_decl()
  qapi: Emit structs used as variants in topological order
  qapi: Adjust layout of FooList types
  qapi-visit: Less indirection in visit_type_Foo_fields()
  qapi-visit: Unify struct and union visit
  qapi: Visit variants in visit_type_FOO_fields()
  qapi-visit: Simplify how we visit common union members
  qapi: Add tests of complex objects within alternate
  qapi: Forbid 'any' inside an alternate
  qapi: Forbid empty unions and useless alternates
  qapi: Simplify excess input reporting in input visitors
  qapi-visit: Honor prefix of discriminator enum

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 09125c5e dbf11922
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -1568,28 +1568,22 @@ CpuInfoList *qmp_query_cpus(Error **errp)
        info->value->thread_id = cpu->thread_id;
#if defined(TARGET_I386)
        info->value->arch = CPU_INFO_ARCH_X86;
        info->value->u.x86 = g_new0(CpuInfoX86, 1);
        info->value->u.x86->pc = env->eip + env->segs[R_CS].base;
        info->value->u.x86.pc = env->eip + env->segs[R_CS].base;
#elif defined(TARGET_PPC)
        info->value->arch = CPU_INFO_ARCH_PPC;
        info->value->u.ppc = g_new0(CpuInfoPPC, 1);
        info->value->u.ppc->nip = env->nip;
        info->value->u.ppc.nip = env->nip;
#elif defined(TARGET_SPARC)
        info->value->arch = CPU_INFO_ARCH_SPARC;
        info->value->u.q_sparc = g_new0(CpuInfoSPARC, 1);
        info->value->u.q_sparc->pc = env->pc;
        info->value->u.q_sparc->npc = env->npc;
        info->value->u.q_sparc.pc = env->pc;
        info->value->u.q_sparc.npc = env->npc;
#elif defined(TARGET_MIPS)
        info->value->arch = CPU_INFO_ARCH_MIPS;
        info->value->u.q_mips = g_new0(CpuInfoMIPS, 1);
        info->value->u.q_mips->PC = env->active_tc.PC;
        info->value->u.q_mips.PC = env->active_tc.PC;
#elif defined(TARGET_TRICORE)
        info->value->arch = CPU_INFO_ARCH_TRICORE;
        info->value->u.tricore = g_new0(CpuInfoTricore, 1);
        info->value->u.tricore->PC = env->PC;
        info->value->u.tricore.PC = env->PC;
#else
        info->value->arch = CPU_INFO_ARCH_OTHER;
        info->value->u.other = g_new0(CpuInfoOther, 1);
#endif

        /* XXX: waiting for the qapi to support GSList */
+8 −7
Original line number Diff line number Diff line
@@ -187,11 +187,11 @@ prevent incomplete include files.

Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME }

A struct is a dictionary containing a single 'data' key whose
value is a dictionary.  This corresponds to a struct in C or an Object
in JSON. Each value of the 'data' dictionary must be the name of a
type, or a one-element array containing a type name.  An example of a
struct is:
A struct is a dictionary containing a single 'data' key whose value is
a dictionary; the dictionary may be empty.  This corresponds to a
struct in C or an Object in JSON. Each value of the 'data' dictionary
must be the name of a type, or a one-element array containing a type
name.  An example of a struct is:

 { 'struct': 'MyType',
   'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
@@ -288,9 +288,10 @@ or: { 'union': STRING, 'data': DICT, 'base': STRUCT-NAME,

Union types are used to let the user choose between several different
variants for an object.  There are two flavors: simple (no
discriminator or base), flat (both discriminator and base).  A union
discriminator or base), and flat (both discriminator and base).  A union
type is defined using a data dictionary as explained in the following
paragraphs.
paragraphs.  The data dictionary for either type of union must not
be empty.

A simple union type defines a mapping from automatic discriminator
values to data types like in this example:
+6 −6
Original line number Diff line number Diff line
@@ -314,22 +314,22 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)

        switch (cpu->value->arch) {
        case CPU_INFO_ARCH_X86:
            monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86->pc);
            monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86.pc);
            break;
        case CPU_INFO_ARCH_PPC:
            monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->u.ppc->nip);
            monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->u.ppc.nip);
            break;
        case CPU_INFO_ARCH_SPARC:
            monitor_printf(mon, " pc=0x%016" PRIx64,
                           cpu->value->u.q_sparc->pc);
                           cpu->value->u.q_sparc.pc);
            monitor_printf(mon, " npc=0x%016" PRIx64,
                           cpu->value->u.q_sparc->npc);
                           cpu->value->u.q_sparc.npc);
            break;
        case CPU_INFO_ARCH_MIPS:
            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.q_mips->PC);
            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.q_mips.PC);
            break;
        case CPU_INFO_ARCH_TRICORE:
            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore->PC);
            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore.PC);
            break;
        default:
            break;
+10 −11
Original line number Diff line number Diff line
@@ -22,22 +22,23 @@ struct Visitor
                         size_t size, Error **errp);
    void (*end_struct)(Visitor *v, Error **errp);

    void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
                                  Error **errp);
    /* May be NULL */
    void (*end_implicit_struct)(Visitor *v);

    void (*start_list)(Visitor *v, const char *name, Error **errp);
    /* Must be set */
    GenericList *(*next_list)(Visitor *v, GenericList **list);
    GenericList *(*next_list)(Visitor *v, GenericList **list, size_t size);
    /* Must be set */
    void (*end_list)(Visitor *v);

    /* Optional, needed for input and dealloc visitors.  */
    void (*start_alternate)(Visitor *v, const char *name,
                            GenericAlternate **obj, size_t size,
                            bool promote_int, Error **errp);

    /* Optional, needed for dealloc visitor.  */
    void (*end_alternate)(Visitor *v);

    /* Must be set. */
    void (*type_enum)(Visitor *v, const char *name, int *obj,
                      const char *const strings[], Error **errp);
    /* May be NULL; only needed for input visitors. */
    void (*get_next_type)(Visitor *v, const char *name, QType *type,
                          bool promote_int, Error **errp);

    /* Must be set. */
    void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
@@ -58,8 +59,6 @@ struct Visitor

    /* May be NULL; most useful for input visitors. */
    void (*optional)(Visitor *v, const char *name, bool *present);

    bool (*start_union)(Visitor *v, bool data_present, Error **errp);
};

void input_type_enum(Visitor *v, const char *name, int *obj,
+44 −19
Original line number Diff line number Diff line
@@ -19,26 +19,60 @@
#include "qapi/error.h"
#include <stdlib.h>

typedef struct GenericList
{
    union {
        void *value;
        uint64_t padding;
    };
/* This struct is layout-compatible with all other *List structs
 * created by the qapi generator.  It is used as a typical
 * singly-linked list. */
typedef struct GenericList {
    struct GenericList *next;
    char padding[];
} GenericList;

/* This struct is layout-compatible with all Alternate types
 * created by the qapi generator. */
typedef struct GenericAlternate {
    QType type;
    char padding[];
} GenericAlternate;

void visit_start_struct(Visitor *v, const char *name, void **obj,
                        size_t size, Error **errp);
void visit_end_struct(Visitor *v, Error **errp);
void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
                                 Error **errp);
void visit_end_implicit_struct(Visitor *v);

void visit_start_list(Visitor *v, const char *name, Error **errp);
GenericList *visit_next_list(Visitor *v, GenericList **list);
GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size);
void visit_end_list(Visitor *v);

/*
 * Start the visit of an alternate @obj with the given @size.
 *
 * @name specifies the relationship to the containing struct (ignored
 * for a top level visit, the name of the key if this alternate is
 * part of an object, or NULL if this alternate is part of a list).
 *
 * @obj must not be NULL. Input visitors will allocate @obj and
 * determine the qtype of the next thing to be visited, stored in
 * (*@obj)->type.  Other visitors will leave @obj unchanged.
 *
 * If @promote_int, treat integers as QTYPE_FLOAT.
 *
 * If successful, this must be paired with visit_end_alternate(), even
 * if visiting the contents of the alternate fails.
 */
void visit_start_alternate(Visitor *v, const char *name,
                           GenericAlternate **obj, size_t size,
                           bool promote_int, Error **errp);

/*
 * Finish visiting an alternate type.
 *
 * Must be called after a successful visit_start_alternate(), even if
 * an error occurred in the meantime.
 *
 * TODO: Should all the visit_end_* interfaces take obj parameter, so
 * that dealloc visitor need not track what was passed in visit_start?
 */
void visit_end_alternate(Visitor *v);

/**
 * Check if an optional member @name of an object needs visiting.
 * For input visitors, set *@present according to whether the
@@ -47,14 +81,6 @@ void visit_end_list(Visitor *v);
 */
bool visit_optional(Visitor *v, const char *name, bool *present);

/**
 * Determine the qtype of the item @name in the current object visit.
 * For input visitors, set *@type to the correct qtype of a qapi
 * alternate type; for other visitors, leave *@type unchanged.
 * If @promote_int, treat integers as QTYPE_FLOAT.
 */
void visit_get_next_type(Visitor *v, const char *name, QType *type,
                         bool promote_int, Error **errp);
void visit_type_enum(Visitor *v, const char *name, int *obj,
                     const char *const strings[], Error **errp);
void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
@@ -80,6 +106,5 @@ void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
void visit_type_number(Visitor *v, const char *name, double *obj,
                       Error **errp);
void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
bool visit_start_union(Visitor *v, bool data_present, Error **errp);

#endif
Loading