1. 18 3月, 2016 2 次提交
    • E
      qapi: Don't special-case simple union wrappers · 32bafa8f
      Eric Blake 提交于
      Simple unions were carrying a special case that hid their 'data'
      QMP member from the resulting C struct, via the hack method
      QAPISchemaObjectTypeVariant.simple_union_type().  But by using
      the work we started by unboxing flat union and alternate
      branches, coupled with the ability to visit the members of an
      implicit type, we can now expose the simple union's implicit
      type in qapi-types.h:
      
      | struct q_obj_ImageInfoSpecificQCow2_wrapper {
      |     ImageInfoSpecificQCow2 *data;
      | };
      |
      | struct q_obj_ImageInfoSpecificVmdk_wrapper {
      |     ImageInfoSpecificVmdk *data;
      | };
      ...
      | struct ImageInfoSpecific {
      |     ImageInfoSpecificKind type;
      |     union { /* union tag is @type */
      |         void *data;
      |-        ImageInfoSpecificQCow2 *qcow2;
      |-        ImageInfoSpecificVmdk *vmdk;
      |+        q_obj_ImageInfoSpecificQCow2_wrapper qcow2;
      |+        q_obj_ImageInfoSpecificVmdk_wrapper vmdk;
      |     } u;
      | };
      
      Doing this removes asymmetry between QAPI's QMP side and its
      C side (both sides now expose 'data'), and means that the
      treatment of a simple union as sugar for a flat union is now
      equivalent in both languages (previously the two approaches used
      a different layer of dereferencing, where the simple union could
      be converted to a flat union with equivalent C layout but
      different {} on the wire, or to an equivalent QMP wire form
      but with different C representation).  Using the implicit type
      also lets us get rid of the simple_union_type() hack.
      
      Of course, now all clients of simple unions have to adjust from
      using su->u.member to using su->u.member.data; while this touches
      a number of files in the tree, some earlier cleanup patches
      helped minimize the change to the initialization of a temporary
      variable rather than every single member access.  The generated
      qapi-visit.c code is also affected by the layout change:
      
      |@@ -7393,10 +7393,10 @@ void visit_type_ImageInfoSpecific_member
      |     }
      |     switch (obj->type) {
      |     case IMAGE_INFO_SPECIFIC_KIND_QCOW2:
      |-        visit_type_ImageInfoSpecificQCow2(v, "data", &obj->u.qcow2, &err);
      |+        visit_type_q_obj_ImageInfoSpecificQCow2_wrapper_members(v, &obj->u.qcow2, &err);
      |         break;
      |     case IMAGE_INFO_SPECIFIC_KIND_VMDK:
      |-        visit_type_ImageInfoSpecificVmdk(v, "data", &obj->u.vmdk, &err);
      |+        visit_type_q_obj_ImageInfoSpecificVmdk_wrapper_members(v, &obj->u.vmdk, &err);
      |         break;
      |     default:
      |         abort();
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1458254921-17042-13-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      32bafa8f
    • E
      qapi: Fix command with named empty argument type · 972a1101
      Eric Blake 提交于
      The generator special-cased
      
       { 'command':'foo', 'data': {} }
      
      to avoid emitting a visitor variable, but failed to see that
      
       { 'struct':'NamedEmptyType, 'data': {} }
       { 'command':'foo', 'data':'NamedEmptyType' }
      
      needs the same treatment.  There, the generator happily generates a
      visitor to get no arguments, and a visitor to destroy no arguments;
      and the compiler isn't happy with that, as demonstrated by the updated
      qapi-schema-test.json:
      
        tests/test-qmp-marshal.c: In function ‘qmp_marshal_user_def_cmd0’:
        tests/test-qmp-marshal.c:264:14: error: variable ‘v’ set but not used [-Werror=unused-but-set-variable]
             Visitor *v;
                      ^
      
      No change to generated code except for the testsuite addition.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1458254921-17042-3-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      972a1101
  2. 16 2月, 2016 1 次提交
  3. 09 2月, 2016 1 次提交
    • E
      qapi: Swap visit_* arguments for consistent 'name' placement · 51e72bc1
      Eric Blake 提交于
      JSON uses "name":value, but many of our visitor interfaces were
      called with visit_type_FOO(v, &value, name, errp).  This can be
      a bit confusing to have to mentally swap the parameter order to
      match JSON order.  It's particularly bad for visit_start_struct(),
      where the 'name' parameter is smack in the middle of the
      otherwise-related group of 'obj, kind, size' parameters! It's
      time to do a global swap of the parameter ordering, so that the
      'name' parameter is always immediately after the Visitor argument.
      
      Additional reason in favor of the swap: the existing include/qjson.h
      prefers listing 'name' first in json_prop_*(), and I have plans to
      unify that file with the qapi visitors; listing 'name' first in
      qapi will minimize churn to the (admittedly few) qjson.h clients.
      
      Later patches will then fix docs, object.h, visitor-impl.h, and
      those clients to match.
      
      Done by first patching scripts/qapi*.py by hand to make generated
      files do what I want, then by running the following Coccinelle
      script to affect the rest of the code base:
       $ spatch --sp-file script `git grep -l '\bvisit_' -- '**/*.[ch]'`
      I then had to apply some touchups (Coccinelle insisted on TAB
      indentation in visitor.h, and botched the signature of
      visit_type_enum() by rewriting 'const char *const strings[]' to
      the syntactically invalid 'const char*const[] strings').  The
      movement of parameters is sufficient to provoke compiler errors
      if any callers were missed.
      
          // Part 1: Swap declaration order
          @@
          type TV, TErr, TObj, T1, T2;
          identifier OBJ, ARG1, ARG2;
          @@
           void visit_start_struct
          -(TV v, TObj OBJ, T1 ARG1, const char *name, T2 ARG2, TErr errp)
          +(TV v, const char *name, TObj OBJ, T1 ARG1, T2 ARG2, TErr errp)
           { ... }
      
          @@
          type bool, TV, T1;
          identifier ARG1;
          @@
           bool visit_optional
          -(TV v, T1 ARG1, const char *name)
          +(TV v, const char *name, T1 ARG1)
           { ... }
      
          @@
          type TV, TErr, TObj, T1;
          identifier OBJ, ARG1;
          @@
           void visit_get_next_type
          -(TV v, TObj OBJ, T1 ARG1, const char *name, TErr errp)
          +(TV v, const char *name, TObj OBJ, T1 ARG1, TErr errp)
           { ... }
      
          @@
          type TV, TErr, TObj, T1, T2;
          identifier OBJ, ARG1, ARG2;
          @@
           void visit_type_enum
          -(TV v, TObj OBJ, T1 ARG1, T2 ARG2, const char *name, TErr errp)
          +(TV v, const char *name, TObj OBJ, T1 ARG1, T2 ARG2, TErr errp)
           { ... }
      
          @@
          type TV, TErr, TObj;
          identifier OBJ;
          identifier VISIT_TYPE =~ "^visit_type_";
          @@
           void VISIT_TYPE
          -(TV v, TObj OBJ, const char *name, TErr errp)
          +(TV v, const char *name, TObj OBJ, TErr errp)
           { ... }
      
          // Part 2: swap caller order
          @@
          expression V, NAME, OBJ, ARG1, ARG2, ERR;
          identifier VISIT_TYPE =~ "^visit_type_";
          @@
          (
          -visit_start_struct(V, OBJ, ARG1, NAME, ARG2, ERR)
          +visit_start_struct(V, NAME, OBJ, ARG1, ARG2, ERR)
          |
          -visit_optional(V, ARG1, NAME)
          +visit_optional(V, NAME, ARG1)
          |
          -visit_get_next_type(V, OBJ, ARG1, NAME, ERR)
          +visit_get_next_type(V, NAME, OBJ, ARG1, ERR)
          |
          -visit_type_enum(V, OBJ, ARG1, ARG2, NAME, ERR)
          +visit_type_enum(V, NAME, OBJ, ARG1, ARG2, ERR)
          |
          -VISIT_TYPE(V, OBJ, NAME, ERR)
          +VISIT_TYPE(V, NAME, OBJ, ERR)
          )
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-Id: <1454075341-13658-19-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      51e72bc1
  4. 17 12月, 2015 1 次提交
    • E
      qapi: Fix c_name() munging · c43567c1
      Eric Blake 提交于
      The method c_name() is supposed to do two different actions: munge
      '-' into '_', and add a 'q_' prefix to ticklish names.  But it did
      these steps out of order, making it possible to submit input that
      is not ticklish until after munging, where the output then lacked
      the desired prefix.
      
      The failure is exposed easily if you have a compiler that recognizes
      C11 keywords, and try to name a member '_Thread-local', as it would
      result in trying to compile the declaration 'uint64_t _Thread_local;'
      which is not valid.  However, this name violates our conventions
      (ultimately, want to enforce that no qapi names start with single
      underscore), so the test is slightly weaker by instead testing
      'wchar-t'; the declaration 'uint64_t wchar_t;' is valid in C (where
      wchar_t is only a typedef) but would fail with a C++ compiler (where
      it is a keyword).
      
      Fix things by reversing the order of actions within c_name().
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1447836791-369-18-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      c43567c1
  5. 10 11月, 2015 1 次提交
    • E
      qapi: Simplify error cleanup in test-qmp-* · a12a5a1a
      Eric Blake 提交于
      We have several tests that perform multiple sub-actions that are
      expected to fail.  Asserting that an error occurred, then clearing
      it up to prepare for the next action, turned into enough
      boilerplate that it was sometimes forgotten (for example, a number
      of tests added to test-qmp-input-visitor.c in d88f5fd1 leaked err).
      Worse, if an error is not reset to NULL, we risk invalidating
      later use of that error (passing a non-NULL err into a function
      is generally a bad idea).  Encapsulate the boilerplate into a
      single helper function error_free_or_abort(), and consistently
      use it.
      
      The new function is added into error.c for use everywhere,
      although it is anticipated that testsuites will be the main
      client.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      a12a5a1a
  6. 02 11月, 2015 2 次提交
    • E
      tests: Convert to new qapi union layout · c363acef
      Eric Blake 提交于
      We have two issues with our qapi union layout:
      1) Even though the QMP wire format spells the tag 'type', the
      C code spells it 'kind', requiring some hacks in the generator.
      2) The C struct uses an anonymous union, which places all tag
      values in the same namespace as all non-variant members. This
      leads to spurious collisions if a tag value matches a non-variant
      member's name.
      
      Make the conversion to the new layout for testsuite code.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1445898903-12082-15-git-send-email-eblake@redhat.com>
      [Commit message tweaked slightly]
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      c363acef
    • E
      qapi: Unbox base members · ddf21908
      Eric Blake 提交于
      Rather than storing a base class as a pointer to a box, just
      store the fields of that base class in the same order, so that
      a child struct can be directly cast to its parent.  This gives
      less malloc overhead, less pointer dereferencing, and even less
      generated code.  Compare to the earlier commit 1e6c1616 "qapi:
      Generate a nicer struct for flat unions" (although that patch
      had fewer places to change, as less of qemu was directly using
      qapi structs for flat unions).  It also allows us to turn on
      automatic type-safe wrappers for upcasting to the base class
      of a struct.
      
      Changes to the generated code look like this in qapi-types.h:
      
      | struct SpiceChannel {
      |-    SpiceBasicInfo *base;
      |+    /* Members inherited from SpiceBasicInfo: */
      |+    char *host;
      |+    char *port;
      |+    NetworkAddressFamily family;
      |+    /* Own members: */
      |     int64_t connection_id;
      
      as well as additional upcast functions like qapi_SpiceChannel_base().
      Meanwhile, changes to qapi-visit.c look like:
      
      | static void visit_type_SpiceChannel_fields(Visitor *v, SpiceChannel **obj, Error **errp)
      | {
      |     Error *err = NULL;
      |
      |-    visit_type_implicit_SpiceBasicInfo(v, &(*obj)->base, &err);
      |+    visit_type_SpiceBasicInfo_fields(v, (SpiceBasicInfo **)obj, &err);
      |     if (err) {
      
      (the cast is necessary, since our upcast wrappers only deal with a
      single pointer, not pointer-to-pointer); plus the wholesale
      elimination of some now-unused visit_type_implicit_FOO() functions.
      
      Without boxing, the corner case of one empty struct having
      another empty struct as its base type now requires inserting a
      dummy member (previously, the 'Base *base' member sufficed).
      
      And now that we no longer consume a 'base' member in the generated
      C struct, we can delete the former negative struct-base-clash-base
      test.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1445898903-12082-11-git-send-email-eblake@redhat.com>
      [Commit message tweaked slightly]
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      ddf21908
  7. 15 10月, 2015 1 次提交
  8. 21 9月, 2015 1 次提交
  9. 15 5月, 2015 1 次提交
  10. 06 5月, 2015 2 次提交
    • E
      qapi: Drop tests for inline nested structs · 6446a592
      Eric Blake 提交于
      A future patch will be using a 'name':{dictionary} entry in the
      QAPI schema to specify a default value for an optional argument;
      but existing use of inline nested structs conflicts with that goal.
      
      More precisely, a definition in the QAPI schema associates a name
      with a set of properties:
      
      Example 1: { 'struct': 'Foo', 'data': { MEMBERS... } }
      associates the global name 'Foo' with properties (meta-type struct)
      and MEMBERS...
      
      Example 2: 'mumble': TYPE
      within MEMBERS... above associates 'mumble' with properties (type
      TYPE) and (optional false) within type Foo
      
      The syntax of example 1 is extensible; if we need another property,
      we add another name/value pair to the dictionary (such as
      'base':TYPE).  The syntax of example 2 is not extensible, because
      the right hand side can only be a type.
      
      We have used name encoding to add a property: "'*mumble': 'int'"
      associates 'mumble' with (type int) and (optional true).  Nice,
      but doesn't scale.  So the solution is to change our existing uses
      to be syntactic sugar to an extensible form:
      
         NAME: TYPE   --> NAME:  { 'type': TYPE, 'optional': false }
         *ONAME: TYPE --> ONAME: { 'type': TYPE, 'optional': true }
      
      This patch fixes the testsuite to avoid inline nested types, by
      breaking the nesting into explicit types; it means that the type
      is now boxed instead of unboxed in C code, but makes no difference
      on the wire (and if desired, a later patch could change the
      generator to not do so much boxing in C).  When touching code to
      add new allocations, also convert existing allocations to
      consistently prefer typesafe g_new0 over g_malloc0 when a type
      name is involved.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NMarkus Armbruster <armbru@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      6446a592
    • E
      qapi: Merge UserDefTwo and UserDefNested in tests · b6fcf32d
      Eric Blake 提交于
      In the testsuite, UserDefTwo and UserDefNested were identical
      structs other than the member names.  Reduce code duplication by
      having just one type, and choose names that also favor reuse.
      This will also make it easier for a later patch to get rid of
      inline nested types in QAPI.  When touching code related to
      allocations, convert g_malloc0(sizeof(Type)) to the more typesafe
      g_new0(Type, 1).
      
      Ensure that 'make check-qapi-schema check-unit' still passes.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NMarkus Armbruster <armbru@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      b6fcf32d
  11. 11 3月, 2014 1 次提交
  12. 04 3月, 2014 4 次提交
  13. 19 12月, 2012 3 次提交
  14. 23 7月, 2012 1 次提交
  15. 30 3月, 2012 1 次提交
  16. 26 3月, 2012 1 次提交
  17. 04 10月, 2011 1 次提交
  18. 21 8月, 2011 1 次提交
  19. 22 7月, 2011 1 次提交