Markus Armbruster
2021-Oct-09 12:09 UTC
[Libguestfs] [PATCH v2 4/5] qapi: Implement deprecated-input={reject, crash} for enum values
This copies the code implementing the policy from qapi/qmp-dispatch.c to qapi/qobject-input-visitor.c. Tolerable, but if we acquire more copes, we should look into factoring them out. Signed-off-by: Markus Armbruster <armbru at redhat.com> --- docs/devel/qapi-code-gen.rst | 6 ++++-- qapi/compat.json | 3 ++- include/qapi/util.h | 6 +++++- qapi/qapi-visit-core.c | 18 +++++++++++++++--- scripts/qapi/types.py | 17 ++++++++++++++++- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index 00334e9fb8..006a6f4a9a 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -708,8 +708,10 @@ QEMU shows a certain behaviour. Special features ~~~~~~~~~~~~~~~~ -Feature "deprecated" marks a command, event, or struct member as -deprecated. It is not supported elsewhere so far. +Feature "deprecated" marks a command, event, struct or enum member as +deprecated. It is not supported elsewhere so far. Interfaces so +marked may be withdrawn in future releases in accordance with QEMU's +deprecation policy. Naming rules and reserved names diff --git a/qapi/compat.json b/qapi/compat.json index 1d2b76f00c..74a8493d3d 100644 --- a/qapi/compat.json +++ b/qapi/compat.json @@ -42,7 +42,8 @@ # with feature 'deprecated'. We may want to extend it to cover # semantic aspects, CLI, and experimental features. # -# Limitation: not implemented for deprecated enumeration values. +# Limitation: deprecated-output policy @hide is not implemented for +# enumeration values. They behave the same as with policy @accept. # # @deprecated-input: how to handle deprecated input (default 'accept') # @deprecated-output: how to handle deprecated output (default 'accept') diff --git a/include/qapi/util.h b/include/qapi/util.h index d7bfb30e25..257c600f99 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -11,9 +11,13 @@ #ifndef QAPI_UTIL_H #define QAPI_UTIL_H +/* QEnumLookup flags */ +#define QAPI_ENUM_DEPRECATED 1 + typedef struct QEnumLookup { const char *const *array; - int size; + const unsigned char *const flags; + const int size; } QEnumLookup; const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 066f77a26d..49136ae88e 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -393,7 +393,7 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, const QEnumLookup *lookup, Error **errp) { int64_t value; - char *enum_str; + g_autofree char *enum_str = NULL; if (!visit_type_str(v, name, &enum_str, errp)) { return false; @@ -402,11 +402,23 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, value = qapi_enum_parse(lookup, enum_str, -1, NULL); if (value < 0) { error_setg(errp, QERR_INVALID_PARAMETER, enum_str); - g_free(enum_str); return false; } - g_free(enum_str); + if (lookup->flags && (lookup->flags[value] & QAPI_ENUM_DEPRECATED)) { + switch (v->compat_policy.deprecated_input) { + case COMPAT_POLICY_INPUT_ACCEPT: + break; + case COMPAT_POLICY_INPUT_REJECT: + error_setg(errp, "Deprecated value '%s' disabled by policy", + enum_str); + return false; + case COMPAT_POLICY_INPUT_CRASH: + default: + abort(); + } + } + *obj = value; return true; } diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 831294fe42..ab2441adc9 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -38,6 +38,8 @@ def gen_enum_lookup(name: str, members: List[QAPISchemaEnumMember], prefix: Optional[str] = None) -> str: + max_index = c_enum_const(name, '_MAX', prefix) + flags = '' ret = mcgen(''' const QEnumLookup %(c_name)s_lookup = { @@ -52,13 +54,26 @@ def gen_enum_lookup(name: str, ''', index=index, name=memb.name) ret += memb.ifcond.gen_endif() + if 'deprecated' in (f.name for f in memb.features): + flags += mcgen(''' + [%(index)s] = QAPI_ENUM_DEPRECATED, +''', + index=index) + + if flags: + ret += mcgen(''' + }, + .flags = (const unsigned char[%(max_index)s]) { +''', + max_index=max_index) + ret += flags ret += mcgen(''' }, .size = %(max_index)s }; ''', - max_index=c_enum_const(name, '_MAX', prefix)) + max_index=max_index) return ret -- 2.31.1
Eric Blake
2021-Oct-11 18:53 UTC
[Libguestfs] [PATCH v2 4/5] qapi: Implement deprecated-input={reject, crash} for enum values
On Sat, Oct 09, 2021 at 02:09:43PM +0200, Markus Armbruster wrote:> This copies the code implementing the policy from qapi/qmp-dispatch.c > to qapi/qobject-input-visitor.c. Tolerable, but if we acquire more > copes, we should look into factoring them out.copies> > Signed-off-by: Markus Armbruster <armbru at redhat.com> > --- > docs/devel/qapi-code-gen.rst | 6 ++++-- > qapi/compat.json | 3 ++- > include/qapi/util.h | 6 +++++- > qapi/qapi-visit-core.c | 18 +++++++++++++++--- > scripts/qapi/types.py | 17 ++++++++++++++++- > 5 files changed, 42 insertions(+), 8 deletions(-) > > diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst > index 00334e9fb8..006a6f4a9a 100644 > --- a/docs/devel/qapi-code-gen.rst > +++ b/docs/devel/qapi-code-gen.rst > @@ -708,8 +708,10 @@ QEMU shows a certain behaviour. > Special features > ~~~~~~~~~~~~~~~~ > > -Feature "deprecated" marks a command, event, or struct member as > -deprecated. It is not supported elsewhere so far. > +Feature "deprecated" marks a command, event, struct or enum member asDo we want the comma before the conjunction? (I've seen style guides that recommend it, and style guides that discourage it; while I tend to write by the former style, I usually don't care about the latter. Rather, switching styles mid-patch caught my attention).> +deprecated. It is not supported elsewhere so far. Interfaces so > +marked may be withdrawn in future releases in accordance with QEMU's > +deprecation policy. > > > +++ b/qapi/qapi-visit-core.c > @@ -393,7 +393,7 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, > const QEnumLookup *lookup, Error **errp) > { > int64_t value; > - char *enum_str; > + g_autofree char *enum_str = NULL;Nice change while touching the code. Is it worth mentioning in the commit message?> > if (!visit_type_str(v, name, &enum_str, errp)) { > return false; > @@ -402,11 +402,23 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, > value = qapi_enum_parse(lookup, enum_str, -1, NULL); > if (value < 0) { > error_setg(errp, QERR_INVALID_PARAMETER, enum_str); > - g_free(enum_str); > return false; > } > > - g_free(enum_str); > + if (lookup->flags && (lookup->flags[value] & QAPI_ENUM_DEPRECATED)) { > + switch (v->compat_policy.deprecated_input) { > + case COMPAT_POLICY_INPUT_ACCEPT: > + break; > + case COMPAT_POLICY_INPUT_REJECT: > + error_setg(errp, "Deprecated value '%s' disabled by policy", > + enum_str); > + return false; > + case COMPAT_POLICY_INPUT_CRASH: > + default: > + abort(); > + } > + } > + > *obj = value; > return true; > }Grammar fixes are minor, so: Reviewed-by: Eric Blake <eblake at redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org