mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-10-27' into staging
QAPI patches patches for 2021-10-27 # gpg: Signature made Wed 27 Oct 2021 08:21:54 AM PDT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] * remotes/armbru/tags/pull-qapi-2021-10-27: qapi: Implement deprecated-input={reject,crash} for enum values qapi: Move compat policy from QObject to generic visitor qapi: Add feature flags to enum members qapi: Enable enum member introspection to show more than name qapi: Improve input_type_enum()'s error message Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -228,6 +228,12 @@ Use the more generic commands ``block-export-add`` and ``block-export-del``
|
||||
instead. As part of this deprecation, where ``nbd-server-add`` used a
|
||||
single ``bitmap``, the new ``block-export-add`` uses a list of ``bitmaps``.
|
||||
|
||||
``query-qmp-schema`` return value member ``values`` (since 6.2)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Member ``values`` in return value elements with meta-type ``enum`` is
|
||||
deprecated. Use ``members`` instead.
|
||||
|
||||
System accelerators
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -200,7 +200,9 @@ Syntax::
|
||||
'*if': COND,
|
||||
'*features': FEATURES }
|
||||
ENUM-VALUE = STRING
|
||||
| { 'name': STRING, '*if': COND }
|
||||
| { 'name': STRING,
|
||||
'*if': COND,
|
||||
'*features': FEATURES }
|
||||
|
||||
Member 'enum' names the enum type.
|
||||
|
||||
@@ -706,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, enum value, or struct
|
||||
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
|
||||
@@ -1157,7 +1161,8 @@ and "variants".
|
||||
|
||||
"members" is a JSON array describing the object's common members, if
|
||||
any. Each element is a JSON object with members "name" (the member's
|
||||
name), "type" (the name of its type), and optionally "default". The
|
||||
name), "type" (the name of its type), "features" (a JSON array of
|
||||
feature strings), and "default". The latter two are optional. The
|
||||
member is optional if "default" is present. Currently, "default" can
|
||||
only have value null. Other values are reserved for future
|
||||
extensions. The "members" array is in no particular order; clients
|
||||
@@ -1231,14 +1236,22 @@ Example: the SchemaInfo for ['str'] ::
|
||||
"element-type": "str" }
|
||||
|
||||
The SchemaInfo for an enumeration type has meta-type "enum" and
|
||||
variant member "values". The values are listed in no particular
|
||||
order; clients must search the entire enum when learning whether a
|
||||
particular value is supported.
|
||||
variant member "members".
|
||||
|
||||
"members" is a JSON array describing the enumeration values. Each
|
||||
element is a JSON object with member "name" (the member's name), and
|
||||
optionally "features" (a JSON array of feature strings). The
|
||||
"members" array is in no particular order; clients must search the
|
||||
entire array when learning whether a particular value is supported.
|
||||
|
||||
Example: the SchemaInfo for MyEnum from section `Enumeration types`_ ::
|
||||
|
||||
{ "name": "MyEnum", "meta-type": "enum",
|
||||
"values": [ "value1", "value2", "value3" ] }
|
||||
"members": [
|
||||
{ "name": "value1" },
|
||||
{ "name": "value2" },
|
||||
{ "name": "value3" }
|
||||
] }
|
||||
|
||||
The SchemaInfo for a built-in type has the same name as the type in
|
||||
the QAPI schema (see section `Built-in Types`_), with one exception
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#ifndef QOBJECT_INPUT_VISITOR_H
|
||||
#define QOBJECT_INPUT_VISITOR_H
|
||||
|
||||
#include "qapi/qapi-types-compat.h"
|
||||
#include "qapi/visitor.h"
|
||||
|
||||
typedef struct QObjectInputVisitor QObjectInputVisitor;
|
||||
@@ -59,9 +58,6 @@ typedef struct QObjectInputVisitor QObjectInputVisitor;
|
||||
*/
|
||||
Visitor *qobject_input_visitor_new(QObject *obj);
|
||||
|
||||
void qobject_input_visitor_set_policy(Visitor *v,
|
||||
CompatPolicyInput deprecated);
|
||||
|
||||
/*
|
||||
* Create a QObject input visitor for @obj for use with keyval_parse()
|
||||
*
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#define QOBJECT_OUTPUT_VISITOR_H
|
||||
|
||||
#include "qapi/visitor.h"
|
||||
#include "qapi/qapi-types-compat.h"
|
||||
|
||||
typedef struct QObjectOutputVisitor QObjectOutputVisitor;
|
||||
|
||||
@@ -54,7 +53,4 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
|
||||
*/
|
||||
Visitor *qobject_output_visitor_new(QObject **result);
|
||||
|
||||
void qobject_output_visitor_set_policy(Visitor *v,
|
||||
CompatPolicyOutput deprecated);
|
||||
|
||||
#endif
|
||||
|
||||
+5
-1
@@ -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);
|
||||
|
||||
@@ -122,6 +122,9 @@ struct Visitor
|
||||
/* Must be set */
|
||||
VisitorType type;
|
||||
|
||||
/* Optional */
|
||||
struct CompatPolicy compat_policy;
|
||||
|
||||
/* Must be set for output visitors, optional otherwise. */
|
||||
void (*complete)(Visitor *v, void *opaque);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define QAPI_VISITOR_H
|
||||
|
||||
#include "qapi/qapi-builtin-types.h"
|
||||
#include "qapi/qapi-types-compat.h"
|
||||
|
||||
/*
|
||||
* The QAPI schema defines both a set of C data types, and a QMP wire
|
||||
@@ -477,6 +478,14 @@ bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp);
|
||||
*/
|
||||
bool visit_deprecated(Visitor *v, const char *name);
|
||||
|
||||
/*
|
||||
* Set policy for handling deprecated management interfaces.
|
||||
*
|
||||
* Intended use: call visit_set_policy(v, &compat_policy) when
|
||||
* visiting management interface input or output.
|
||||
*/
|
||||
void visit_set_policy(Visitor *v, CompatPolicy *policy);
|
||||
|
||||
/*
|
||||
* Visit an enum value.
|
||||
*
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
# with feature 'deprecated'. We may want to extend it to cover
|
||||
# semantic aspects, CLI, and experimental features.
|
||||
#
|
||||
# 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')
|
||||
#
|
||||
|
||||
+26
-2
@@ -142,14 +142,38 @@
|
||||
#
|
||||
# Additional SchemaInfo members for meta-type 'enum'.
|
||||
#
|
||||
# @values: the enumeration type's values, in no particular order.
|
||||
# @members: the enum type's members, in no particular order
|
||||
# (since 6.2).
|
||||
#
|
||||
# @values: the enumeration type's member names, in no particular order.
|
||||
# Redundant with @members. Just for backward compatibility.
|
||||
#
|
||||
# Features:
|
||||
# @deprecated: Member @values is deprecated. Use @members instead.
|
||||
#
|
||||
# Values of this type are JSON string on the wire.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'struct': 'SchemaInfoEnum',
|
||||
'data': { 'values': ['str'] } }
|
||||
'data': { 'members': [ 'SchemaInfoEnumMember' ],
|
||||
'values': { 'type': [ 'str' ],
|
||||
'features': [ 'deprecated' ] } } }
|
||||
|
||||
##
|
||||
# @SchemaInfoEnumMember:
|
||||
#
|
||||
# An object member.
|
||||
#
|
||||
# @name: the member's name, as defined in the QAPI schema.
|
||||
#
|
||||
# @features: names of features associated with the member, in no
|
||||
# particular order.
|
||||
#
|
||||
# Since: 6.2
|
||||
##
|
||||
{ 'struct': 'SchemaInfoEnumMember',
|
||||
'data': { 'name': 'str', '*features': [ 'str' ] } }
|
||||
|
||||
##
|
||||
# @SchemaInfoArray:
|
||||
|
||||
+26
-4
@@ -19,6 +19,10 @@
|
||||
#include "qapi/visitor-impl.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Zero-initialization must result in default policy */
|
||||
QEMU_BUILD_BUG_ON(COMPAT_POLICY_INPUT_ACCEPT || COMPAT_POLICY_OUTPUT_ACCEPT);
|
||||
|
||||
|
||||
void visit_complete(Visitor *v, void *opaque)
|
||||
{
|
||||
assert(v->type != VISITOR_OUTPUT || v->complete);
|
||||
@@ -153,6 +157,11 @@ bool visit_deprecated(Visitor *v, const char *name)
|
||||
return true;
|
||||
}
|
||||
|
||||
void visit_set_policy(Visitor *v, CompatPolicy *policy)
|
||||
{
|
||||
v->compat_policy = *policy;
|
||||
}
|
||||
|
||||
bool visit_is_input(Visitor *v)
|
||||
{
|
||||
return v->type == VISITOR_INPUT;
|
||||
@@ -384,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;
|
||||
@@ -392,12 +401,25 @@ 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);
|
||||
error_setg(errp, "Parameter '%s' does not accept value '%s'",
|
||||
name ? name : "null", 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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ Visitor *qobject_input_visitor_new_qmp(QObject *obj)
|
||||
{
|
||||
Visitor *v = qobject_input_visitor_new(obj);
|
||||
|
||||
qobject_input_visitor_set_policy(v, compat_policy.deprecated_input);
|
||||
visit_set_policy(v, &compat_policy);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ Visitor *qobject_output_visitor_new_qmp(QObject **result)
|
||||
{
|
||||
Visitor *v = qobject_output_visitor_new(result);
|
||||
|
||||
qobject_output_visitor_set_policy(v, compat_policy.deprecated_output);
|
||||
visit_set_policy(v, &compat_policy);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <math.h>
|
||||
#include "qapi/compat-policy.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/visitor-impl.h"
|
||||
@@ -44,7 +43,6 @@ typedef struct StackObject {
|
||||
|
||||
struct QObjectInputVisitor {
|
||||
Visitor visitor;
|
||||
CompatPolicyInput deprecated_policy;
|
||||
|
||||
/* Root of visit at visitor creation. */
|
||||
QObject *root;
|
||||
@@ -667,9 +665,7 @@ static void qobject_input_optional(Visitor *v, const char *name, bool *present)
|
||||
static bool qobject_input_deprecated_accept(Visitor *v, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
QObjectInputVisitor *qiv = to_qiv(v);
|
||||
|
||||
switch (qiv->deprecated_policy) {
|
||||
switch (v->compat_policy.deprecated_input) {
|
||||
case COMPAT_POLICY_INPUT_ACCEPT:
|
||||
return true;
|
||||
case COMPAT_POLICY_INPUT_REJECT:
|
||||
@@ -739,14 +735,6 @@ Visitor *qobject_input_visitor_new(QObject *obj)
|
||||
return &v->visitor;
|
||||
}
|
||||
|
||||
void qobject_input_visitor_set_policy(Visitor *v,
|
||||
CompatPolicyInput deprecated)
|
||||
{
|
||||
QObjectInputVisitor *qiv = to_qiv(v);
|
||||
|
||||
qiv->deprecated_policy = deprecated;
|
||||
}
|
||||
|
||||
Visitor *qobject_input_visitor_new_keyval(QObject *obj)
|
||||
{
|
||||
QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/compat-policy.h"
|
||||
#include "qapi/qobject-output-visitor.h"
|
||||
#include "qapi/visitor-impl.h"
|
||||
#include "qemu/queue.h"
|
||||
@@ -32,7 +31,6 @@ typedef struct QStackEntry {
|
||||
|
||||
struct QObjectOutputVisitor {
|
||||
Visitor visitor;
|
||||
CompatPolicyOutput deprecated_policy;
|
||||
|
||||
QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
|
||||
QObject *root; /* Root of the output visit */
|
||||
@@ -212,9 +210,7 @@ static bool qobject_output_type_null(Visitor *v, const char *name,
|
||||
|
||||
static bool qobject_output_deprecated(Visitor *v, const char *name)
|
||||
{
|
||||
QObjectOutputVisitor *qov = to_qov(v);
|
||||
|
||||
return qov->deprecated_policy != COMPAT_POLICY_OUTPUT_HIDE;
|
||||
return v->compat_policy.deprecated_output != COMPAT_POLICY_OUTPUT_HIDE;
|
||||
}
|
||||
|
||||
/* Finish building, and return the root object.
|
||||
@@ -275,11 +271,3 @@ Visitor *qobject_output_visitor_new(QObject **result)
|
||||
|
||||
return &v->visitor;
|
||||
}
|
||||
|
||||
void qobject_output_visitor_set_policy(Visitor *v,
|
||||
CompatPolicyOutput deprecated)
|
||||
{
|
||||
QObjectOutputVisitor *qov = to_qov(v);
|
||||
|
||||
qov->deprecated_policy = deprecated;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
for m in members]
|
||||
for member in members:
|
||||
source = "'data' member"
|
||||
check_keys(member, info, source, ['name'], ['if'])
|
||||
check_keys(member, info, source, ['name'], ['if', 'features'])
|
||||
member_name = member['name']
|
||||
check_name_is_str(member_name, info, source)
|
||||
source = "%s '%s'" % (source, member_name)
|
||||
@@ -483,6 +483,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
permit_upper=permissive,
|
||||
permit_underscore=permissive)
|
||||
check_if(member, info, source)
|
||||
check_features(member.get('features'), info)
|
||||
|
||||
|
||||
def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
|
||||
@@ -68,6 +68,7 @@ JSONValue = Union[_Value, 'Annotated[_Value]']
|
||||
# TypedDict constructs, so they are broadly typed here as simple
|
||||
# Python Dicts.
|
||||
SchemaInfo = Dict[str, object]
|
||||
SchemaInfoEnumMember = Dict[str, object]
|
||||
SchemaInfoObject = Dict[str, object]
|
||||
SchemaInfoObjectVariant = Dict[str, object]
|
||||
SchemaInfoObjectMember = Dict[str, object]
|
||||
@@ -274,8 +275,17 @@ const QLitObject %(c_name)s = %(c_string)s;
|
||||
obj['features'] = self._gen_features(features)
|
||||
self._trees.append(Annotated(obj, ifcond, comment))
|
||||
|
||||
def _gen_member(self, member: QAPISchemaObjectTypeMember
|
||||
) -> Annotated[SchemaInfoObjectMember]:
|
||||
def _gen_enum_member(self, member: QAPISchemaEnumMember
|
||||
) -> Annotated[SchemaInfoEnumMember]:
|
||||
obj: SchemaInfoEnumMember = {
|
||||
'name': member.name,
|
||||
}
|
||||
if member.features:
|
||||
obj['features'] = self._gen_features(member.features)
|
||||
return Annotated(obj, member.ifcond)
|
||||
|
||||
def _gen_object_member(self, member: QAPISchemaObjectTypeMember
|
||||
) -> Annotated[SchemaInfoObjectMember]:
|
||||
obj: SchemaInfoObjectMember = {
|
||||
'name': member.name,
|
||||
'type': self._use_type(member.type)
|
||||
@@ -305,7 +315,8 @@ const QLitObject %(c_name)s = %(c_string)s;
|
||||
prefix: Optional[str]) -> None:
|
||||
self._gen_tree(
|
||||
name, 'enum',
|
||||
{'values': [Annotated(m.name, m.ifcond) for m in members]},
|
||||
{'members': [self._gen_enum_member(m) for m in members],
|
||||
'values': [Annotated(m.name, m.ifcond) for m in members]},
|
||||
ifcond, features
|
||||
)
|
||||
|
||||
@@ -322,7 +333,7 @@ const QLitObject %(c_name)s = %(c_string)s;
|
||||
members: List[QAPISchemaObjectTypeMember],
|
||||
variants: Optional[QAPISchemaVariants]) -> None:
|
||||
obj: SchemaInfoObject = {
|
||||
'members': [self._gen_member(m) for m in members]
|
||||
'members': [self._gen_object_member(m) for m in members]
|
||||
}
|
||||
if variants:
|
||||
obj['tag'] = variants.tag_member.name
|
||||
|
||||
+20
-2
@@ -708,6 +708,19 @@ class QAPISchemaMember:
|
||||
class QAPISchemaEnumMember(QAPISchemaMember):
|
||||
role = 'value'
|
||||
|
||||
def __init__(self, name, info, ifcond=None, features=None):
|
||||
super().__init__(name, info, ifcond)
|
||||
for f in features or []:
|
||||
assert isinstance(f, QAPISchemaFeature)
|
||||
f.set_defined_in(name)
|
||||
self.features = features or []
|
||||
|
||||
def connect_doc(self, doc):
|
||||
super().connect_doc(doc)
|
||||
if doc:
|
||||
for f in self.features:
|
||||
doc.connect_feature(f)
|
||||
|
||||
|
||||
class QAPISchemaFeature(QAPISchemaMember):
|
||||
role = 'feature'
|
||||
@@ -980,9 +993,14 @@ class QAPISchema:
|
||||
QAPISchemaIfCond(f.get('if')))
|
||||
for f in features]
|
||||
|
||||
def _make_enum_member(self, name, ifcond, features, info):
|
||||
return QAPISchemaEnumMember(name, info,
|
||||
QAPISchemaIfCond(ifcond),
|
||||
self._make_features(features, info))
|
||||
|
||||
def _make_enum_members(self, values, info):
|
||||
return [QAPISchemaEnumMember(v['name'], info,
|
||||
QAPISchemaIfCond(v.get('if')))
|
||||
return [self._make_enum_member(v['name'], v.get('if'),
|
||||
v.get('features'), info)
|
||||
for v in values]
|
||||
|
||||
def _make_array_type(self, element_type, info):
|
||||
|
||||
+16
-1
@@ -38,6 +38,8 @@ objects_seen = set()
|
||||
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 @@ const QEnumLookup %(c_name)s_lookup = {
|
||||
''',
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -58,11 +58,14 @@
|
||||
#
|
||||
# Features:
|
||||
# @enum-feat: Also _one_ {and only}
|
||||
# @enum-member-feat: a member feature
|
||||
#
|
||||
# @two is undocumented
|
||||
##
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
|
||||
'data': [ { 'name': 'one', 'if': 'IFONE',
|
||||
'features': [ 'enum-member-feat' ] },
|
||||
'two' ],
|
||||
'features': [ 'enum-feat' ],
|
||||
'if': 'IFCOND' }
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ module doc-good.json
|
||||
enum Enum
|
||||
member one
|
||||
if IFONE
|
||||
feature enum-member-feat
|
||||
member two
|
||||
if IFCOND
|
||||
feature enum-feat
|
||||
@@ -108,6 +109,8 @@ The _one_ {and only}
|
||||
|
||||
feature=enum-feat
|
||||
Also _one_ {and only}
|
||||
feature=enum-member-feat
|
||||
a member feature
|
||||
section=None
|
||||
@two is undocumented
|
||||
doc symbol=Base
|
||||
|
||||
@@ -56,6 +56,9 @@ Features
|
||||
"enum-feat"
|
||||
Also _one_ {and only}
|
||||
|
||||
"enum-member-feat"
|
||||
a member feature
|
||||
|
||||
"two" is undocumented
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user