[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v9 37/37] qapi: Update docs to match recent generato
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v9 37/37] qapi: Update docs to match recent generator changes |
Date: |
Tue, 19 Jan 2016 09:10:45 -0700 |
Several commits have been changing the generator, but not updating
the docs to match:
- The implicit tag member is named "type", not "kind". Screwed up in
commit 39a1815.
- Commit 9f08c8ec made list types lazy, and thereby dropped
UserDefOneList if nothing explicitly uses the list type.
- The parameter order has switched 'name' to occur earlier.
- The generated code now checks for partial allocations.
- etc.
Rework the examples to show slightly more output (we don't want to
show too much; that's what the testsuite is for), and regenerate the
output to match all recent changes.
Reported-by: Marc-André Lureau <address@hidden>
Signed-off-by: Eric Blake <address@hidden>
Signed-off-by: Markus Armbruster <address@hidden>
---
v9: new patch
---
docs/qapi-code-gen.txt | 130 +++++++++++++++++++++++++++++--------------------
1 file changed, 78 insertions(+), 52 deletions(-)
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 128f074..ae7b1a5 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -1,7 +1,7 @@
= How to use the QAPI code generator =
Copyright IBM Corp. 2011
-Copyright (C) 2012-2015 Red Hat, Inc.
+Copyright (C) 2012-2016 Red Hat, Inc.
This work is licensed under the terms of the GNU GPL, version 2 or
later. See the COPYING file in the top-level directory.
@@ -655,7 +655,7 @@ Union types
{ "name": "BlockdevOptions", "meta-type": "object",
"members": [
- { "name": "kind", "type": "BlockdevOptionsKind" } ],
+ { "name": "type", "type": "BlockdevOptionsKind" } ],
"tag": "type",
"variants": [
{ "case": "file", "type": ":obj-FileOptions-wrapper" },
@@ -721,29 +721,34 @@ the names of built-in types. Clients should examine
member
== Code generation ==
-Schemas are fed into four scripts to generate all the code/files that,
+Schemas are fed into five scripts to generate all the code/files that,
paired with the core QAPI libraries, comprise everything required to
take JSON commands read in by a Client JSON Protocol server, unmarshal
the arguments into the underlying C types, call into the corresponding
-C function, and map the response back to a Client JSON Protocol
-response to be returned to the user.
+C function, map the response back to a Client JSON Protocol response
+to be returned to the user, and introspect the commands.
-As an example, we'll use the following schema, which describes a single
-complex user-defined type (which will produce a C struct, along with a list
-node structure that can be used to chain together a list of such types in
-case we want to accept/return a list of this type with a command), and a
-command which takes that type as a parameter and returns the same type:
+As an example, we'll use the following schema, which describes a
+single complex user-defined type, along with command which takes a
+list of that type as a parameter. The user is responsible for writing
+the implementation of qmp_my_command(); everything else is produced by
+the generator.
$ cat example-schema.json
{ 'struct': 'UserDefOne',
- 'data': { 'integer': 'int', 'string': 'str' } }
+ 'data': { 'integer': 'int', '*string': 'str' } }
{ 'command': 'my-command',
- 'data': {'arg1': 'UserDefOne'},
+ 'data': { 'arg1': ['UserDefOne'] },
'returns': 'UserDefOne' }
{ 'event': 'MY_EVENT' }
+For a more thorough look at generated code, the testsuite includes
+tests/qapi-schema/qapi-schema-tests.json that covers more examples of
+what the generator will accept, and compiles the resulting C code as
+part of 'make check-unit'.
+
=== scripts/qapi-types.py ===
Used to generate the C types defined by a schema. The following files are
@@ -776,7 +781,7 @@ Example:
qdv = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(qdv);
- visit_type_UserDefOne(v, &obj, NULL, NULL);
+ visit_type_UserDefOne(v, NULL, &obj, NULL);
qapi_dealloc_visitor_cleanup(qdv);
}
@@ -791,7 +796,7 @@ Example:
qdv = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(qdv);
- visit_type_UserDefOneList(v, &obj, NULL, NULL);
+ visit_type_UserDefOneList(v, NULL, &obj, NULL);
qapi_dealloc_visitor_cleanup(qdv);
}
$ cat qapi-generated/example-qapi-types.h
@@ -808,17 +813,15 @@ Example:
struct UserDefOne {
int64_t integer;
+ bool has_string;
char *string;
};
void qapi_free_UserDefOne(UserDefOne *obj);
struct UserDefOneList {
- union {
- UserDefOne *value;
- uint64_t padding;
- };
UserDefOneList *next;
+ UserDefOne *value;
};
void qapi_free_UserDefOneList(UserDefOneList *obj);
@@ -854,54 +857,76 @@ Example:
{
Error *err = NULL;
- visit_type_int(v, &(*obj)->integer, "integer", &err);
+ visit_type_int(v, "integer", &(*obj)->integer, &err);
if (err) {
goto out;
}
- visit_type_str(v, &(*obj)->string, "string", &err);
- if (err) {
- goto out;
+ if (visit_optional(v, "string", &(*obj)->has_string)) {
+ visit_type_str(v, "string", &(*obj)->string, &err);
+ if (err) {
+ goto out;
+ }
}
out:
error_propagate(errp, err);
}
- void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name,
Error **errp)
+ void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj,
Error **errp)
{
Error *err = NULL;
+ bool allocated;
- visit_start_struct(v, (void **)obj, "UserDefOne", name,
sizeof(UserDefOne), &err);
- if (!err) {
- if (*obj) {
- visit_type_UserDefOne_fields(v, obj, errp);
- }
- visit_end_struct(v, &err);
+ allocated = visit_start_struct(v, name, (void **)obj,
sizeof(UserDefOne),
+ &err);
+ if (err) {
+ goto out;
+ }
+ if (!*obj) {
+ goto out_obj;
+ }
+ visit_type_UserDefOne_fields(v, obj, &err);
+ if (err) {
+ goto out_obj;
}
+ visit_check_struct(v, &err);
+ out_obj:
+ visit_end_struct(v);
+ if (allocated && err) {
+ qapi_free_UserDefOne(*obj);
+ *obj = NULL;
+ }
+ out:
error_propagate(errp, err);
}
- void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const
char *name, Error **errp)
+ void visit_type_UserDefOneList(Visitor *v, const char *name,
UserDefOneList **obj, Error **errp)
{
Error *err = NULL;
- GenericList *i, **prev;
+ UserDefOneList *eld;
+ bool allocated;
- visit_start_list(v, name, &err);
+ allocated = visit_start_list(v, name, (GenericList **)obj,
sizeof(UserDefOneList), &err);
if (err) {
goto out;
}
-
- for (prev = (GenericList **)obj;
- !err && (i = visit_next_list(v, prev, &err)) != NULL;
- prev = &i) {
- UserDefOneList *native_i = (UserDefOneList *)i;
- visit_type_UserDefOne(v, &native_i->value, NULL, &err);
+ elt = *obj;
+ while (elt) {
+ visit_type_UserDefOne(v, NULL, &elt->value, &err);
+ if (err) {
+ break;
+ }
+ elt = (UserDefOneList *)visit_next_list(v, (GenericList *)elt,
sizeof(UserDefOneList), &err);
+ if (err) {
+ break;
+ }
}
-
- error_propagate(errp, err);
- err = NULL;
- visit_end_list(v, &err);
+ visit_end_list(v);
out:
+ if (allocated && err) {
+ qapi_free_UserDefOneList(*obj);
+ *obj = NULL;
+ }
error_propagate(errp, err);
}
$ cat qapi-generated/example-qapi-visit.h
@@ -912,8 +937,8 @@ Example:
[Visitors for built-in types omitted...]
- void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name,
Error **errp);
- void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const
char *name, Error **errp);
+ void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj,
Error **errp);
+ void visit_type_UserDefOneList(Visitor *v, const char *name,
UserDefOneList **obj, Error **errp);
#endif
@@ -949,7 +974,7 @@ Example:
Visitor *v;
v = qmp_output_get_visitor(qov);
- visit_type_UserDefOne(v, &ret_in, "unused", &err);
+ visit_type_UserDefOne(v, "unused", &ret_in, &err);
if (err) {
goto out;
}
@@ -960,7 +985,7 @@ Example:
qmp_output_visitor_cleanup(qov);
qdv = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(qdv);
- visit_type_UserDefOne(v, &ret_in, "unused", NULL);
+ visit_type_UserDefOne(v, "unused", &ret_in, NULL);
qapi_dealloc_visitor_cleanup(qdv);
}
@@ -971,10 +996,10 @@ Example:
QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
QapiDeallocVisitor *qdv;
Visitor *v;
- UserDefOne *arg1 = NULL;
+ UserDefOneList *arg1 = NULL;
v = qmp_input_get_visitor(qiv);
- visit_type_UserDefOne(v, &arg1, "arg1", &err);
+ visit_type_UserDefOne(v, "arg1", &arg1, &err);
if (err) {
goto out;
}
@@ -991,7 +1016,7 @@ Example:
qmp_input_visitor_cleanup(qiv);
qdv = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(qdv);
- visit_type_UserDefOne(v, &arg1, "arg1", NULL);
+ visit_type_UserDefOne(v, "arg1", &arg1, NULL);
qapi_dealloc_visitor_cleanup(qdv);
}
@@ -1011,7 +1036,7 @@ Example:
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"
- UserDefOne *qmp_my_command(UserDefOne *arg1, Error **errp);
+ UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp);
#endif
@@ -1095,8 +1120,9 @@ Example:
"{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\":
\"MY_EVENT\"}, "
"{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\":
\"my-command\", \"ret-type\": \"2\"}, "
"{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, "
- "{\"members\": [{\"name\": \"arg1\", \"type\": \"2\"}], \"meta-type\":
\"object\", \"name\": \"1\"}, "
- "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\":
\"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, "
+ "{\"members\": [{\"name\": \"arg1\", \"type\": \"[2]\"}],
\"meta-type\": \"object\", \"name\": \"1\"}, "
+ "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"},
{\"default\": null, \"name\": \"string\", \"type\": \"str\"}], \"meta-type\":
\"object\", \"name\": \"2\"}, "
+ "{\"element-type\": \"2\", \"meta-type\": \"array\", \"name\":
\"[2]\"}, "
"{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\":
\"int\"}, "
"{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\":
\"str\"}]";
$ cat qapi-generated/example-qmp-introspect.h
--
2.5.0
- [Qemu-devel] [PATCH v9 18/37] qapi: Drop unused error argument for list and implicit struct, (continued)
- [Qemu-devel] [PATCH v9 17/37] qapi: Drop unused 'kind' for struct/enum visit, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 29/37] qapi: Eliminate empty visit_type_FOO_fields, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 27/37] qapi: Add type.is_empty() helper, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 37/37] qapi: Update docs to match recent generator changes,
Eric Blake <=
- [Qemu-devel] [PATCH v9 22/37] qapi: Add visit_type_null() visitor, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 25/37] spapr_drc: Expose 'null' in qom-get when there is no fdt, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 24/37] qmp: Tighten output visitor rules, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 31/37] qapi-visit: Unify struct and union visit, Eric Blake, 2016/01/19
- [Qemu-devel] [PATCH v9 30/37] qapi: Canonicalize missing object to :empty, Eric Blake, 2016/01/19