2011-07-20 03:50:32 +08:00
|
|
|
/*
|
|
|
|
* Core Definitions for QAPI Visitor Classes
|
|
|
|
*
|
qapi-visit: Kill unused visit_end_union()
The generated code can call visit_end_union() without having called
visit_start_union(). Example:
if (!*obj) {
goto out_obj;
}
visit_type_CpuInfoBase_fields(v, (CpuInfoBase **)obj, &err);
if (err) {
goto out_obj; // if we go from here...
}
if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
goto out_obj;
}
switch ((*obj)->arch) {
[...]
}
out_obj:
// ... then *obj is true, and ...
error_propagate(errp, err);
err = NULL;
if (*obj) {
// we end up here
visit_end_union(v, !!(*obj)->u.data, &err);
}
error_propagate(errp, err);
Harmless only because no visitor implements end_union(). Clean it up
anyway, by deleting the function as useless.
Messed up since we have visit_end_union (commit cee2ded).
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1453902888-20457-3-git-send-email-armbru@redhat.com>
[expand scope of patch to delete rather than repair]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1454075341-13658-13-git-send-email-eblake@redhat.com>
2016-01-29 21:48:48 +08:00
|
|
|
* Copyright (C) 2012-2016 Red Hat, Inc.
|
2011-07-20 03:50:32 +08:00
|
|
|
* Copyright IBM, Corp. 2011
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Anthony Liguori <aliguori@us.ibm.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
|
|
|
* See the COPYING.LIB file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-01-30 01:49:57 +08:00
|
|
|
#include "qemu/osdep.h"
|
2012-12-06 18:22:34 +08:00
|
|
|
#include "qemu-common.h"
|
2013-07-08 22:14:21 +08:00
|
|
|
#include "qapi/qmp/qobject.h"
|
2012-12-18 01:19:43 +08:00
|
|
|
#include "qapi/qmp/qerror.h"
|
|
|
|
#include "qapi/visitor.h"
|
|
|
|
#include "qapi/visitor-impl.h"
|
2011-07-20 03:50:32 +08:00
|
|
|
|
|
|
|
void visit_start_struct(Visitor *v, void **obj, const char *kind,
|
|
|
|
const char *name, size_t size, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->start_struct(v, obj, kind, name, size, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_end_struct(Visitor *v, Error **errp)
|
|
|
|
{
|
2012-07-17 22:17:04 +08:00
|
|
|
v->end_struct(v, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
2013-07-03 21:52:42 +08:00
|
|
|
void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
|
|
|
|
Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
if (v->start_implicit_struct) {
|
2013-07-03 21:52:42 +08:00
|
|
|
v->start_implicit_struct(v, obj, size, errp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void visit_end_implicit_struct(Visitor *v, Error **errp)
|
|
|
|
{
|
|
|
|
if (v->end_implicit_struct) {
|
|
|
|
v->end_implicit_struct(v, errp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-20 03:50:32 +08:00
|
|
|
void visit_start_list(Visitor *v, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->start_list(v, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
return v->next_list(v, list, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_end_list(Visitor *v, Error **errp)
|
|
|
|
{
|
2012-07-17 22:17:04 +08:00
|
|
|
v->end_list(v, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
2014-09-19 04:36:40 +08:00
|
|
|
bool visit_start_union(Visitor *v, bool data_present, Error **errp)
|
|
|
|
{
|
|
|
|
if (v->start_union) {
|
|
|
|
return v->start_union(v, data_present, errp);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-02 13:20:53 +08:00
|
|
|
bool visit_optional(Visitor *v, bool *present, const char *name)
|
2011-07-20 03:50:32 +08:00
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
if (v->optional) {
|
2015-12-02 13:20:52 +08:00
|
|
|
v->optional(v, present, name);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
2015-12-02 13:20:53 +08:00
|
|
|
return *present;
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
2015-12-02 13:20:51 +08:00
|
|
|
void visit_get_next_type(Visitor *v, QType *type, bool promote_int,
|
2013-07-08 22:14:21 +08:00
|
|
|
const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
if (v->get_next_type) {
|
2015-12-02 13:20:51 +08:00
|
|
|
v->get_next_type(v, type, promote_int, name, errp);
|
2013-07-08 22:14:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-14 00:14:07 +08:00
|
|
|
void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
|
2011-07-20 03:50:32 +08:00
|
|
|
const char *kind, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->type_enum(v, obj, strings, kind, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Prefer type_int64 over type_int in visitors
The qapi builtin type 'int' is basically shorthand for the type
'int64'. In fact, since no visitor was providing the optional
type_int64() callback, visit_type_int64() was just always falling
back to type_int(), cementing the equivalence between the types.
However, some visitors are providing a type_uint64() callback.
For purposes of code consistency, it is nicer if all visitors
use the paired type_int64/type_uint64 names rather than the
mismatched type_int/type_uint64. So this patch just renames
the signed int callbacks in place, dropping the type_int()
callback as redundant, and a later patch will focus on the
unsigned int callbacks.
Add some FIXMEs to questionable reuse of errp in code touched
by the rename, while at it (the reuse works as long as the
callbacks don't modify value when setting an error, but it's not
a good example to set) - a later patch will then fix those.
No change in functionality here, although further cleanups are
in the pipeline.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1454075341-13658-14-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-01-29 21:48:49 +08:00
|
|
|
v->type_int64(v, obj, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
static void visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
|
|
|
|
uint64_t max, const char *type, Error **errp)
|
|
|
|
{
|
|
|
|
Error *err = NULL;
|
|
|
|
uint64_t value = *obj;
|
|
|
|
|
|
|
|
v->type_uint64(v, &value, name, &err);
|
|
|
|
if (err) {
|
|
|
|
error_propagate(errp, err);
|
|
|
|
} else if (value > max) {
|
|
|
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
|
|
|
name ? name : "null", type);
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
} else {
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
|
2011-08-25 23:44:50 +08:00
|
|
|
{
|
2016-01-29 21:48:51 +08:00
|
|
|
uint64_t value = *obj;
|
|
|
|
visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name,
|
|
|
|
Error **errp)
|
2011-08-25 23:44:50 +08:00
|
|
|
{
|
2016-01-29 21:48:51 +08:00
|
|
|
uint64_t value = *obj;
|
|
|
|
visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
|
|
|
|
*obj = value;
|
|
|
|
}
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
uint64_t value = *obj;
|
|
|
|
visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name,
|
|
|
|
Error **errp)
|
2011-08-25 23:44:50 +08:00
|
|
|
{
|
qapi: Make all visitors supply uint64 callbacks
Our qapi visitor contract supports multiple integer visitors,
but left the type_uint64 visitor as optional (falling back on
type_int64); which in turn can lead to awkward behavior with
numbers larger than INT64_MAX (the user has to be aware of
twos complement, and deal with negatives).
This patch does not address the disparity in handling large
values as negatives. It merely moves the fallback from uint64
to int64 from the visitor core to the visitors, where the issue
can actually be fixed, by implementing the missing type_uint64()
callbacks on top of the respective type_int64() callbacks, and
with a FIXME comment explaining why that's wrong.
With that done, we now have a type_uint64() callback in every
driver, so we can make it mandatory from the core. And although
the type_int64() callback can cover the entire valid range of
type_uint{8,16,32} on valid user input, using type_uint64() to
avoid mixed signedness makes more sense.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1454075341-13658-15-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-01-29 21:48:50 +08:00
|
|
|
v->type_uint64(v, obj, name, errp);
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
static void visit_type_intN(Visitor *v, int64_t *obj, const char *name,
|
|
|
|
int64_t min, int64_t max, const char *type,
|
|
|
|
Error **errp)
|
2011-08-25 23:44:50 +08:00
|
|
|
{
|
2016-01-29 21:48:51 +08:00
|
|
|
Error *err = NULL;
|
|
|
|
int64_t value = *obj;
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
v->type_int64(v, &value, name, &err);
|
|
|
|
if (err) {
|
|
|
|
error_propagate(errp, err);
|
|
|
|
} else if (value < min || value > max) {
|
|
|
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
|
|
|
name ? name : "null", type);
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
} else {
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
|
2011-08-25 23:44:50 +08:00
|
|
|
{
|
2016-01-29 21:48:51 +08:00
|
|
|
int64_t value = *obj;
|
|
|
|
visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
|
|
|
|
*obj = value;
|
|
|
|
}
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
|
2016-01-29 21:48:51 +08:00
|
|
|
void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
|
|
|
|
{
|
|
|
|
int64_t value = *obj;
|
|
|
|
visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t", errp);
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
|
|
|
|
{
|
2016-01-29 21:48:51 +08:00
|
|
|
int64_t value = *obj;
|
|
|
|
visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t", errp);
|
|
|
|
*obj = value;
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Prefer type_int64 over type_int in visitors
The qapi builtin type 'int' is basically shorthand for the type
'int64'. In fact, since no visitor was providing the optional
type_int64() callback, visit_type_int64() was just always falling
back to type_int(), cementing the equivalence between the types.
However, some visitors are providing a type_uint64() callback.
For purposes of code consistency, it is nicer if all visitors
use the paired type_int64/type_uint64 names rather than the
mismatched type_int/type_uint64. So this patch just renames
the signed int callbacks in place, dropping the type_int()
callback as redundant, and a later patch will focus on the
unsigned int callbacks.
Add some FIXMEs to questionable reuse of errp in code touched
by the rename, while at it (the reuse works as long as the
callbacks don't modify value when setting an error, but it's not
a good example to set) - a later patch will then fix those.
No change in functionality here, although further cleanups are
in the pipeline.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1454075341-13658-14-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-01-29 21:48:49 +08:00
|
|
|
v->type_int64(v, obj, name, errp);
|
2011-08-25 23:44:50 +08:00
|
|
|
}
|
|
|
|
|
2012-07-17 22:17:07 +08:00
|
|
|
void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
if (v->type_size) {
|
|
|
|
v->type_size(v, obj, name, errp);
|
|
|
|
} else {
|
qapi: Make all visitors supply uint64 callbacks
Our qapi visitor contract supports multiple integer visitors,
but left the type_uint64 visitor as optional (falling back on
type_int64); which in turn can lead to awkward behavior with
numbers larger than INT64_MAX (the user has to be aware of
twos complement, and deal with negatives).
This patch does not address the disparity in handling large
values as negatives. It merely moves the fallback from uint64
to int64 from the visitor core to the visitors, where the issue
can actually be fixed, by implementing the missing type_uint64()
callbacks on top of the respective type_int64() callbacks, and
with a FIXME comment explaining why that's wrong.
With that done, we now have a type_uint64() callback in every
driver, so we can make it mandatory from the core. And although
the type_int64() callback can cover the entire valid range of
type_uint{8,16,32} on valid user input, using type_uint64() to
avoid mixed signedness makes more sense.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1454075341-13658-15-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-01-29 21:48:50 +08:00
|
|
|
v->type_uint64(v, obj, name, errp);
|
2012-07-17 22:17:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-20 03:50:32 +08:00
|
|
|
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->type_bool(v, obj, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->type_str(v, obj, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
v->type_number(v, obj, name, errp);
|
2011-07-20 03:50:32 +08:00
|
|
|
}
|
2012-02-09 16:11:52 +08:00
|
|
|
|
2015-09-16 19:06:24 +08:00
|
|
|
void visit_type_any(Visitor *v, QObject **obj, const char *name,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
v->type_any(v, obj, name, errp);
|
|
|
|
}
|
|
|
|
|
2015-05-14 00:14:07 +08:00
|
|
|
void output_type_enum(Visitor *v, int *obj, const char * const strings[],
|
2012-02-09 16:11:52 +08:00
|
|
|
const char *kind, const char *name,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
int value = *obj;
|
|
|
|
char *enum_str;
|
|
|
|
|
|
|
|
assert(strings);
|
|
|
|
while (strings[i++] != NULL);
|
|
|
|
if (value < 0 || value >= i - 1) {
|
2015-03-17 18:54:50 +08:00
|
|
|
error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
|
2012-02-09 16:11:52 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum_str = (char *)strings[value];
|
|
|
|
visit_type_str(v, &enum_str, name, errp);
|
|
|
|
}
|
|
|
|
|
2015-05-14 00:14:07 +08:00
|
|
|
void input_type_enum(Visitor *v, int *obj, const char * const strings[],
|
2012-02-09 16:11:52 +08:00
|
|
|
const char *kind, const char *name,
|
|
|
|
Error **errp)
|
|
|
|
{
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
Error *local_err = NULL;
|
2012-02-09 16:11:52 +08:00
|
|
|
int64_t value = 0;
|
|
|
|
char *enum_str;
|
|
|
|
|
|
|
|
assert(strings);
|
|
|
|
|
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:
err = NULL;
foo(..., &err);
if (err) {
goto out;
}
bar(..., &err);
Every error source is checked separately. The second function is only
called when the first one succeeds. Both functions are free to pass
their argument to error_set(). Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.
The qapi-generated code uses the error API differently:
// *errp was initialized to NULL somewhere up the call chain
frob(..., errp);
gnat(..., errp);
Errors accumulate in *errp: first error wins, subsequent errors get
dropped. To make this work, the second function does nothing when
called with an error set. Requires non-null errp, or else the second
function can't see the first one fail.
This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().
With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee. Can be
nice.
However, mixing the two techniques is confusing. You can't use the
"accumulate" technique with functions designed for the "check
separately" technique. You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.
Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-07 15:53:54 +08:00
|
|
|
visit_type_str(v, &enum_str, name, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_propagate(errp, local_err);
|
2012-02-09 16:11:52 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (strings[value] != NULL) {
|
|
|
|
if (strcmp(strings[value], enum_str) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
value++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strings[value] == NULL) {
|
2015-03-17 18:54:50 +08:00
|
|
|
error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
|
2012-02-09 16:11:52 +08:00
|
|
|
g_free(enum_str);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(enum_str);
|
|
|
|
*obj = value;
|
|
|
|
}
|