From 597494abdefc68991b41cfda03801a496c9fcc4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 25 Jan 2017 17:03:07 +0400 Subject: [PATCH 01/49] qapi2texi: change texi formatters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STRUCT_FMT is generic enough, rename it to TYPE_FMT, use it for unions. Rename COMMAND_FMT to MSG_FMT, since it applies to both commands and events. Signed-off-by: Marc-André Lureau Message-Id: <20170125130308.16104-2-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi2texi.py | 46 ++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index c1071c62c6..69f5edce4d 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -9,7 +9,7 @@ import qapi -COMMAND_FMT = """ +MSG_FMT = """ @deftypefn {type} {{}} {name} {body} @@ -18,16 +18,7 @@ """.format -ENUM_FMT = """ -@deftp Enum {name} - -{body} - -@end deftp - -""".format - -STRUCT_FMT = """ +TYPE_FMT = """ @deftp {{{type}}} {name} {body} @@ -170,9 +161,9 @@ def texi_body(doc): def texi_alternate(expr, doc): """Format an alternate to texi""" body = texi_body(doc) - return STRUCT_FMT(type="Alternate", - name=doc.symbol, - body=body) + return TYPE_FMT(type="Alternate", + name=doc.symbol, + body=body) def texi_union(expr, doc): @@ -184,9 +175,9 @@ def texi_union(expr, doc): union = "Simple Union" body = texi_body(doc) - return STRUCT_FMT(type=union, - name=doc.symbol, - body=body) + return TYPE_FMT(type=union, + name=doc.symbol, + body=body) def texi_enum(expr, doc): @@ -195,32 +186,33 @@ def texi_enum(expr, doc): if i not in doc.args: doc.args[i] = '' body = texi_body(doc) - return ENUM_FMT(name=doc.symbol, + return TYPE_FMT(type="Enum", + name=doc.symbol, body=body) def texi_struct(expr, doc): """Format a struct to texi""" body = texi_body(doc) - return STRUCT_FMT(type="Struct", - name=doc.symbol, - body=body) + return TYPE_FMT(type="Struct", + name=doc.symbol, + body=body) def texi_command(expr, doc): """Format a command to texi""" body = texi_body(doc) - return COMMAND_FMT(type="Command", - name=doc.symbol, - body=body) + return MSG_FMT(type="Command", + name=doc.symbol, + body=body) def texi_event(expr, doc): """Format an event to texi""" body = texi_body(doc) - return COMMAND_FMT(type="Event", - name=doc.symbol, - body=body) + return MSG_FMT(type="Event", + name=doc.symbol, + body=body) def texi_expr(expr, doc): From f880cd6b6f3fe7847cde3bec1fa98891c92229d2 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 2 Mar 2017 12:24:29 +0000 Subject: [PATCH 02/49] qmp: allow setting properties to empty string in qmp-shell The qmp-shell property parser currently rejects attempts to set string properties to the empty string eg (QEMU) migrate-set-parameters tls-hostname= Error while parsing command line: Expected a key=value pair, got 'tls-hostname=' command format: [arg-name1=arg1] ... [arg-nameN=argN] This is caused by checking the wrong condition after splitting the parameter on '='. The "partition" method will return "" for the separator field, if the seperator was not present, so that is the correct thing to check for malformed syntax. Signed-off-by: Daniel P. Berrange Message-Id: <20170302122429.7737-1-berrange@redhat.com> Reviewed-by: Eric Blake Reviewed-by: John Snow Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 0373b24b20..eccb88a4e8 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -166,8 +166,8 @@ class QMPShell(qmp.QEMUMonitorProtocol): def __cli_expr(self, tokens, parent): for arg in tokens: - (key, _, val) = arg.partition('=') - if not val: + (key, sep, val) = arg.partition('=') + if sep != '=': raise QMPShellError("Expected a key=value pair, got '%s'" % arg) value = self.__parse_value(val) From e04dea88727c2ac97091333ac8be6af5952634a7 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:50 +0100 Subject: [PATCH 03/49] qapi: Factor QAPISchemaParser._include() out of .__init__() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau Message-Id: <1489582656-31133-2-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 53a44779d0..345cde157e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -268,34 +268,15 @@ def __init__(self, fp, previously_included=[], incl_info=None): continue expr = self.get_expr(False) - if isinstance(expr, dict) and "include" in expr: + if 'include' in expr: if len(expr) != 1: raise QAPISemError(info, "Invalid 'include' directive") include = expr["include"] if not isinstance(include, str): raise QAPISemError(info, "Value of 'include' must be a string") - incl_abs_fname = os.path.join(os.path.dirname(abs_fname), - include) - # catch inclusion cycle - inf = info - while inf: - if incl_abs_fname == os.path.abspath(inf['file']): - raise QAPISemError(info, "Inclusion loop for %s" - % include) - inf = inf['parent'] - - # skip multiple include of the same file - if incl_abs_fname in previously_included: - continue - try: - fobj = open(incl_abs_fname, 'r') - except IOError as e: - raise QAPISemError(info, '%s: %s' % (e.strerror, include)) - exprs_include = QAPISchemaParser(fobj, previously_included, - info) - self.exprs.extend(exprs_include.exprs) - self.docs.extend(exprs_include.docs) + self._include(include, info, os.path.dirname(abs_fname), + previously_included) else: expr_elem = {'expr': expr, 'info': info} @@ -307,6 +288,26 @@ def __init__(self, fp, previously_included=[], incl_info=None): self.exprs.append(expr_elem) + def _include(self, include, info, base_dir, previously_included): + incl_abs_fname = os.path.join(base_dir, include) + # catch inclusion cycle + inf = info + while inf: + if incl_abs_fname == os.path.abspath(inf['file']): + raise QAPISemError(info, "Inclusion loop for %s" % include) + inf = inf['parent'] + + # skip multiple include of the same file + if incl_abs_fname in previously_included: + return + try: + fobj = open(incl_abs_fname, 'r') + except IOError as e: + raise QAPISemError(info, '%s: %s' % (e.strerror, include)) + exprs_include = QAPISchemaParser(fobj, previously_included, info) + self.exprs.extend(exprs_include.exprs) + self.docs.extend(exprs_include.docs) + def accept(self, skip_comment=True): while True: self.tok = self.src[self.cursor] From bc52d03ff589a033843b4603cfdfd1518867c626 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:51 +0100 Subject: [PATCH 04/49] qapi: Make doc comments optional where we don't need them Since we added the documentation generator in commit 3313b61, doc comments are mandatory. That's a very good idea for a schema that needs to be documented, but has proven to be annoying for testing. Make doc comments optional again, but add a new directive { 'pragma': { 'doc-required': true } } to let a QAPI schema require them. Add test cases for the new pragma directive. While there, plug a minor hole in includ directive test coverage. Require documentation in the schemas we actually want documented: qapi-schema.json and qga/qapi-schema.json. We could probably make qapi2texi.py cope with incomplete documentation, but for now, simply make it refuse to run unless the schema has 'doc-required': true. Signed-off-by: Markus Armbruster Message-Id: <1489582656-31133-3-git-send-email-armbru@redhat.com> [qapi-code-gen.txt wording tweaked] Reviewed-by: Eric Blake --- docs/qapi-code-gen.txt | 43 +++++++++++++------ qapi-schema.json | 2 + qga/qapi-schema.json | 2 + scripts/qapi.py | 24 ++++++++++- scripts/qapi2texi.py | 3 ++ tests/Makefile.include | 5 +++ tests/qapi-schema/doc-missing.err | 1 + tests/qapi-schema/doc-missing.exit | 1 + tests/qapi-schema/doc-missing.json | 5 +++ tests/qapi-schema/doc-missing.out | 0 tests/qapi-schema/include-extra-junk.err | 1 + tests/qapi-schema/include-extra-junk.exit | 1 + tests/qapi-schema/include-extra-junk.json | 3 ++ tests/qapi-schema/include-extra-junk.out | 0 .../qapi-schema/pragma-doc-required-crap.err | 1 + .../qapi-schema/pragma-doc-required-crap.exit | 1 + .../qapi-schema/pragma-doc-required-crap.json | 3 ++ .../qapi-schema/pragma-doc-required-crap.out | 0 tests/qapi-schema/pragma-extra-junk.err | 1 + tests/qapi-schema/pragma-extra-junk.exit | 1 + tests/qapi-schema/pragma-extra-junk.json | 3 ++ tests/qapi-schema/pragma-extra-junk.out | 0 tests/qapi-schema/pragma-non-dict.err | 1 + tests/qapi-schema/pragma-non-dict.exit | 1 + tests/qapi-schema/pragma-non-dict.json | 3 ++ tests/qapi-schema/pragma-non-dict.out | 0 26 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 tests/qapi-schema/doc-missing.err create mode 100644 tests/qapi-schema/doc-missing.exit create mode 100644 tests/qapi-schema/doc-missing.json create mode 100644 tests/qapi-schema/doc-missing.out create mode 100644 tests/qapi-schema/include-extra-junk.err create mode 100644 tests/qapi-schema/include-extra-junk.exit create mode 100644 tests/qapi-schema/include-extra-junk.json create mode 100644 tests/qapi-schema/include-extra-junk.out create mode 100644 tests/qapi-schema/pragma-doc-required-crap.err create mode 100644 tests/qapi-schema/pragma-doc-required-crap.exit create mode 100644 tests/qapi-schema/pragma-doc-required-crap.json create mode 100644 tests/qapi-schema/pragma-doc-required-crap.out create mode 100644 tests/qapi-schema/pragma-extra-junk.err create mode 100644 tests/qapi-schema/pragma-extra-junk.exit create mode 100644 tests/qapi-schema/pragma-extra-junk.json create mode 100644 tests/qapi-schema/pragma-extra-junk.out create mode 100644 tests/qapi-schema/pragma-non-dict.err create mode 100644 tests/qapi-schema/pragma-non-dict.exit create mode 100644 tests/qapi-schema/pragma-non-dict.json create mode 100644 tests/qapi-schema/pragma-non-dict.out diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 9514d936ad..4b64ee7364 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -117,10 +117,13 @@ Example: ==== Expression documentation ==== -Each expression that isn't an include directive must be preceded by a +Each expression that isn't an include directive may be preceded by a documentation block. Such blocks are called expression documentation blocks. +When documentation is required (see pragma 'doc-required'), expression +documentation blocks are mandatory. + The documentation block consists of a first line naming the expression, an optional overview, a description of each argument (for commands and events) or member (for structs, unions and alternates), @@ -204,17 +207,17 @@ once. It is permissible for the schema to contain additional types not used by any commands or events in the Client JSON Protocol, for the side effect of generated C code used internally. -There are seven top-level expressions recognized by the parser: -'include', 'command', 'struct', 'enum', 'union', 'alternate', and -'event'. There are several groups of types: simple types (a number of -built-in types, such as 'int' and 'str'; as well as enumerations), -complex types (structs and two flavors of unions), and alternate types -(a choice between other types). The 'command' and 'event' expressions -can refer to existing types by name, or list an anonymous type as a -dictionary. Listing a type name inside an array refers to a -single-dimension array of that type; multi-dimension arrays are not -directly supported (although an array of a complex struct that -contains an array member is possible). +There are eight top-level expressions recognized by the parser: +'include', 'pragma', 'command', 'struct', 'enum', 'union', +'alternate', and 'event'. There are several groups of types: simple +types (a number of built-in types, such as 'int' and 'str'; as well as +enumerations), complex types (structs and two flavors of unions), and +alternate types (a choice between other types). The 'command' and +'event' expressions can refer to existing types by name, or list an +anonymous type as a dictionary. Listing a type name inside an array +refers to a single-dimension array of that type; multi-dimension +arrays are not directly supported (although an array of a complex +struct that contains an array member is possible). All names must begin with a letter, and contain only ASCII letters, digits, hyphen, and underscore. There are two exceptions: enum values @@ -282,7 +285,7 @@ The following types are predefined, and map to C as follows: QType QType JSON string matching enum QType values -=== Includes === +=== Include directives === Usage: { 'include': STRING } @@ -302,6 +305,20 @@ an outer file. The parser may be made stricter in the future to prevent incomplete include files. +=== Pragma directives === + +Usage: { 'pragma': DICT } + +The pragma directive lets you control optional generator behavior. +The dictionary's entries are pragma names and values. + +Pragma's scope is currently the complete schema. Setting the same +pragma to different values in parts of the schema doesn't work. + +Pragma 'doc-required' takes a boolean value. If true, documentation +is required. Default is false. + + === Struct types === Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME } diff --git a/qapi-schema.json b/qapi-schema.json index 32b4a4b782..d5438ee2b1 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -49,6 +49,8 @@ # ## +{ 'pragma': { 'doc-required': true } } + # QAPI common definitions { 'include': 'qapi/common.json' } diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index d421609dcb..3f3d428fce 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -11,6 +11,8 @@ # ## +{ 'pragma': { 'doc-required': true } } + ## # @guest-sync-delimited: # diff --git a/scripts/qapi.py b/scripts/qapi.py index 345cde157e..fe9d3cf36d 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -37,6 +37,9 @@ 'QType': 'QTYPE_QSTRING', } +# Are documentation comments required? +doc_required = False + # Whitelist of commands allowed to return a non-dictionary returns_whitelist = [ # From QMP: @@ -277,6 +280,15 @@ def __init__(self, fp, previously_included=[], incl_info=None): "Value of 'include' must be a string") self._include(include, info, os.path.dirname(abs_fname), previously_included) + elif "pragma" in expr: + if len(expr) != 1: + raise QAPISemError(info, "Invalid 'pragma' directive") + pragma = expr['pragma'] + if not isinstance(pragma, dict): + raise QAPISemError( + info, "Value of 'pragma' must be a dictionary") + for name, value in pragma.iteritems(): + self._pragma(name, value, info) else: expr_elem = {'expr': expr, 'info': info} @@ -308,6 +320,16 @@ def _include(self, include, info, base_dir, previously_included): self.exprs.extend(exprs_include.exprs) self.docs.extend(exprs_include.docs) + def _pragma(self, name, value, info): + global doc_required + if name == 'doc-required': + if not isinstance(value, bool): + raise QAPISemError(info, + "Pragma 'doc-required' must be boolean") + doc_required = value + else: + raise QAPISemError(info, "Unknown pragma '%s'" % name) + def accept(self, skip_comment=True): while True: self.tok = self.src[self.cursor] @@ -863,7 +885,7 @@ def check_exprs(exprs): expr = expr_elem['expr'] info = expr_elem['info'] - if 'doc' not in expr_elem: + if 'doc' not in expr_elem and doc_required: raise QAPISemError(info, "Expression missing documentation comment") diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 69f5edce4d..06d6abfa5a 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -254,6 +254,9 @@ def main(argv): sys.exit(1) schema = qapi.QAPISchema(argv[1]) + if not qapi.doc_required: + print >>sys.stderr, ("%s: need pragma 'doc-required' " + "to generate documentation" % argv[0]) print texi(schema.docs) diff --git a/tests/Makefile.include b/tests/Makefile.include index 346345e84d..7a58c12a7e 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -381,6 +381,7 @@ qapi-schema += doc-invalid-end2.json qapi-schema += doc-invalid-return.json qapi-schema += doc-invalid-section.json qapi-schema += doc-invalid-start.json +qapi-schema += doc-missing.json qapi-schema += doc-missing-colon.json qapi-schema += doc-missing-expr.json qapi-schema += doc-missing-space.json @@ -422,6 +423,7 @@ qapi-schema += funny-char.json qapi-schema += ident-with-escape.json qapi-schema += include-before-err.json qapi-schema += include-cycle.json +qapi-schema += include-extra-junk.json qapi-schema += include-format-err.json qapi-schema += include-nested-err.json qapi-schema += include-no-file.json @@ -439,6 +441,9 @@ qapi-schema += missing-comma-object.json qapi-schema += missing-type.json qapi-schema += nested-struct-data.json qapi-schema += non-objects.json +qapi-schema += pragma-doc-required-crap.json +qapi-schema += pragma-extra-junk.json +qapi-schema += pragma-non-dict.json qapi-schema += qapi-schema-test.json qapi-schema += quoted-structural-chars.json qapi-schema += redefined-builtin.json diff --git a/tests/qapi-schema/doc-missing.err b/tests/qapi-schema/doc-missing.err new file mode 100644 index 0000000000..7f2f326b30 --- /dev/null +++ b/tests/qapi-schema/doc-missing.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-missing.json:5: Expression missing documentation comment diff --git a/tests/qapi-schema/doc-missing.exit b/tests/qapi-schema/doc-missing.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/doc-missing.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/doc-missing.json b/tests/qapi-schema/doc-missing.json new file mode 100644 index 0000000000..5956709742 --- /dev/null +++ b/tests/qapi-schema/doc-missing.json @@ -0,0 +1,5 @@ +# Expression documentation required + +{ 'pragma': { 'doc-required': true } } + +{ 'command': 'undocumented' } diff --git a/tests/qapi-schema/doc-missing.out b/tests/qapi-schema/doc-missing.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/include-extra-junk.err b/tests/qapi-schema/include-extra-junk.err new file mode 100644 index 0000000000..e6ef2a3720 --- /dev/null +++ b/tests/qapi-schema/include-extra-junk.err @@ -0,0 +1 @@ +tests/qapi-schema/include-extra-junk.json:3: Invalid 'include' directive diff --git a/tests/qapi-schema/include-extra-junk.exit b/tests/qapi-schema/include-extra-junk.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/include-extra-junk.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/include-extra-junk.json b/tests/qapi-schema/include-extra-junk.json new file mode 100644 index 0000000000..25fe85078d --- /dev/null +++ b/tests/qapi-schema/include-extra-junk.json @@ -0,0 +1,3 @@ +# 'include' must be the sole member + +{ 'include': 'comments.json', 'junk': true } diff --git a/tests/qapi-schema/include-extra-junk.out b/tests/qapi-schema/include-extra-junk.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/pragma-doc-required-crap.err b/tests/qapi-schema/pragma-doc-required-crap.err new file mode 100644 index 0000000000..39cd56cd48 --- /dev/null +++ b/tests/qapi-schema/pragma-doc-required-crap.err @@ -0,0 +1 @@ +tests/qapi-schema/pragma-doc-required-crap.json:3: Pragma 'doc-required' must be boolean diff --git a/tests/qapi-schema/pragma-doc-required-crap.exit b/tests/qapi-schema/pragma-doc-required-crap.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/pragma-doc-required-crap.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/pragma-doc-required-crap.json b/tests/qapi-schema/pragma-doc-required-crap.json new file mode 100644 index 0000000000..ed763c5ffc --- /dev/null +++ b/tests/qapi-schema/pragma-doc-required-crap.json @@ -0,0 +1,3 @@ +# 'doc-required' must be bool + +{ 'pragma': { 'doc-required': {} } } diff --git a/tests/qapi-schema/pragma-doc-required-crap.out b/tests/qapi-schema/pragma-doc-required-crap.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/pragma-extra-junk.err b/tests/qapi-schema/pragma-extra-junk.err new file mode 100644 index 0000000000..4481688dbf --- /dev/null +++ b/tests/qapi-schema/pragma-extra-junk.err @@ -0,0 +1 @@ +tests/qapi-schema/pragma-extra-junk.json:3: Invalid 'pragma' directive diff --git a/tests/qapi-schema/pragma-extra-junk.exit b/tests/qapi-schema/pragma-extra-junk.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/pragma-extra-junk.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/pragma-extra-junk.json b/tests/qapi-schema/pragma-extra-junk.json new file mode 100644 index 0000000000..ba38ef2e95 --- /dev/null +++ b/tests/qapi-schema/pragma-extra-junk.json @@ -0,0 +1,3 @@ +# 'pragma' must be the sole member + +{ 'pragma': { 'doc-required': true }, 'junk': true } diff --git a/tests/qapi-schema/pragma-extra-junk.out b/tests/qapi-schema/pragma-extra-junk.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/pragma-non-dict.err b/tests/qapi-schema/pragma-non-dict.err new file mode 100644 index 0000000000..75bc335aea --- /dev/null +++ b/tests/qapi-schema/pragma-non-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/pragma-non-dict.json:3: Value of 'pragma' must be a dictionary diff --git a/tests/qapi-schema/pragma-non-dict.exit b/tests/qapi-schema/pragma-non-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/pragma-non-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/pragma-non-dict.json b/tests/qapi-schema/pragma-non-dict.json new file mode 100644 index 0000000000..60fcc79bdb --- /dev/null +++ b/tests/qapi-schema/pragma-non-dict.json @@ -0,0 +1,3 @@ +# Value of 'pragma' must be a dictionary + +{ 'pragma': [] } diff --git a/tests/qapi-schema/pragma-non-dict.out b/tests/qapi-schema/pragma-non-dict.out new file mode 100644 index 0000000000..e69de29bb2 From 87c16dcecae62ce324ba6cb360b86434cb324c95 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:52 +0100 Subject: [PATCH 05/49] qapi: Back out doc comments added just to please qapi.py This reverts commit 3313b61's changes to tests/qapi-schema/, except for tests/qapi-schema/doc-*. We could keep some of these doc comments to serve as positive test cases. However, they don't actually add to what we get from doc comment use in actual schemas, as we we don't test output matches expectations, and don't systematically cover doc comment features. Proper positive test coverage would be nice. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-4-git-send-email-armbru@redhat.com> --- tests/qapi-schema/alternate-any.err | 2 +- tests/qapi-schema/alternate-any.json | 4 - tests/qapi-schema/alternate-array.err | 2 +- tests/qapi-schema/alternate-array.json | 7 - tests/qapi-schema/alternate-base.err | 2 +- tests/qapi-schema/alternate-base.json | 7 - tests/qapi-schema/alternate-clash.err | 2 +- tests/qapi-schema/alternate-clash.json | 4 - tests/qapi-schema/alternate-conflict-dict.err | 2 +- .../qapi-schema/alternate-conflict-dict.json | 10 - .../qapi-schema/alternate-conflict-string.err | 2 +- .../alternate-conflict-string.json | 7 - tests/qapi-schema/alternate-empty.err | 2 +- tests/qapi-schema/alternate-empty.json | 4 - tests/qapi-schema/alternate-nested.err | 2 +- tests/qapi-schema/alternate-nested.json | 7 - tests/qapi-schema/alternate-unknown.err | 2 +- tests/qapi-schema/alternate-unknown.json | 4 - tests/qapi-schema/args-alternate.err | 2 +- tests/qapi-schema/args-alternate.json | 8 - tests/qapi-schema/args-any.err | 2 +- tests/qapi-schema/args-any.json | 4 - tests/qapi-schema/args-array-empty.err | 2 +- tests/qapi-schema/args-array-empty.json | 4 - tests/qapi-schema/args-array-unknown.err | 2 +- tests/qapi-schema/args-array-unknown.json | 4 - tests/qapi-schema/args-bad-boxed.err | 2 +- tests/qapi-schema/args-bad-boxed.json | 4 - tests/qapi-schema/args-boxed-anon.err | 2 +- tests/qapi-schema/args-boxed-anon.json | 4 - tests/qapi-schema/args-boxed-empty.err | 2 +- tests/qapi-schema/args-boxed-empty.json | 8 - tests/qapi-schema/args-boxed-string.err | 2 +- tests/qapi-schema/args-boxed-string.json | 4 - tests/qapi-schema/args-int.err | 2 +- tests/qapi-schema/args-int.json | 4 - tests/qapi-schema/args-invalid.err | 2 +- tests/qapi-schema/args-invalid.json | 3 - tests/qapi-schema/args-member-array-bad.err | 2 +- tests/qapi-schema/args-member-array-bad.json | 4 - tests/qapi-schema/args-member-case.err | 2 +- tests/qapi-schema/args-member-case.json | 4 - tests/qapi-schema/args-member-unknown.err | 2 +- tests/qapi-schema/args-member-unknown.json | 4 - tests/qapi-schema/args-name-clash.err | 2 +- tests/qapi-schema/args-name-clash.json | 4 - tests/qapi-schema/args-union.err | 2 +- tests/qapi-schema/args-union.json | 7 - tests/qapi-schema/args-unknown.err | 2 +- tests/qapi-schema/args-unknown.json | 4 - tests/qapi-schema/bad-base.err | 2 +- tests/qapi-schema/bad-base.json | 7 - tests/qapi-schema/bad-data.err | 2 +- tests/qapi-schema/bad-data.json | 4 - tests/qapi-schema/bad-ident.err | 2 +- tests/qapi-schema/bad-ident.json | 4 - tests/qapi-schema/bad-type-bool.err | 2 +- tests/qapi-schema/bad-type-bool.json | 4 - tests/qapi-schema/bad-type-dict.err | 2 +- tests/qapi-schema/bad-type-dict.json | 4 - tests/qapi-schema/base-cycle-direct.err | 2 +- tests/qapi-schema/base-cycle-direct.json | 4 - tests/qapi-schema/base-cycle-indirect.err | 2 +- tests/qapi-schema/base-cycle-indirect.json | 7 - tests/qapi-schema/command-int.err | 2 +- tests/qapi-schema/command-int.json | 4 - tests/qapi-schema/comments.json | 4 - tests/qapi-schema/comments.out | 1 - tests/qapi-schema/double-type.err | 2 +- tests/qapi-schema/double-type.json | 4 - tests/qapi-schema/enum-bad-name.err | 2 +- tests/qapi-schema/enum-bad-name.json | 4 - tests/qapi-schema/enum-bad-prefix.err | 2 +- tests/qapi-schema/enum-bad-prefix.json | 4 - tests/qapi-schema/enum-clash-member.err | 2 +- tests/qapi-schema/enum-clash-member.json | 4 - tests/qapi-schema/enum-dict-member.err | 2 +- tests/qapi-schema/enum-dict-member.json | 4 - tests/qapi-schema/enum-member-case.err | 2 +- tests/qapi-schema/enum-member-case.json | 7 - tests/qapi-schema/enum-missing-data.err | 2 +- tests/qapi-schema/enum-missing-data.json | 4 - tests/qapi-schema/enum-wrong-data.err | 2 +- tests/qapi-schema/enum-wrong-data.json | 4 - tests/qapi-schema/event-boxed-empty.err | 2 +- tests/qapi-schema/event-boxed-empty.json | 4 - tests/qapi-schema/event-case.json | 4 - tests/qapi-schema/event-case.out | 1 - tests/qapi-schema/event-nest-struct.err | 2 +- tests/qapi-schema/event-nest-struct.json | 4 - tests/qapi-schema/flat-union-array-branch.err | 2 +- .../qapi-schema/flat-union-array-branch.json | 12 - tests/qapi-schema/flat-union-bad-base.err | 2 +- tests/qapi-schema/flat-union-bad-base.json | 13 -- .../flat-union-bad-discriminator.err | 2 +- .../flat-union-bad-discriminator.json | 16 -- tests/qapi-schema/flat-union-base-any.err | 2 +- tests/qapi-schema/flat-union-base-any.json | 13 -- tests/qapi-schema/flat-union-base-union.err | 2 +- tests/qapi-schema/flat-union-base-union.json | 16 -- tests/qapi-schema/flat-union-clash-member.err | 2 +- .../qapi-schema/flat-union-clash-member.json | 16 -- tests/qapi-schema/flat-union-empty.err | 2 +- tests/qapi-schema/flat-union-empty.json | 10 - .../flat-union-incomplete-branch.err | 2 +- .../flat-union-incomplete-branch.json | 10 - tests/qapi-schema/flat-union-inline.err | 2 +- tests/qapi-schema/flat-union-inline.json | 10 - tests/qapi-schema/flat-union-int-branch.err | 2 +- tests/qapi-schema/flat-union-int-branch.json | 13 -- .../flat-union-invalid-branch-key.err | 2 +- .../flat-union-invalid-branch-key.json | 15 -- .../flat-union-invalid-discriminator.err | 2 +- .../flat-union-invalid-discriminator.json | 15 -- tests/qapi-schema/flat-union-no-base.err | 2 +- tests/qapi-schema/flat-union-no-base.json | 13 -- .../flat-union-optional-discriminator.err | 2 +- .../flat-union-optional-discriminator.json | 13 -- .../flat-union-string-discriminator.err | 2 +- .../flat-union-string-discriminator.json | 15 -- tests/qapi-schema/ident-with-escape.json | 4 - tests/qapi-schema/ident-with-escape.out | 1 - tests/qapi-schema/include-relpath-sub.json | 3 - tests/qapi-schema/include-relpath.out | 1 - tests/qapi-schema/include-repetition.out | 1 - tests/qapi-schema/include-simple-sub.json | 3 - tests/qapi-schema/include-simple.out | 1 - tests/qapi-schema/indented-expr.json | 6 - tests/qapi-schema/indented-expr.out | 2 - tests/qapi-schema/missing-type.err | 2 +- tests/qapi-schema/missing-type.json | 4 - tests/qapi-schema/nested-struct-data.err | 2 +- tests/qapi-schema/nested-struct-data.json | 4 - tests/qapi-schema/qapi-schema-test.json | 213 ------------------ tests/qapi-schema/qapi-schema-test.out | 130 ----------- tests/qapi-schema/redefined-builtin.err | 2 +- tests/qapi-schema/redefined-builtin.json | 4 - tests/qapi-schema/redefined-command.err | 2 +- tests/qapi-schema/redefined-command.json | 7 - tests/qapi-schema/redefined-event.err | 2 +- tests/qapi-schema/redefined-event.json | 7 - tests/qapi-schema/redefined-type.err | 2 +- tests/qapi-schema/redefined-type.json | 7 - tests/qapi-schema/reserved-command-q.err | 2 +- tests/qapi-schema/reserved-command-q.json | 7 - tests/qapi-schema/reserved-enum-q.err | 2 +- tests/qapi-schema/reserved-enum-q.json | 4 - tests/qapi-schema/reserved-member-has.err | 2 +- tests/qapi-schema/reserved-member-has.json | 4 - tests/qapi-schema/reserved-member-q.err | 2 +- tests/qapi-schema/reserved-member-q.json | 4 - tests/qapi-schema/reserved-member-u.err | 2 +- tests/qapi-schema/reserved-member-u.json | 4 - .../reserved-member-underscore.err | 2 +- .../reserved-member-underscore.json | 4 - tests/qapi-schema/reserved-type-kind.err | 2 +- tests/qapi-schema/reserved-type-kind.json | 4 - tests/qapi-schema/reserved-type-list.err | 2 +- tests/qapi-schema/reserved-type-list.json | 4 - tests/qapi-schema/returns-alternate.err | 2 +- tests/qapi-schema/returns-alternate.json | 7 - tests/qapi-schema/returns-array-bad.err | 2 +- tests/qapi-schema/returns-array-bad.json | 4 - tests/qapi-schema/returns-dict.err | 2 +- tests/qapi-schema/returns-dict.json | 4 - tests/qapi-schema/returns-unknown.err | 2 +- tests/qapi-schema/returns-unknown.json | 4 - tests/qapi-schema/returns-whitelist.err | 2 +- tests/qapi-schema/returns-whitelist.json | 16 -- tests/qapi-schema/struct-base-clash-deep.err | 2 +- tests/qapi-schema/struct-base-clash-deep.json | 10 - tests/qapi-schema/struct-base-clash.err | 2 +- tests/qapi-schema/struct-base-clash.json | 7 - tests/qapi-schema/struct-data-invalid.err | 2 +- tests/qapi-schema/struct-data-invalid.json | 3 - tests/qapi-schema/struct-member-invalid.err | 2 +- tests/qapi-schema/struct-member-invalid.json | 3 - tests/qapi-schema/test-qapi.py | 14 -- tests/qapi-schema/type-bypass-bad-gen.err | 2 +- tests/qapi-schema/type-bypass-bad-gen.json | 4 - tests/qapi-schema/unicode-str.err | 2 +- tests/qapi-schema/unicode-str.json | 4 - .../union-base-no-discriminator.err | 2 +- .../union-base-no-discriminator.json | 12 - tests/qapi-schema/union-branch-case.err | 2 +- tests/qapi-schema/union-branch-case.json | 4 - tests/qapi-schema/union-clash-branches.err | 2 +- tests/qapi-schema/union-clash-branches.json | 4 - tests/qapi-schema/union-empty.err | 2 +- tests/qapi-schema/union-empty.json | 4 - tests/qapi-schema/union-invalid-base.err | 2 +- tests/qapi-schema/union-invalid-base.json | 10 - tests/qapi-schema/union-optional-branch.err | 2 +- tests/qapi-schema/union-optional-branch.json | 4 - tests/qapi-schema/union-unknown.err | 2 +- tests/qapi-schema/union-unknown.json | 4 - tests/qapi-schema/unknown-escape.err | 2 +- tests/qapi-schema/unknown-escape.json | 4 - tests/qapi-schema/unknown-expr-key.err | 2 +- tests/qapi-schema/unknown-expr-key.json | 4 - 200 files changed, 92 insertions(+), 1074 deletions(-) diff --git a/tests/qapi-schema/alternate-any.err b/tests/qapi-schema/alternate-any.err index 395c8ab583..aaa0154731 100644 --- a/tests/qapi-schema/alternate-any.err +++ b/tests/qapi-schema/alternate-any.err @@ -1 +1 @@ -tests/qapi-schema/alternate-any.json:6: Alternate 'Alt' member 'one' cannot use type 'any' +tests/qapi-schema/alternate-any.json:2: Alternate 'Alt' member 'one' cannot use type 'any' diff --git a/tests/qapi-schema/alternate-any.json b/tests/qapi-schema/alternate-any.json index c958776767..e47a73a116 100644 --- a/tests/qapi-schema/alternate-any.json +++ b/tests/qapi-schema/alternate-any.json @@ -1,8 +1,4 @@ # we do not allow the 'any' type as an alternate branch - -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'one': 'any', 'two': 'int' } } diff --git a/tests/qapi-schema/alternate-array.err b/tests/qapi-schema/alternate-array.err index 09628e9755..7b930c64ab 100644 --- a/tests/qapi-schema/alternate-array.err +++ b/tests/qapi-schema/alternate-array.err @@ -1 +1 @@ -tests/qapi-schema/alternate-array.json:12: Member 'two' of alternate 'Alt' cannot be an array +tests/qapi-schema/alternate-array.json:5: Member 'two' of alternate 'Alt' cannot be an array diff --git a/tests/qapi-schema/alternate-array.json b/tests/qapi-schema/alternate-array.json index c2f98ad608..f241aac122 100644 --- a/tests/qapi-schema/alternate-array.json +++ b/tests/qapi-schema/alternate-array.json @@ -1,14 +1,7 @@ # we do not allow array branches in alternates - -## -# @One: -## # TODO: should we support this? { 'struct': 'One', 'data': { 'name': 'str' } } -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'one': 'One', 'two': [ 'int' ] } } diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err index 3b679140e0..30d8a34373 100644 --- a/tests/qapi-schema/alternate-base.err +++ b/tests/qapi-schema/alternate-base.err @@ -1 +1 @@ -tests/qapi-schema/alternate-base.json:11: Unknown key 'base' in alternate 'Alt' +tests/qapi-schema/alternate-base.json:4: Unknown key 'base' in alternate 'Alt' diff --git a/tests/qapi-schema/alternate-base.json b/tests/qapi-schema/alternate-base.json index 9612b7925d..529430ecf2 100644 --- a/tests/qapi-schema/alternate-base.json +++ b/tests/qapi-schema/alternate-base.json @@ -1,13 +1,6 @@ # we reject alternate with base type - -## -# @Base: -## { 'struct': 'Base', 'data': { 'string': 'str' } } -## -# @Alt: -## { 'alternate': 'Alt', 'base': 'Base', 'data': { 'number': 'int' } } diff --git a/tests/qapi-schema/alternate-clash.err b/tests/qapi-schema/alternate-clash.err index f07c3e8ad3..604d8495eb 100644 --- a/tests/qapi-schema/alternate-clash.err +++ b/tests/qapi-schema/alternate-clash.err @@ -1 +1 @@ -tests/qapi-schema/alternate-clash.json:11: 'a_b' (branch of Alt1) collides with 'a-b' (branch of Alt1) +tests/qapi-schema/alternate-clash.json:7: 'a_b' (branch of Alt1) collides with 'a-b' (branch of Alt1) diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json index 97ca7c80e7..6d73bc527b 100644 --- a/tests/qapi-schema/alternate-clash.json +++ b/tests/qapi-schema/alternate-clash.json @@ -4,9 +4,5 @@ # TODO: In the future, if alternates are simplified to not generate # the implicit Alt1Kind enum, we would still have a collision with the # resulting C union trying to have two members named 'a_b'. - -## -# @Alt1: -## { 'alternate': 'Alt1', 'data': { 'a-b': 'str', 'a_b': 'int' } } diff --git a/tests/qapi-schema/alternate-conflict-dict.err b/tests/qapi-schema/alternate-conflict-dict.err index 7cb023fdd8..0f411f4faf 100644 --- a/tests/qapi-schema/alternate-conflict-dict.err +++ b/tests/qapi-schema/alternate-conflict-dict.err @@ -1 +1 @@ -tests/qapi-schema/alternate-conflict-dict.json:16: Alternate 'Alt' member 'two' can't be distinguished from member 'one' +tests/qapi-schema/alternate-conflict-dict.json:6: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-dict.json b/tests/qapi-schema/alternate-conflict-dict.json index 9f9d97fa2e..d566cca816 100644 --- a/tests/qapi-schema/alternate-conflict-dict.json +++ b/tests/qapi-schema/alternate-conflict-dict.json @@ -1,18 +1,8 @@ # we reject alternates with multiple object branches - -## -# @One: -## { 'struct': 'One', 'data': { 'name': 'str' } } -## -# @Two: -## { 'struct': 'Two', 'data': { 'value': 'int' } } -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'one': 'One', 'two': 'Two' } } diff --git a/tests/qapi-schema/alternate-conflict-string.err b/tests/qapi-schema/alternate-conflict-string.err index 6dbbacd1d2..fc523b0879 100644 --- a/tests/qapi-schema/alternate-conflict-string.err +++ b/tests/qapi-schema/alternate-conflict-string.err @@ -1 +1 @@ -tests/qapi-schema/alternate-conflict-string.json:11: Alternate 'Alt' member 'two' can't be distinguished from member 'one' +tests/qapi-schema/alternate-conflict-string.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-string.json b/tests/qapi-schema/alternate-conflict-string.json index 12aafab808..72f04a820a 100644 --- a/tests/qapi-schema/alternate-conflict-string.json +++ b/tests/qapi-schema/alternate-conflict-string.json @@ -1,13 +1,6 @@ # we reject alternates with multiple string-like branches - -## -# @Enum: -## { 'enum': 'Enum', 'data': [ 'hello', 'world' ] } -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'one': 'str', 'two': 'Enum' } } diff --git a/tests/qapi-schema/alternate-empty.err b/tests/qapi-schema/alternate-empty.err index 8245ce3103..bb06c5bfec 100644 --- a/tests/qapi-schema/alternate-empty.err +++ b/tests/qapi-schema/alternate-empty.err @@ -1 +1 @@ -tests/qapi-schema/alternate-empty.json:6: Alternate 'Alt' should have at least two branches in 'data' +tests/qapi-schema/alternate-empty.json:2: Alternate 'Alt' should have at least two branches in 'data' diff --git a/tests/qapi-schema/alternate-empty.json b/tests/qapi-schema/alternate-empty.json index db54405240..fff15baf16 100644 --- a/tests/qapi-schema/alternate-empty.json +++ b/tests/qapi-schema/alternate-empty.json @@ -1,6 +1,2 @@ # alternates must list at least two types to be useful - -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'i': 'int' } } diff --git a/tests/qapi-schema/alternate-nested.err b/tests/qapi-schema/alternate-nested.err index 1804ffbf47..4d1187e60e 100644 --- a/tests/qapi-schema/alternate-nested.err +++ b/tests/qapi-schema/alternate-nested.err @@ -1 +1 @@ -tests/qapi-schema/alternate-nested.json:11: Member 'nested' of alternate 'Alt2' cannot use alternate type 'Alt1' +tests/qapi-schema/alternate-nested.json:4: Member 'nested' of alternate 'Alt2' cannot use alternate type 'Alt1' diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json index 9f83ebe2e0..8e22186491 100644 --- a/tests/qapi-schema/alternate-nested.json +++ b/tests/qapi-schema/alternate-nested.json @@ -1,12 +1,5 @@ # we reject a nested alternate branch - -## -# @Alt1: -## { 'alternate': 'Alt1', 'data': { 'name': 'str', 'value': 'int' } } -## -# @Alt2: -## { 'alternate': 'Alt2', 'data': { 'nested': 'Alt1', 'b': 'bool' } } diff --git a/tests/qapi-schema/alternate-unknown.err b/tests/qapi-schema/alternate-unknown.err index cf5b9b6830..dea45dc730 100644 --- a/tests/qapi-schema/alternate-unknown.err +++ b/tests/qapi-schema/alternate-unknown.err @@ -1 +1 @@ -tests/qapi-schema/alternate-unknown.json:6: Member 'unknown' of alternate 'Alt' uses unknown type 'MissingType' +tests/qapi-schema/alternate-unknown.json:2: Member 'unknown' of alternate 'Alt' uses unknown type 'MissingType' diff --git a/tests/qapi-schema/alternate-unknown.json b/tests/qapi-schema/alternate-unknown.json index 941ba1fac4..08c80dced0 100644 --- a/tests/qapi-schema/alternate-unknown.json +++ b/tests/qapi-schema/alternate-unknown.json @@ -1,7 +1,3 @@ # we reject an alternate with unknown type in branch - -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'unknown': 'MissingType', 'i': 'int' } } diff --git a/tests/qapi-schema/args-alternate.err b/tests/qapi-schema/args-alternate.err index 2e6bf54245..3086eae56b 100644 --- a/tests/qapi-schema/args-alternate.err +++ b/tests/qapi-schema/args-alternate.err @@ -1 +1 @@ -tests/qapi-schema/args-alternate.json:11: 'data' for command 'oops' cannot use alternate type 'Alt' +tests/qapi-schema/args-alternate.json:3: 'data' for command 'oops' cannot use alternate type 'Alt' diff --git a/tests/qapi-schema/args-alternate.json b/tests/qapi-schema/args-alternate.json index 49d0211a03..69e94d4819 100644 --- a/tests/qapi-schema/args-alternate.json +++ b/tests/qapi-schema/args-alternate.json @@ -1,11 +1,3 @@ # we do not allow alternate arguments - -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } } - -## -# @oops: -## { 'command': 'oops', 'data': 'Alt' } diff --git a/tests/qapi-schema/args-any.err b/tests/qapi-schema/args-any.err index 955504b10f..bf9b5e0730 100644 --- a/tests/qapi-schema/args-any.err +++ b/tests/qapi-schema/args-any.err @@ -1 +1 @@ -tests/qapi-schema/args-any.json:6: 'data' for command 'oops' cannot use built-in type 'any' +tests/qapi-schema/args-any.json:2: 'data' for command 'oops' cannot use built-in type 'any' diff --git a/tests/qapi-schema/args-any.json b/tests/qapi-schema/args-any.json index f494479cc9..58fe5e470e 100644 --- a/tests/qapi-schema/args-any.json +++ b/tests/qapi-schema/args-any.json @@ -1,6 +1,2 @@ # we do not allow an 'any' argument - -## -# @oops: -## { 'command': 'oops', 'data': 'any' } diff --git a/tests/qapi-schema/args-array-empty.err b/tests/qapi-schema/args-array-empty.err index e85f7918ab..cb7ed33b3f 100644 --- a/tests/qapi-schema/args-array-empty.err +++ b/tests/qapi-schema/args-array-empty.err @@ -1 +1 @@ -tests/qapi-schema/args-array-empty.json:6: Member 'empty' of 'data' for command 'oops': array type must contain single type name +tests/qapi-schema/args-array-empty.json:2: Member 'empty' of 'data' for command 'oops': array type must contain single type name diff --git a/tests/qapi-schema/args-array-empty.json b/tests/qapi-schema/args-array-empty.json index 78a0b88221..652dcfb24a 100644 --- a/tests/qapi-schema/args-array-empty.json +++ b/tests/qapi-schema/args-array-empty.json @@ -1,6 +1,2 @@ # we reject an array for data if it does not contain a known type - -## -# @oops: -## { 'command': 'oops', 'data': { 'empty': [ ] } } diff --git a/tests/qapi-schema/args-array-unknown.err b/tests/qapi-schema/args-array-unknown.err index 77788de099..cd7a0f98d7 100644 --- a/tests/qapi-schema/args-array-unknown.err +++ b/tests/qapi-schema/args-array-unknown.err @@ -1 +1 @@ -tests/qapi-schema/args-array-unknown.json:6: Member 'array' of 'data' for command 'oops' uses unknown type 'NoSuchType' +tests/qapi-schema/args-array-unknown.json:2: Member 'array' of 'data' for command 'oops' uses unknown type 'NoSuchType' diff --git a/tests/qapi-schema/args-array-unknown.json b/tests/qapi-schema/args-array-unknown.json index f680fc10d3..6f3e883315 100644 --- a/tests/qapi-schema/args-array-unknown.json +++ b/tests/qapi-schema/args-array-unknown.json @@ -1,6 +1,2 @@ # we reject an array for data if it does not contain a known type - -## -# @oops: -## { 'command': 'oops', 'data': { 'array': [ 'NoSuchType' ] } } diff --git a/tests/qapi-schema/args-bad-boxed.err b/tests/qapi-schema/args-bad-boxed.err index 87a906137a..ad0d417321 100644 --- a/tests/qapi-schema/args-bad-boxed.err +++ b/tests/qapi-schema/args-bad-boxed.err @@ -1 +1 @@ -tests/qapi-schema/args-bad-boxed.json:6: 'boxed' of command 'foo' should only use true value +tests/qapi-schema/args-bad-boxed.json:2: 'boxed' of command 'foo' should only use true value diff --git a/tests/qapi-schema/args-bad-boxed.json b/tests/qapi-schema/args-bad-boxed.json index 4c0b28f291..dea0cd0aa5 100644 --- a/tests/qapi-schema/args-bad-boxed.json +++ b/tests/qapi-schema/args-bad-boxed.json @@ -1,6 +1,2 @@ # 'boxed' should only appear with value true - -## -# @foo: -## { 'command': 'foo', 'boxed': false } diff --git a/tests/qapi-schema/args-boxed-anon.err b/tests/qapi-schema/args-boxed-anon.err index 3cfac0b923..f24f345218 100644 --- a/tests/qapi-schema/args-boxed-anon.err +++ b/tests/qapi-schema/args-boxed-anon.err @@ -1 +1 @@ -tests/qapi-schema/args-boxed-anon.json:6: 'data' for command 'foo' should be a type name +tests/qapi-schema/args-boxed-anon.json:2: 'data' for command 'foo' should be a type name diff --git a/tests/qapi-schema/args-boxed-anon.json b/tests/qapi-schema/args-boxed-anon.json index 2358e6abb1..95f60da2ed 100644 --- a/tests/qapi-schema/args-boxed-anon.json +++ b/tests/qapi-schema/args-boxed-anon.json @@ -1,6 +1,2 @@ # 'boxed' can only be used with named types - -## -# @foo: -## { 'command': 'foo', 'boxed': true, 'data': { 'string': 'str' } } diff --git a/tests/qapi-schema/args-boxed-empty.err b/tests/qapi-schema/args-boxed-empty.err index 963f495a9d..039603e85c 100644 --- a/tests/qapi-schema/args-boxed-empty.err +++ b/tests/qapi-schema/args-boxed-empty.err @@ -1 +1 @@ -tests/qapi-schema/args-boxed-empty.json:11: Cannot use 'boxed' with empty type +tests/qapi-schema/args-boxed-empty.json:3: Cannot use 'boxed' with empty type diff --git a/tests/qapi-schema/args-boxed-empty.json b/tests/qapi-schema/args-boxed-empty.json index 8e8cc26525..52717e065f 100644 --- a/tests/qapi-schema/args-boxed-empty.json +++ b/tests/qapi-schema/args-boxed-empty.json @@ -1,11 +1,3 @@ # 'boxed' requires a non-empty type - -## -# @Empty: -## { 'struct': 'Empty', 'data': {} } - -## -# @foo: -## { 'command': 'foo', 'boxed': true, 'data': 'Empty' } diff --git a/tests/qapi-schema/args-boxed-string.err b/tests/qapi-schema/args-boxed-string.err index 7623755208..d326b48aef 100644 --- a/tests/qapi-schema/args-boxed-string.err +++ b/tests/qapi-schema/args-boxed-string.err @@ -1 +1 @@ -tests/qapi-schema/args-boxed-string.json:6: 'data' for command 'foo' cannot use built-in type 'str' +tests/qapi-schema/args-boxed-string.json:2: 'data' for command 'foo' cannot use built-in type 'str' diff --git a/tests/qapi-schema/args-boxed-string.json b/tests/qapi-schema/args-boxed-string.json index aecdf97ce9..f91a1502e7 100644 --- a/tests/qapi-schema/args-boxed-string.json +++ b/tests/qapi-schema/args-boxed-string.json @@ -1,6 +1,2 @@ # 'boxed' requires a complex (not built-in) type - -## -# @foo: -## { 'command': 'foo', 'boxed': true, 'data': 'str' } diff --git a/tests/qapi-schema/args-int.err b/tests/qapi-schema/args-int.err index 38b3202b09..dc1d2504ff 100644 --- a/tests/qapi-schema/args-int.err +++ b/tests/qapi-schema/args-int.err @@ -1 +1 @@ -tests/qapi-schema/args-int.json:6: 'data' for command 'oops' cannot use built-in type 'int' +tests/qapi-schema/args-int.json:2: 'data' for command 'oops' cannot use built-in type 'int' diff --git a/tests/qapi-schema/args-int.json b/tests/qapi-schema/args-int.json index 7f4e1b7aa6..a334d92e8c 100644 --- a/tests/qapi-schema/args-int.json +++ b/tests/qapi-schema/args-int.json @@ -1,6 +1,2 @@ # we reject commands where data is not an array or complex type - -## -# @oops: -## { 'command': 'oops', 'data': 'int' } diff --git a/tests/qapi-schema/args-invalid.err b/tests/qapi-schema/args-invalid.err index 5d3568d7c3..fe1e94975b 100644 --- a/tests/qapi-schema/args-invalid.err +++ b/tests/qapi-schema/args-invalid.err @@ -1 +1 @@ -tests/qapi-schema/args-invalid.json:4: 'data' for command 'foo' should be a dictionary or type name +tests/qapi-schema/args-invalid.json:1: 'data' for command 'foo' should be a dictionary or type name diff --git a/tests/qapi-schema/args-invalid.json b/tests/qapi-schema/args-invalid.json index 1a7e63bb23..db0981341b 100644 --- a/tests/qapi-schema/args-invalid.json +++ b/tests/qapi-schema/args-invalid.json @@ -1,5 +1,2 @@ -## -# @foo: -## { 'command': 'foo', 'data': false } diff --git a/tests/qapi-schema/args-member-array-bad.err b/tests/qapi-schema/args-member-array-bad.err index 825ffca9bf..881b4d954f 100644 --- a/tests/qapi-schema/args-member-array-bad.err +++ b/tests/qapi-schema/args-member-array-bad.err @@ -1 +1 @@ -tests/qapi-schema/args-member-array-bad.json:6: Member 'member' of 'data' for command 'oops': array type must contain single type name +tests/qapi-schema/args-member-array-bad.json:2: Member 'member' of 'data' for command 'oops': array type must contain single type name diff --git a/tests/qapi-schema/args-member-array-bad.json b/tests/qapi-schema/args-member-array-bad.json index e934f5c457..b2ff144ec6 100644 --- a/tests/qapi-schema/args-member-array-bad.json +++ b/tests/qapi-schema/args-member-array-bad.json @@ -1,6 +1,2 @@ # we reject data if it does not contain a valid array type - -## -# @oops: -## { 'command': 'oops', 'data': { 'member': [ { 'nested': 'str' } ] } } diff --git a/tests/qapi-schema/args-member-case.err b/tests/qapi-schema/args-member-case.err index a3fb2bdd60..19c4426601 100644 --- a/tests/qapi-schema/args-member-case.err +++ b/tests/qapi-schema/args-member-case.err @@ -1 +1 @@ -tests/qapi-schema/args-member-case.json:6: 'Arg' (parameter of no-way-this-will-get-whitelisted) should not use uppercase +tests/qapi-schema/args-member-case.json:2: 'Arg' (parameter of no-way-this-will-get-whitelisted) should not use uppercase diff --git a/tests/qapi-schema/args-member-case.json b/tests/qapi-schema/args-member-case.json index 811e658d66..93439bee8b 100644 --- a/tests/qapi-schema/args-member-case.json +++ b/tests/qapi-schema/args-member-case.json @@ -1,6 +1,2 @@ # Member names should be 'lower-case' unless the struct/command is whitelisted - -## -# @no-way-this-will-get-whitelisted: -## { 'command': 'no-way-this-will-get-whitelisted', 'data': { 'Arg': 'int' } } diff --git a/tests/qapi-schema/args-member-unknown.err b/tests/qapi-schema/args-member-unknown.err index 3db452b95a..f6f82828ce 100644 --- a/tests/qapi-schema/args-member-unknown.err +++ b/tests/qapi-schema/args-member-unknown.err @@ -1 +1 @@ -tests/qapi-schema/args-member-unknown.json:6: Member 'member' of 'data' for command 'oops' uses unknown type 'NoSuchType' +tests/qapi-schema/args-member-unknown.json:2: Member 'member' of 'data' for command 'oops' uses unknown type 'NoSuchType' diff --git a/tests/qapi-schema/args-member-unknown.json b/tests/qapi-schema/args-member-unknown.json index e2fef9c46f..342a41ec90 100644 --- a/tests/qapi-schema/args-member-unknown.json +++ b/tests/qapi-schema/args-member-unknown.json @@ -1,6 +1,2 @@ # we reject data if it does not contain a known type - -## -# @oops: -## { 'command': 'oops', 'data': { 'member': 'NoSuchType' } } diff --git a/tests/qapi-schema/args-name-clash.err b/tests/qapi-schema/args-name-clash.err index 23988cb5ca..d953e8d241 100644 --- a/tests/qapi-schema/args-name-clash.err +++ b/tests/qapi-schema/args-name-clash.err @@ -1 +1 @@ -tests/qapi-schema/args-name-clash.json:8: 'a_b' (parameter of oops) collides with 'a-b' (parameter of oops) +tests/qapi-schema/args-name-clash.json:4: 'a_b' (parameter of oops) collides with 'a-b' (parameter of oops) diff --git a/tests/qapi-schema/args-name-clash.json b/tests/qapi-schema/args-name-clash.json index 991323b78d..61423cb893 100644 --- a/tests/qapi-schema/args-name-clash.json +++ b/tests/qapi-schema/args-name-clash.json @@ -1,8 +1,4 @@ # C member name collision # Reject members that clash when mapped to C names (we would have two 'a_b' # members). - -## -# @oops: -## { 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } } diff --git a/tests/qapi-schema/args-union.err b/tests/qapi-schema/args-union.err index ce0a34e16c..f8ad223dde 100644 --- a/tests/qapi-schema/args-union.err +++ b/tests/qapi-schema/args-union.err @@ -1 +1 @@ -tests/qapi-schema/args-union.json:10: 'data' for command 'oops' cannot use union type 'Uni' +tests/qapi-schema/args-union.json:3: 'data' for command 'oops' cannot use union type 'Uni' diff --git a/tests/qapi-schema/args-union.json b/tests/qapi-schema/args-union.json index 57284b43c5..2fcaeaae16 100644 --- a/tests/qapi-schema/args-union.json +++ b/tests/qapi-schema/args-union.json @@ -1,10 +1,3 @@ # use of union arguments requires 'boxed':true - -## -# @Uni: -## { 'union': 'Uni', 'data': { 'case1': 'int', 'case2': 'str' } } -## -# oops: -## { 'command': 'oops', 'data': 'Uni' } diff --git a/tests/qapi-schema/args-unknown.err b/tests/qapi-schema/args-unknown.err index ba6c6cf326..4d91ec869f 100644 --- a/tests/qapi-schema/args-unknown.err +++ b/tests/qapi-schema/args-unknown.err @@ -1 +1 @@ -tests/qapi-schema/args-unknown.json:6: 'data' for command 'oops' uses unknown type 'NoSuchType' +tests/qapi-schema/args-unknown.json:2: 'data' for command 'oops' uses unknown type 'NoSuchType' diff --git a/tests/qapi-schema/args-unknown.json b/tests/qapi-schema/args-unknown.json index 12666dc020..32aba43b3f 100644 --- a/tests/qapi-schema/args-unknown.json +++ b/tests/qapi-schema/args-unknown.json @@ -1,6 +1,2 @@ # we reject data if it does not contain a known type - -## -# @oops: -## { 'command': 'oops', 'data': 'NoSuchType' } diff --git a/tests/qapi-schema/bad-base.err b/tests/qapi-schema/bad-base.err index e668761c65..154274bdd3 100644 --- a/tests/qapi-schema/bad-base.err +++ b/tests/qapi-schema/bad-base.err @@ -1 +1 @@ -tests/qapi-schema/bad-base.json:10: 'base' for struct 'MyType' cannot use union type 'Union' +tests/qapi-schema/bad-base.json:3: 'base' for struct 'MyType' cannot use union type 'Union' diff --git a/tests/qapi-schema/bad-base.json b/tests/qapi-schema/bad-base.json index c3faa8242b..a634331cdd 100644 --- a/tests/qapi-schema/bad-base.json +++ b/tests/qapi-schema/bad-base.json @@ -1,10 +1,3 @@ # we reject a base that is not a struct - -## -# @Union: -## { 'union': 'Union', 'data': { 'a': 'int', 'b': 'str' } } -## -# @MyType: -## { 'struct': 'MyType', 'base': 'Union', 'data': { 'c': 'int' } } diff --git a/tests/qapi-schema/bad-data.err b/tests/qapi-schema/bad-data.err index c1b9e35313..8523ac4f46 100644 --- a/tests/qapi-schema/bad-data.err +++ b/tests/qapi-schema/bad-data.err @@ -1 +1 @@ -tests/qapi-schema/bad-data.json:6: 'data' for command 'oops' cannot be an array +tests/qapi-schema/bad-data.json:2: 'data' for command 'oops' cannot be an array diff --git a/tests/qapi-schema/bad-data.json b/tests/qapi-schema/bad-data.json index 51c444f4f8..832eeb76f4 100644 --- a/tests/qapi-schema/bad-data.json +++ b/tests/qapi-schema/bad-data.json @@ -1,6 +1,2 @@ # we ensure 'data' is a dictionary for all but enums - -## -# @oops: -## { 'command': 'oops', 'data': [ ] } diff --git a/tests/qapi-schema/bad-ident.err b/tests/qapi-schema/bad-ident.err index b757aa21e7..c4190602b5 100644 --- a/tests/qapi-schema/bad-ident.err +++ b/tests/qapi-schema/bad-ident.err @@ -1 +1 @@ -tests/qapi-schema/bad-ident.json:6: 'struct' does not allow optional name '*oops' +tests/qapi-schema/bad-ident.json:2: 'struct' does not allow optional name '*oops' diff --git a/tests/qapi-schema/bad-ident.json b/tests/qapi-schema/bad-ident.json index b43df7a3e0..763627ad23 100644 --- a/tests/qapi-schema/bad-ident.json +++ b/tests/qapi-schema/bad-ident.json @@ -1,6 +1,2 @@ # we reject creating a type name with bad name - -## -# @*oops: -## { 'struct': '*oops', 'data': { 'i': 'int' } } diff --git a/tests/qapi-schema/bad-type-bool.err b/tests/qapi-schema/bad-type-bool.err index 72e026b46c..62fd70baaf 100644 --- a/tests/qapi-schema/bad-type-bool.err +++ b/tests/qapi-schema/bad-type-bool.err @@ -1 +1 @@ -tests/qapi-schema/bad-type-bool.json:6: 'struct' key must have a string value +tests/qapi-schema/bad-type-bool.json:2: 'struct' key must have a string value diff --git a/tests/qapi-schema/bad-type-bool.json b/tests/qapi-schema/bad-type-bool.json index 1f9eddf938..bde17b56c4 100644 --- a/tests/qapi-schema/bad-type-bool.json +++ b/tests/qapi-schema/bad-type-bool.json @@ -1,6 +1,2 @@ # we reject an expression with a metatype that is not a string - -## -# @true: -## { 'struct': true, 'data': { } } diff --git a/tests/qapi-schema/bad-type-dict.err b/tests/qapi-schema/bad-type-dict.err index d0d1f607e5..0b2a2aeac4 100644 --- a/tests/qapi-schema/bad-type-dict.err +++ b/tests/qapi-schema/bad-type-dict.err @@ -1 +1 @@ -tests/qapi-schema/bad-type-dict.json:6: 'command' key must have a string value +tests/qapi-schema/bad-type-dict.json:2: 'command' key must have a string value diff --git a/tests/qapi-schema/bad-type-dict.json b/tests/qapi-schema/bad-type-dict.json index 5952caab28..2a91b241f8 100644 --- a/tests/qapi-schema/bad-type-dict.json +++ b/tests/qapi-schema/bad-type-dict.json @@ -1,6 +1,2 @@ # we reject an expression with a metatype that is not a string - -## -# @foo: -## { 'command': { } } diff --git a/tests/qapi-schema/base-cycle-direct.err b/tests/qapi-schema/base-cycle-direct.err index dd7f5aace6..9c68f6543d 100644 --- a/tests/qapi-schema/base-cycle-direct.err +++ b/tests/qapi-schema/base-cycle-direct.err @@ -1 +1 @@ -tests/qapi-schema/base-cycle-direct.json:6: Object Loopy contains itself +tests/qapi-schema/base-cycle-direct.json:2: Object Loopy contains itself diff --git a/tests/qapi-schema/base-cycle-direct.json b/tests/qapi-schema/base-cycle-direct.json index 9780f7e2ca..4fc66d0516 100644 --- a/tests/qapi-schema/base-cycle-direct.json +++ b/tests/qapi-schema/base-cycle-direct.json @@ -1,6 +1,2 @@ # we reject a loop in base classes - -## -# @Loopy: -## { 'struct': 'Loopy', 'base': 'Loopy', 'data': {} } diff --git a/tests/qapi-schema/base-cycle-indirect.err b/tests/qapi-schema/base-cycle-indirect.err index f4198e4a40..fc92fe47f8 100644 --- a/tests/qapi-schema/base-cycle-indirect.err +++ b/tests/qapi-schema/base-cycle-indirect.err @@ -1 +1 @@ -tests/qapi-schema/base-cycle-indirect.json:6: Object Base1 contains itself +tests/qapi-schema/base-cycle-indirect.json:2: Object Base1 contains itself diff --git a/tests/qapi-schema/base-cycle-indirect.json b/tests/qapi-schema/base-cycle-indirect.json index 99926c4609..28667721a3 100644 --- a/tests/qapi-schema/base-cycle-indirect.json +++ b/tests/qapi-schema/base-cycle-indirect.json @@ -1,10 +1,3 @@ # we reject a loop in base classes - -## -# @Base1: -## { 'struct': 'Base1', 'base': 'Base2', 'data': {} } -## -# @Base2: -## { 'struct': 'Base2', 'base': 'Base1', 'data': {} } diff --git a/tests/qapi-schema/command-int.err b/tests/qapi-schema/command-int.err index 3c834a97ab..0f9300679b 100644 --- a/tests/qapi-schema/command-int.err +++ b/tests/qapi-schema/command-int.err @@ -1 +1 @@ -tests/qapi-schema/command-int.json:6: built-in 'int' is already defined +tests/qapi-schema/command-int.json:2: built-in 'int' is already defined diff --git a/tests/qapi-schema/command-int.json b/tests/qapi-schema/command-int.json index 5b51bf148b..9a62554fc6 100644 --- a/tests/qapi-schema/command-int.json +++ b/tests/qapi-schema/command-int.json @@ -1,6 +1,2 @@ # we reject collisions between commands and types - -## -# @int: -## { 'command': 'int', 'data': { 'character': 'str' } } diff --git a/tests/qapi-schema/comments.json b/tests/qapi-schema/comments.json index d31ef0d90a..e643f3a74c 100644 --- a/tests/qapi-schema/comments.json +++ b/tests/qapi-schema/comments.json @@ -1,8 +1,4 @@ # Unindented comment - -## -# @Status: -## { 'enum': 'Status', # Comment to the right of code # Indented comment 'data': [ 'good', 'bad', 'ugly' ] } diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out index a962fb2d2e..5d7c13cad1 100644 --- a/tests/qapi-schema/comments.out +++ b/tests/qapi-schema/comments.out @@ -2,4 +2,3 @@ enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbo prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty -doc symbol=Status expr=('enum', 'Status') diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err index 424df9bedd..f9613c6d6b 100644 --- a/tests/qapi-schema/double-type.err +++ b/tests/qapi-schema/double-type.err @@ -1 +1 @@ -tests/qapi-schema/double-type.json:6: Unknown key 'command' in struct 'bar' +tests/qapi-schema/double-type.json:2: Unknown key 'command' in struct 'bar' diff --git a/tests/qapi-schema/double-type.json b/tests/qapi-schema/double-type.json index ab59523ff7..911fa7af50 100644 --- a/tests/qapi-schema/double-type.json +++ b/tests/qapi-schema/double-type.json @@ -1,6 +1,2 @@ # we reject an expression with ambiguous metatype - -## -# @foo: -## { 'command': 'foo', 'struct': 'bar', 'data': { } } diff --git a/tests/qapi-schema/enum-bad-name.err b/tests/qapi-schema/enum-bad-name.err index 157d1b0d69..9c3c1002b7 100644 --- a/tests/qapi-schema/enum-bad-name.err +++ b/tests/qapi-schema/enum-bad-name.err @@ -1 +1 @@ -tests/qapi-schema/enum-bad-name.json:6: Member of enum 'MyEnum' uses invalid name 'not^possible' +tests/qapi-schema/enum-bad-name.json:2: Member of enum 'MyEnum' uses invalid name 'not^possible' diff --git a/tests/qapi-schema/enum-bad-name.json b/tests/qapi-schema/enum-bad-name.json index 978cb88994..8506562b31 100644 --- a/tests/qapi-schema/enum-bad-name.json +++ b/tests/qapi-schema/enum-bad-name.json @@ -1,6 +1,2 @@ # we ensure all enum names can map to C - -## -# @MyEnum: -## { 'enum': 'MyEnum', 'data': [ 'not^possible' ] } diff --git a/tests/qapi-schema/enum-bad-prefix.err b/tests/qapi-schema/enum-bad-prefix.err index 918915f7ab..399f5f7af5 100644 --- a/tests/qapi-schema/enum-bad-prefix.err +++ b/tests/qapi-schema/enum-bad-prefix.err @@ -1 +1 @@ -tests/qapi-schema/enum-bad-prefix.json:6: Enum 'MyEnum' requires a string for 'prefix' +tests/qapi-schema/enum-bad-prefix.json:2: Enum 'MyEnum' requires a string for 'prefix' diff --git a/tests/qapi-schema/enum-bad-prefix.json b/tests/qapi-schema/enum-bad-prefix.json index 25f17a7b08..996f628f6d 100644 --- a/tests/qapi-schema/enum-bad-prefix.json +++ b/tests/qapi-schema/enum-bad-prefix.json @@ -1,6 +1,2 @@ # The prefix must be a string type - -## -# @MyEnum: -## { 'enum': 'MyEnum', 'data': [ 'one' ], 'prefix': [ 'fish' ] } diff --git a/tests/qapi-schema/enum-clash-member.err b/tests/qapi-schema/enum-clash-member.err index 25249b63c4..5403c78507 100644 --- a/tests/qapi-schema/enum-clash-member.err +++ b/tests/qapi-schema/enum-clash-member.err @@ -1 +1 @@ -tests/qapi-schema/enum-clash-member.json:6: 'one_two' (member of MyEnum) collides with 'one-two' (member of MyEnum) +tests/qapi-schema/enum-clash-member.json:2: 'one_two' (member of MyEnum) collides with 'one-two' (member of MyEnum) diff --git a/tests/qapi-schema/enum-clash-member.json b/tests/qapi-schema/enum-clash-member.json index fd52751941..b6928b8bfd 100644 --- a/tests/qapi-schema/enum-clash-member.json +++ b/tests/qapi-schema/enum-clash-member.json @@ -1,6 +1,2 @@ # we reject enums where members will clash when mapped to C enum - -## -# @MyEnum: -## { 'enum': 'MyEnum', 'data': [ 'one-two', 'one_two' ] } diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err index 9b7d2f111d..8ca146ea59 100644 --- a/tests/qapi-schema/enum-dict-member.err +++ b/tests/qapi-schema/enum-dict-member.err @@ -1 +1 @@ -tests/qapi-schema/enum-dict-member.json:6: Member of enum 'MyEnum' requires a string name +tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json index 69d30f0c1e..79672e0f09 100644 --- a/tests/qapi-schema/enum-dict-member.json +++ b/tests/qapi-schema/enum-dict-member.json @@ -1,6 +1,2 @@ # we reject any enum member that is not a string - -## -# @MyEnum: -## { 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] } diff --git a/tests/qapi-schema/enum-member-case.err b/tests/qapi-schema/enum-member-case.err index df96e2205a..b652e9aacc 100644 --- a/tests/qapi-schema/enum-member-case.err +++ b/tests/qapi-schema/enum-member-case.err @@ -1 +1 @@ -tests/qapi-schema/enum-member-case.json:10: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase +tests/qapi-schema/enum-member-case.json:3: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase diff --git a/tests/qapi-schema/enum-member-case.json b/tests/qapi-schema/enum-member-case.json index d2e4aba39d..2096b350ca 100644 --- a/tests/qapi-schema/enum-member-case.json +++ b/tests/qapi-schema/enum-member-case.json @@ -1,10 +1,3 @@ # Member names should be 'lower-case' unless the enum is whitelisted - -## -# @UuidInfo: -## { 'enum': 'UuidInfo', 'data': [ 'Value' ] } # UuidInfo is whitelisted -## -# @NoWayThisWillGetWhitelisted: -## { 'enum': 'NoWayThisWillGetWhitelisted', 'data': [ 'Value' ] } diff --git a/tests/qapi-schema/enum-missing-data.err b/tests/qapi-schema/enum-missing-data.err index de4b9e8281..ba4873ae69 100644 --- a/tests/qapi-schema/enum-missing-data.err +++ b/tests/qapi-schema/enum-missing-data.err @@ -1 +1 @@ -tests/qapi-schema/enum-missing-data.json:6: Key 'data' is missing from enum 'MyEnum' +tests/qapi-schema/enum-missing-data.json:2: Key 'data' is missing from enum 'MyEnum' diff --git a/tests/qapi-schema/enum-missing-data.json b/tests/qapi-schema/enum-missing-data.json index d7601f91fb..558fd35e93 100644 --- a/tests/qapi-schema/enum-missing-data.json +++ b/tests/qapi-schema/enum-missing-data.json @@ -1,6 +1,2 @@ # we require that all QAPI enums have a data array - -## -# @MyEnum: -## { 'enum': 'MyEnum' } diff --git a/tests/qapi-schema/enum-wrong-data.err b/tests/qapi-schema/enum-wrong-data.err index c44e9b59dc..11b43471cf 100644 --- a/tests/qapi-schema/enum-wrong-data.err +++ b/tests/qapi-schema/enum-wrong-data.err @@ -1 +1 @@ -tests/qapi-schema/enum-wrong-data.json:6: Enum 'MyEnum' requires an array for 'data' +tests/qapi-schema/enum-wrong-data.json:2: Enum 'MyEnum' requires an array for 'data' diff --git a/tests/qapi-schema/enum-wrong-data.json b/tests/qapi-schema/enum-wrong-data.json index 4b9e97878b..7b3e255c14 100644 --- a/tests/qapi-schema/enum-wrong-data.json +++ b/tests/qapi-schema/enum-wrong-data.json @@ -1,6 +1,2 @@ # we require that all qapi enums have an array for data - -## -# @MyEnum: -## { 'enum': 'MyEnum', 'data': { 'value': 'str' } } diff --git a/tests/qapi-schema/event-boxed-empty.err b/tests/qapi-schema/event-boxed-empty.err index defe656e32..68ec6f2d2b 100644 --- a/tests/qapi-schema/event-boxed-empty.err +++ b/tests/qapi-schema/event-boxed-empty.err @@ -1 +1 @@ -tests/qapi-schema/event-boxed-empty.json:6: Use of 'boxed' requires 'data' +tests/qapi-schema/event-boxed-empty.json:2: Use of 'boxed' requires 'data' diff --git a/tests/qapi-schema/event-boxed-empty.json b/tests/qapi-schema/event-boxed-empty.json index 63b870b31b..cb145f1433 100644 --- a/tests/qapi-schema/event-boxed-empty.json +++ b/tests/qapi-schema/event-boxed-empty.json @@ -1,6 +1,2 @@ # 'boxed' requires a non-empty type - -## -# @FOO: -## { 'event': 'FOO', 'boxed': true } diff --git a/tests/qapi-schema/event-case.json b/tests/qapi-schema/event-case.json index 6b05c5d247..3a92d8b610 100644 --- a/tests/qapi-schema/event-case.json +++ b/tests/qapi-schema/event-case.json @@ -1,7 +1,3 @@ # TODO: might be nice to enforce naming conventions; but until then this works # even though events should usually be ALL_CAPS - -## -# @oops: -## { 'event': 'oops' } diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out index 2865714ad5..5a0f2bf805 100644 --- a/tests/qapi-schema/event-case.out +++ b/tests/qapi-schema/event-case.out @@ -3,4 +3,3 @@ enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbo event oops None boxed=False object q_empty -doc symbol=oops expr=('event', 'oops') diff --git a/tests/qapi-schema/event-nest-struct.err b/tests/qapi-schema/event-nest-struct.err index 17a6c3c7b9..5a42701b8f 100644 --- a/tests/qapi-schema/event-nest-struct.err +++ b/tests/qapi-schema/event-nest-struct.err @@ -1 +1 @@ -tests/qapi-schema/event-nest-struct.json:5: Member 'a' of 'data' for event 'EVENT_A' should be a type name +tests/qapi-schema/event-nest-struct.json:1: Member 'a' of 'data' for event 'EVENT_A' should be a type name diff --git a/tests/qapi-schema/event-nest-struct.json b/tests/qapi-schema/event-nest-struct.json index 328e0a64d3..ee6f3ecb6f 100644 --- a/tests/qapi-schema/event-nest-struct.json +++ b/tests/qapi-schema/event-nest-struct.json @@ -1,6 +1,2 @@ -## -# @EVENT_A: -# event-nest-struct -## { 'event': 'EVENT_A', 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } diff --git a/tests/qapi-schema/flat-union-array-branch.err b/tests/qapi-schema/flat-union-array-branch.err index e456094993..8ea91eadb2 100644 --- a/tests/qapi-schema/flat-union-array-branch.err +++ b/tests/qapi-schema/flat-union-array-branch.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-array-branch.json:20: Member 'value1' of union 'TestUnion' cannot be an array +tests/qapi-schema/flat-union-array-branch.json:8: Member 'value1' of union 'TestUnion' cannot be an array diff --git a/tests/qapi-schema/flat-union-array-branch.json b/tests/qapi-schema/flat-union-array-branch.json index 51dde10392..0b98820a8f 100644 --- a/tests/qapi-schema/flat-union-array-branch.json +++ b/tests/qapi-schema/flat-union-array-branch.json @@ -1,22 +1,10 @@ -## -# @TestEnum: -## # we require flat union branches to be a struct { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @Base: -## { 'struct': 'Base', 'data': { 'enum1': 'TestEnum' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'Base', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-bad-base.err b/tests/qapi-schema/flat-union-bad-base.err index 072ffbaadd..bee24a217a 100644 --- a/tests/qapi-schema/flat-union-bad-base.err +++ b/tests/qapi-schema/flat-union-bad-base.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-bad-base.json:21: 'string' (member of TestTypeA) collides with 'string' (base of TestUnion) +tests/qapi-schema/flat-union-bad-base.json:8: 'string' (member of TestTypeA) collides with 'string' (base of TestUnion) diff --git a/tests/qapi-schema/flat-union-bad-base.json b/tests/qapi-schema/flat-union-bad-base.json index 7713e7f0ad..74dd421708 100644 --- a/tests/qapi-schema/flat-union-bad-base.json +++ b/tests/qapi-schema/flat-union-bad-base.json @@ -1,23 +1,10 @@ # we allow anonymous base, but enforce no duplicate keys - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': { 'enum1': 'TestEnum', 'string': 'str' }, 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-bad-discriminator.err b/tests/qapi-schema/flat-union-bad-discriminator.err index 1be4e7b23a..c38cc8e4df 100644 --- a/tests/qapi-schema/flat-union-bad-discriminator.err +++ b/tests/qapi-schema/flat-union-bad-discriminator.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-bad-discriminator.json:27: Discriminator of flat union 'TestUnion' requires a string name +tests/qapi-schema/flat-union-bad-discriminator.json:11: Discriminator of flat union 'TestUnion' requires a string name diff --git a/tests/qapi-schema/flat-union-bad-discriminator.json b/tests/qapi-schema/flat-union-bad-discriminator.json index ef92f9b583..cd10b9d901 100644 --- a/tests/qapi-schema/flat-union-bad-discriminator.json +++ b/tests/qapi-schema/flat-union-bad-discriminator.json @@ -1,29 +1,13 @@ # we require the discriminator to be a string naming a base-type member # this tests the old syntax for anonymous unions before we added alternates - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestBase: -## { 'struct': 'TestBase', 'data': { 'enum1': 'TestEnum', 'kind': 'str' } } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'TestBase', 'discriminator': {}, diff --git a/tests/qapi-schema/flat-union-base-any.err b/tests/qapi-schema/flat-union-base-any.err index c1ea2d76b3..646f1c9cd1 100644 --- a/tests/qapi-schema/flat-union-base-any.err +++ b/tests/qapi-schema/flat-union-base-any.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-base-any.json:21: 'base' for union 'TestUnion' cannot use built-in type 'any' +tests/qapi-schema/flat-union-base-any.json:8: 'base' for union 'TestUnion' cannot use built-in type 'any' diff --git a/tests/qapi-schema/flat-union-base-any.json b/tests/qapi-schema/flat-union-base-any.json index 3dfb02fa30..fe66b713ef 100644 --- a/tests/qapi-schema/flat-union-base-any.json +++ b/tests/qapi-schema/flat-union-base-any.json @@ -1,23 +1,10 @@ # we require the base to be an existing struct - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'any', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-base-union.err b/tests/qapi-schema/flat-union-base-union.err index ccc5e85876..f138395e45 100644 --- a/tests/qapi-schema/flat-union-base-union.err +++ b/tests/qapi-schema/flat-union-base-union.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-base-union.json:30: 'base' for union 'TestUnion' cannot use union type 'UnionBase' +tests/qapi-schema/flat-union-base-union.json:14: 'base' for union 'TestUnion' cannot use union type 'UnionBase' diff --git a/tests/qapi-schema/flat-union-base-union.json b/tests/qapi-schema/flat-union-base-union.json index c63c6130b8..98b4eba181 100644 --- a/tests/qapi-schema/flat-union-base-union.json +++ b/tests/qapi-schema/flat-union-base-union.json @@ -2,31 +2,15 @@ # TODO: It would be possible to allow a union as a base, as long as all # permutations of QMP names exposed by base do not clash with any QMP # member names added by local variants. - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @UnionBase: -## { 'union': 'UnionBase', 'data': { 'kind1': 'TestTypeA', 'kind2': 'TestTypeB' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'UnionBase', 'discriminator': 'type', diff --git a/tests/qapi-schema/flat-union-clash-member.err b/tests/qapi-schema/flat-union-clash-member.err index fe12a07e2d..2adf69755a 100644 --- a/tests/qapi-schema/flat-union-clash-member.err +++ b/tests/qapi-schema/flat-union-clash-member.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-clash-member.json:27: 'name' (member of Branch1) collides with 'name' (member of Base) +tests/qapi-schema/flat-union-clash-member.json:11: 'name' (member of Branch1) collides with 'name' (member of Base) diff --git a/tests/qapi-schema/flat-union-clash-member.json b/tests/qapi-schema/flat-union-clash-member.json index 9000b94f16..9efc7719b8 100644 --- a/tests/qapi-schema/flat-union-clash-member.json +++ b/tests/qapi-schema/flat-union-clash-member.json @@ -1,29 +1,13 @@ # We check for no duplicate keys between branch members and base # base's member 'name' clashes with Branch1's - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @Base: -## { 'struct': 'Base', 'data': { 'enum1': 'TestEnum', '*name': 'str' } } -## -# @Branch1: -## { 'struct': 'Branch1', 'data': { 'name': 'str' } } -## -# @Branch2: -## { 'struct': 'Branch2', 'data': { 'value': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'Base', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-empty.err b/tests/qapi-schema/flat-union-empty.err index ead7bd4fcb..15754f54eb 100644 --- a/tests/qapi-schema/flat-union-empty.err +++ b/tests/qapi-schema/flat-union-empty.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-empty.json:14: Union 'Union' cannot have empty 'data' +tests/qapi-schema/flat-union-empty.json:4: Union 'Union' cannot have empty 'data' diff --git a/tests/qapi-schema/flat-union-empty.json b/tests/qapi-schema/flat-union-empty.json index afa8988205..77f1d9abfb 100644 --- a/tests/qapi-schema/flat-union-empty.json +++ b/tests/qapi-schema/flat-union-empty.json @@ -1,14 +1,4 @@ # flat unions cannot be empty - -## -# @Empty: -## { 'enum': 'Empty', 'data': [ ] } -## -# @Base: -## { 'struct': 'Base', 'data': { 'type': 'Empty' } } -## -# @Union: -## { 'union': 'Union', 'base': 'Base', 'discriminator': 'type', 'data': { } } diff --git a/tests/qapi-schema/flat-union-incomplete-branch.err b/tests/qapi-schema/flat-union-incomplete-branch.err index c655bbfb4a..e826bf0789 100644 --- a/tests/qapi-schema/flat-union-incomplete-branch.err +++ b/tests/qapi-schema/flat-union-incomplete-branch.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-incomplete-branch.json:16: Union 'TestUnion' data missing 'value2' branch +tests/qapi-schema/flat-union-incomplete-branch.json:6: Union 'TestUnion' data missing 'value2' branch diff --git a/tests/qapi-schema/flat-union-incomplete-branch.json b/tests/qapi-schema/flat-union-incomplete-branch.json index dea03775c7..25a411bc83 100644 --- a/tests/qapi-schema/flat-union-incomplete-branch.json +++ b/tests/qapi-schema/flat-union-incomplete-branch.json @@ -1,18 +1,8 @@ # we require all branches of the union to be covered - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': { 'type': 'TestEnum' }, 'discriminator': 'type', diff --git a/tests/qapi-schema/flat-union-inline.err b/tests/qapi-schema/flat-union-inline.err index c2c3f7604b..2333358d28 100644 --- a/tests/qapi-schema/flat-union-inline.err +++ b/tests/qapi-schema/flat-union-inline.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-inline.json:17: Member 'value1' of union 'TestUnion' should be a type name +tests/qapi-schema/flat-union-inline.json:7: Member 'value1' of union 'TestUnion' should be a type name diff --git a/tests/qapi-schema/flat-union-inline.json b/tests/qapi-schema/flat-union-inline.json index 400f0817a1..62c7cda617 100644 --- a/tests/qapi-schema/flat-union-inline.json +++ b/tests/qapi-schema/flat-union-inline.json @@ -1,19 +1,9 @@ # we require branches to be a struct name # TODO: should we allow anonymous inline branch types? - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @Base: -## { 'struct': 'Base', 'data': { 'enum1': 'TestEnum', 'kind': 'str' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'Base', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-int-branch.err b/tests/qapi-schema/flat-union-int-branch.err index 299cbb24b2..faf01573b7 100644 --- a/tests/qapi-schema/flat-union-int-branch.err +++ b/tests/qapi-schema/flat-union-int-branch.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-int-branch.json:21: Member 'value1' of union 'TestUnion' cannot use built-in type 'int' +tests/qapi-schema/flat-union-int-branch.json:8: Member 'value1' of union 'TestUnion' cannot use built-in type 'int' diff --git a/tests/qapi-schema/flat-union-int-branch.json b/tests/qapi-schema/flat-union-int-branch.json index 9603e172f8..9370c349e8 100644 --- a/tests/qapi-schema/flat-union-int-branch.json +++ b/tests/qapi-schema/flat-union-int-branch.json @@ -1,23 +1,10 @@ # we require flat union branches to be a struct - -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @Base: -## { 'struct': 'Base', 'data': { 'enum1': 'TestEnum' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'Base', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-invalid-branch-key.err b/tests/qapi-schema/flat-union-invalid-branch-key.err index 455f2dc083..ccf72d2dfe 100644 --- a/tests/qapi-schema/flat-union-invalid-branch-key.err +++ b/tests/qapi-schema/flat-union-invalid-branch-key.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-invalid-branch-key.json:28: Discriminator value 'value_wrong' is not found in enum 'TestEnum' +tests/qapi-schema/flat-union-invalid-branch-key.json:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum' diff --git a/tests/qapi-schema/flat-union-invalid-branch-key.json b/tests/qapi-schema/flat-union-invalid-branch-key.json index 00f28966ff..95ff7746bf 100644 --- a/tests/qapi-schema/flat-union-invalid-branch-key.json +++ b/tests/qapi-schema/flat-union-invalid-branch-key.json @@ -1,30 +1,15 @@ -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestBase: -## { 'struct': 'TestBase', 'data': { 'enum1': 'TestEnum' } } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'TestBase', 'discriminator': 'enum1', diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.err b/tests/qapi-schema/flat-union-invalid-discriminator.err index f0e427b0a7..5f4055614e 100644 --- a/tests/qapi-schema/flat-union-invalid-discriminator.err +++ b/tests/qapi-schema/flat-union-invalid-discriminator.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-invalid-discriminator.json:28: Discriminator 'enum_wrong' is not a member of base struct 'TestBase' +tests/qapi-schema/flat-union-invalid-discriminator.json:13: Discriminator 'enum_wrong' is not a member of base struct 'TestBase' diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.json b/tests/qapi-schema/flat-union-invalid-discriminator.json index c8700c7d71..48b94c3a4d 100644 --- a/tests/qapi-schema/flat-union-invalid-discriminator.json +++ b/tests/qapi-schema/flat-union-invalid-discriminator.json @@ -1,30 +1,15 @@ -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestBase: -## { 'struct': 'TestBase', 'data': { 'enum1': 'TestEnum' } } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'TestBase', 'discriminator': 'enum_wrong', diff --git a/tests/qapi-schema/flat-union-no-base.err b/tests/qapi-schema/flat-union-no-base.err index a2d0a81aa0..841c93b554 100644 --- a/tests/qapi-schema/flat-union-no-base.err +++ b/tests/qapi-schema/flat-union-no-base.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-no-base.json:22: Flat union 'TestUnion' must have a base +tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a base diff --git a/tests/qapi-schema/flat-union-no-base.json b/tests/qapi-schema/flat-union-no-base.json index 641f68aea4..ffc4c6f0e6 100644 --- a/tests/qapi-schema/flat-union-no-base.json +++ b/tests/qapi-schema/flat-union-no-base.json @@ -1,24 +1,11 @@ # flat unions require a base # TODO: simple unions should be able to use an enum discriminator - -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @Enum: -## { 'enum': 'Enum', 'data': [ 'value1', 'value2' ] } -## -# @TestUnion: -## { 'union': 'TestUnion', 'discriminator': 'Enum', 'data': { 'value1': 'TestTypeA', diff --git a/tests/qapi-schema/flat-union-optional-discriminator.err b/tests/qapi-schema/flat-union-optional-discriminator.err index e15f8564dd..aaabedb3bd 100644 --- a/tests/qapi-schema/flat-union-optional-discriminator.err +++ b/tests/qapi-schema/flat-union-optional-discriminator.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-optional-discriminator.json:19: Discriminator of flat union 'MyUnion' does not allow optional name '*switch' +tests/qapi-schema/flat-union-optional-discriminator.json:6: Discriminator of flat union 'MyUnion' does not allow optional name '*switch' diff --git a/tests/qapi-schema/flat-union-optional-discriminator.json b/tests/qapi-schema/flat-union-optional-discriminator.json index 9f19af5789..08a8f7ef8b 100644 --- a/tests/qapi-schema/flat-union-optional-discriminator.json +++ b/tests/qapi-schema/flat-union-optional-discriminator.json @@ -1,21 +1,8 @@ # we require the discriminator to be non-optional - -## -# @Enum: -## { 'enum': 'Enum', 'data': [ 'one', 'two' ] } -## -# @Base: -## { 'struct': 'Base', 'data': { '*switch': 'Enum' } } -## -# @Branch: -## { 'struct': 'Branch', 'data': { 'name': 'str' } } -## -# @MyUnion: -## { 'union': 'MyUnion', 'base': 'Base', 'discriminator': '*switch', diff --git a/tests/qapi-schema/flat-union-string-discriminator.err b/tests/qapi-schema/flat-union-string-discriminator.err index bc0c133aa9..200016bd5c 100644 --- a/tests/qapi-schema/flat-union-string-discriminator.err +++ b/tests/qapi-schema/flat-union-string-discriminator.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-string-discriminator.json:28: Discriminator 'kind' must be of enumeration type +tests/qapi-schema/flat-union-string-discriminator.json:13: Discriminator 'kind' must be of enumeration type diff --git a/tests/qapi-schema/flat-union-string-discriminator.json b/tests/qapi-schema/flat-union-string-discriminator.json index 47a17d2e4a..8af60333b6 100644 --- a/tests/qapi-schema/flat-union-string-discriminator.json +++ b/tests/qapi-schema/flat-union-string-discriminator.json @@ -1,30 +1,15 @@ -## -# @TestEnum: -## { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } -## -# @TestBase: -## { 'struct': 'TestBase', 'data': { 'enum1': 'TestEnum', 'kind': 'str' } } -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'TestBase', 'discriminator': 'kind', diff --git a/tests/qapi-schema/ident-with-escape.json b/tests/qapi-schema/ident-with-escape.json index c03404bee3..56617501e7 100644 --- a/tests/qapi-schema/ident-with-escape.json +++ b/tests/qapi-schema/ident-with-escape.json @@ -1,8 +1,4 @@ # we allow escape sequences in strings, if they map back to ASCII # { 'command': 'fooA', 'data': { 'bar1': 'str' } } - -## -# @fooA: -## { 'c\u006fmmand': '\u0066\u006f\u006FA', 'd\u0061ta': { '\u0062\u0061\u00721': '\u0073\u0074\u0072' } } diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index 69fc908e68..1d2722c02e 100644 --- a/tests/qapi-schema/ident-with-escape.out +++ b/tests/qapi-schema/ident-with-escape.out @@ -5,4 +5,3 @@ command fooA q_obj_fooA-arg -> None object q_empty object q_obj_fooA-arg member bar1: str optional=False -doc symbol=fooA expr=('command', 'fooA') diff --git a/tests/qapi-schema/include-relpath-sub.json b/tests/qapi-schema/include-relpath-sub.json index b4bd8a23d7..4bd4af4162 100644 --- a/tests/qapi-schema/include-relpath-sub.json +++ b/tests/qapi-schema/include-relpath-sub.json @@ -1,5 +1,2 @@ -## -# @Status: -## { 'enum': 'Status', 'data': [ 'good', 'bad', 'ugly' ] } diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out index a962fb2d2e..5d7c13cad1 100644 --- a/tests/qapi-schema/include-relpath.out +++ b/tests/qapi-schema/include-relpath.out @@ -2,4 +2,3 @@ enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbo prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty -doc symbol=Status expr=('enum', 'Status') diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out index a962fb2d2e..5d7c13cad1 100644 --- a/tests/qapi-schema/include-repetition.out +++ b/tests/qapi-schema/include-repetition.out @@ -2,4 +2,3 @@ enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbo prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty -doc symbol=Status expr=('enum', 'Status') diff --git a/tests/qapi-schema/include-simple-sub.json b/tests/qapi-schema/include-simple-sub.json index b4bd8a23d7..4bd4af4162 100644 --- a/tests/qapi-schema/include-simple-sub.json +++ b/tests/qapi-schema/include-simple-sub.json @@ -1,5 +1,2 @@ -## -# @Status: -## { 'enum': 'Status', 'data': [ 'good', 'bad', 'ugly' ] } diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out index a962fb2d2e..5d7c13cad1 100644 --- a/tests/qapi-schema/include-simple.out +++ b/tests/qapi-schema/include-simple.out @@ -2,4 +2,3 @@ enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbo prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty -doc symbol=Status expr=('enum', 'Status') diff --git a/tests/qapi-schema/indented-expr.json b/tests/qapi-schema/indented-expr.json index d759be1877..7115d3131e 100644 --- a/tests/qapi-schema/indented-expr.json +++ b/tests/qapi-schema/indented-expr.json @@ -1,8 +1,2 @@ -## -# @eins: -## { 'command' : 'eins' } -## -# @zwei: -## { 'command' : 'zwei' } diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index 285d052257..e8171c935f 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -5,5 +5,3 @@ command eins None -> None object q_empty command zwei None -> None gen=True success_response=True boxed=False -doc symbol=eins expr=('command', 'eins') -doc symbol=zwei expr=('command', 'zwei') diff --git a/tests/qapi-schema/missing-type.err b/tests/qapi-schema/missing-type.err index 74c4ef7324..b3e7b14e42 100644 --- a/tests/qapi-schema/missing-type.err +++ b/tests/qapi-schema/missing-type.err @@ -1 +1 @@ -tests/qapi-schema/missing-type.json:6: Expression is missing metatype +tests/qapi-schema/missing-type.json:2: Expression is missing metatype diff --git a/tests/qapi-schema/missing-type.json b/tests/qapi-schema/missing-type.json index c2fc62d0af..ff5349d3fe 100644 --- a/tests/qapi-schema/missing-type.json +++ b/tests/qapi-schema/missing-type.json @@ -1,6 +1,2 @@ # we reject an expression with missing metatype - -## -# @foo: -## { 'data': { } } diff --git a/tests/qapi-schema/nested-struct-data.err b/tests/qapi-schema/nested-struct-data.err index 379bd1d3f4..da767bade2 100644 --- a/tests/qapi-schema/nested-struct-data.err +++ b/tests/qapi-schema/nested-struct-data.err @@ -1 +1 @@ -tests/qapi-schema/nested-struct-data.json:6: Member 'a' of 'data' for command 'foo' should be a type name +tests/qapi-schema/nested-struct-data.json:2: Member 'a' of 'data' for command 'foo' should be a type name diff --git a/tests/qapi-schema/nested-struct-data.json b/tests/qapi-schema/nested-struct-data.json index 6106e15e86..efbe773ded 100644 --- a/tests/qapi-schema/nested-struct-data.json +++ b/tests/qapi-schema/nested-struct-data.json @@ -1,7 +1,3 @@ # inline subtypes collide with our desired future use of defaults - -## -# @foo: -## { 'command': 'foo', 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index f4d8cc4230..17194637ba 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -3,153 +3,67 @@ # This file is a stress test of supported qapi constructs that must # parse and compile correctly. -## -# = Section -# == subsection -# -# Some text foo with *strong* and _emphasis_ -# 1. with a list -# 2. like that @foo -# -# And some code: -# | $ echo foo -# | -> do this -# | <- get that -# -# Note: is not a meta -## - -## -# @TestStruct: -# -# body with @var -# -# @integer: foo -# blah -# -# bao -# -# @boolean: bar -# @string: baz -# -# Example: -# -# -> { "execute": ... } -# <- { "return": ... } -# -# Since: 2.3 -# Note: a note -# -## { 'struct': 'TestStruct', 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } } -## -# @NestedEnumsOne: # for testing enums -## { 'struct': 'NestedEnumsOne', 'data': { 'enum1': 'EnumOne', # Intentional forward reference '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } } -## -# @MyEnum: # An empty enum, although unusual, is currently acceptable -## { 'enum': 'MyEnum', 'data': [ ] } -## -# @Empty1: # Likewise for an empty struct, including an empty base -## { 'struct': 'Empty1', 'data': { } } -## -# @Empty2: -## { 'struct': 'Empty2', 'base': 'Empty1', 'data': { } } -## -# @user_def_cmd0: -## { 'command': 'user_def_cmd0', 'data': 'Empty2', 'returns': 'Empty2' } -## -# @QEnumTwo: # for testing override of default naming heuristic -## { 'enum': 'QEnumTwo', 'prefix': 'QENUM_TWO', 'data': [ 'value1', 'value2' ] } -## -# @UserDefOne: # for testing nested structs -## { 'struct': 'UserDefOne', 'base': 'UserDefZero', # intentional forward reference 'data': { 'string': 'str', '*enum1': 'EnumOne' } } # intentional forward reference -## -# @EnumOne: -## { 'enum': 'EnumOne', 'data': [ 'value1', 'value2', 'value3' ] } -## -# @UserDefZero: -## { 'struct': 'UserDefZero', 'data': { 'integer': 'int' } } -## -# @UserDefTwoDictDict: -## { 'struct': 'UserDefTwoDictDict', 'data': { 'userdef': 'UserDefOne', 'string': 'str' } } -## -# @UserDefTwoDict: -## { 'struct': 'UserDefTwoDict', 'data': { 'string1': 'str', 'dict2': 'UserDefTwoDictDict', '*dict3': 'UserDefTwoDictDict' } } -## -# @UserDefTwo: -## { 'struct': 'UserDefTwo', 'data': { 'string0': 'str', 'dict1': 'UserDefTwoDict' } } -## -# @ForceArrays: # dummy struct to force generation of array types not otherwise mentioned -## { 'struct': 'ForceArrays', 'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'], 'unused3':['TestStruct'] } } -## -# @UserDefA: # for testing unions # Among other things, test that a name collision between branches does # not cause any problems (since only one branch can be in use at a time), # by intentionally using two branches that both have a C member 'a_b' -## { 'struct': 'UserDefA', 'data': { 'boolean': 'bool', '*a_b': 'int' } } -## -# @UserDefB: -## { 'struct': 'UserDefB', 'data': { 'intb': 'int', '*a-b': 'bool' } } -## -# @UserDefFlatUnion: -## { 'union': 'UserDefFlatUnion', 'base': 'UserDefUnionBase', # intentional forward reference 'discriminator': 'enum1', @@ -157,71 +71,35 @@ 'value2' : 'UserDefB', 'value3' : 'UserDefB' } } -## -# @UserDefUnionBase: -## { 'struct': 'UserDefUnionBase', 'base': 'UserDefZero', 'data': { 'string': 'str', 'enum1': 'EnumOne' } } -## -# @UserDefFlatUnion2: # this variant of UserDefFlatUnion defaults to a union that uses members with # allocated types to test corner cases in the cleanup/dealloc visitor -## { 'union': 'UserDefFlatUnion2', 'base': { '*integer': 'int', 'string': 'str', 'enum1': 'QEnumTwo' }, 'discriminator': 'enum1', 'data': { 'value1' : 'UserDefC', # intentional forward reference 'value2' : 'UserDefB' } } -## -# @WrapAlternate: -## { 'struct': 'WrapAlternate', 'data': { 'alt': 'UserDefAlternate' } } -## -# @UserDefAlternate: -## { 'alternate': 'UserDefAlternate', 'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } } -## -# @UserDefC: -## { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } # for testing use of 'number' within alternates -## -# @AltStrBool: -## { 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } } -## -# @AltStrNum: -## { 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } } -## -# @AltNumStr: -## { 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } } -## -# @AltStrInt: -## { 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } } -## -# @AltIntNum: -## { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } -## -# @AltNumInt: -## { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } -## -# @UserDefNativeListUnion: # for testing native lists -## { 'union': 'UserDefNativeListUnion', 'data': { 'integer': ['int'], 's8': ['int8'], @@ -239,61 +117,19 @@ 'any': ['any'] } } # testing commands -## -# @user_def_cmd: -## { 'command': 'user_def_cmd', 'data': {} } -## -# @user_def_cmd1: -## { 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} } -## -# @user_def_cmd2: -## { 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } -## -# Another comment -## - -## -# @guest-get-time: -# -# @guest-get-time body -# -# @a: an integer -# @b: #optional integer -# -# Returns: returns something -# -# Example: -# -# -> { "execute": "guest-get-time", ... } -# <- { "return": "42" } -# -## - # Returning a non-dictionary requires a name from the whitelist { 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } -## -# @guest-sync: -## { 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' } -## -# @boxed-struct: -## { 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' } -## -# @boxed-union: -## { 'command': 'boxed-union', 'data': 'UserDefNativeListUnion', 'boxed': true } -## -# @UserDefOptions: -# # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: # @@ -301,7 +137,6 @@ # # For simplicity, this example doesn't use [type=]discriminator nor optargs # specific to discriminator values. -## { 'struct': 'UserDefOptions', 'data': { '*i64' : [ 'int' ], @@ -311,83 +146,35 @@ '*u64x': 'uint64' } } # testing event -## -# @EventStructOne: -## { 'struct': 'EventStructOne', 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } } -## -# @EVENT_A: -## { 'event': 'EVENT_A' } -## -# @EVENT_B: -## { 'event': 'EVENT_B', 'data': { } } -## -# @EVENT_C: -## { 'event': 'EVENT_C', 'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } } -## -# @EVENT_D: -## { 'event': 'EVENT_D', 'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } } -## -# @EVENT_E: -## { 'event': 'EVENT_E', 'boxed': true, 'data': 'UserDefZero' } -## -# @EVENT_F: -## { 'event': 'EVENT_F', 'boxed': true, 'data': 'UserDefAlternate' } # test that we correctly compile downstream extensions, as well as munge # ticklish names -## -# @__org.qemu_x-Enum: -## { 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] } -## -# @__org.qemu_x-Base: -## { 'struct': '__org.qemu_x-Base', 'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } } -## -# @__org.qemu_x-Struct: -## { 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base', 'data': { '__org.qemu_x-member2': 'str', '*wchar-t': 'int' } } -## -# @__org.qemu_x-Union1: -## { 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } } -## -# @__org.qemu_x-Struct2: -## { 'struct': '__org.qemu_x-Struct2', 'data': { 'array': ['__org.qemu_x-Union1'] } } -## -# @__org.qemu_x-Union2: -## { 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base', 'discriminator': '__org.qemu_x-member1', 'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } } -## -# @__org.qemu_x-Alt: -## { 'alternate': '__org.qemu_x-Alt', 'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } } -## -# @__ORG.QEMU_X-EVENT: -## { 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' } -## -# @__org.qemu_x-command: -## { 'command': '__org.qemu_x-command', 'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'], 'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' }, diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index bc8d496ff4..9d99c4eebb 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -232,133 +232,3 @@ command user_def_cmd1 q_obj_user_def_cmd1-arg -> None gen=True success_response=True boxed=False command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo gen=True success_response=True boxed=False -doc freeform - body= -= Section -== subsection - -Some text foo with *strong* and _emphasis_ -1. with a list -2. like that @foo - -And some code: -| $ echo foo -| -> do this -| <- get that - -Note: is not a meta -doc symbol=TestStruct expr=('struct', 'TestStruct') - arg=integer -foo -blah - -bao - arg=boolean -bar - arg=string -baz - section=Example --> { "execute": ... } -<- { "return": ... } - section=Since -2.3 - section=Note -a note - body= -body with @var -doc symbol=NestedEnumsOne expr=('struct', 'NestedEnumsOne') - body= -for testing enums -doc symbol=MyEnum expr=('enum', 'MyEnum') - body= -An empty enum, although unusual, is currently acceptable -doc symbol=Empty1 expr=('struct', 'Empty1') - body= -Likewise for an empty struct, including an empty base -doc symbol=Empty2 expr=('struct', 'Empty2') -doc symbol=user_def_cmd0 expr=('command', 'user_def_cmd0') -doc symbol=QEnumTwo expr=('enum', 'QEnumTwo') - body= -for testing override of default naming heuristic -doc symbol=UserDefOne expr=('struct', 'UserDefOne') - body= -for testing nested structs -doc symbol=EnumOne expr=('enum', 'EnumOne') -doc symbol=UserDefZero expr=('struct', 'UserDefZero') -doc symbol=UserDefTwoDictDict expr=('struct', 'UserDefTwoDictDict') -doc symbol=UserDefTwoDict expr=('struct', 'UserDefTwoDict') -doc symbol=UserDefTwo expr=('struct', 'UserDefTwo') -doc symbol=ForceArrays expr=('struct', 'ForceArrays') - body= -dummy struct to force generation of array types not otherwise mentioned -doc symbol=UserDefA expr=('struct', 'UserDefA') - body= -for testing unions -Among other things, test that a name collision between branches does -not cause any problems (since only one branch can be in use at a time), -by intentionally using two branches that both have a C member 'a_b' -doc symbol=UserDefB expr=('struct', 'UserDefB') -doc symbol=UserDefFlatUnion expr=('union', 'UserDefFlatUnion') -doc symbol=UserDefUnionBase expr=('struct', 'UserDefUnionBase') -doc symbol=UserDefFlatUnion2 expr=('union', 'UserDefFlatUnion2') - body= -this variant of UserDefFlatUnion defaults to a union that uses members with -allocated types to test corner cases in the cleanup/dealloc visitor -doc symbol=WrapAlternate expr=('struct', 'WrapAlternate') -doc symbol=UserDefAlternate expr=('alternate', 'UserDefAlternate') -doc symbol=UserDefC expr=('struct', 'UserDefC') -doc symbol=AltStrBool expr=('alternate', 'AltStrBool') -doc symbol=AltStrNum expr=('alternate', 'AltStrNum') -doc symbol=AltNumStr expr=('alternate', 'AltNumStr') -doc symbol=AltStrInt expr=('alternate', 'AltStrInt') -doc symbol=AltIntNum expr=('alternate', 'AltIntNum') -doc symbol=AltNumInt expr=('alternate', 'AltNumInt') -doc symbol=UserDefNativeListUnion expr=('union', 'UserDefNativeListUnion') - body= -for testing native lists -doc symbol=user_def_cmd expr=('command', 'user_def_cmd') -doc symbol=user_def_cmd1 expr=('command', 'user_def_cmd1') -doc symbol=user_def_cmd2 expr=('command', 'user_def_cmd2') -doc freeform - body= -Another comment -doc symbol=guest-get-time expr=('command', 'guest-get-time') - arg=a -an integer - arg=b -#optional integer - section=Returns -returns something - section=Example --> { "execute": "guest-get-time", ... } -<- { "return": "42" } - body= -@guest-get-time body -doc symbol=guest-sync expr=('command', 'guest-sync') -doc symbol=boxed-struct expr=('command', 'boxed-struct') -doc symbol=boxed-union expr=('command', 'boxed-union') -doc symbol=UserDefOptions expr=('struct', 'UserDefOptions') - body= -For testing integer range flattening in opts-visitor. The following schema -corresponds to the option format: - --userdef i64=3-6,i64=-5--1,u64=2,u16=1,u16=7-12 - -For simplicity, this example doesn't use [type=]discriminator nor optargs -specific to discriminator values. -doc symbol=EventStructOne expr=('struct', 'EventStructOne') -doc symbol=EVENT_A expr=('event', 'EVENT_A') -doc symbol=EVENT_B expr=('event', 'EVENT_B') -doc symbol=EVENT_C expr=('event', 'EVENT_C') -doc symbol=EVENT_D expr=('event', 'EVENT_D') -doc symbol=EVENT_E expr=('event', 'EVENT_E') -doc symbol=EVENT_F expr=('event', 'EVENT_F') -doc symbol=__org.qemu_x-Enum expr=('enum', '__org.qemu_x-Enum') -doc symbol=__org.qemu_x-Base expr=('struct', '__org.qemu_x-Base') -doc symbol=__org.qemu_x-Struct expr=('struct', '__org.qemu_x-Struct') -doc symbol=__org.qemu_x-Union1 expr=('union', '__org.qemu_x-Union1') -doc symbol=__org.qemu_x-Struct2 expr=('struct', '__org.qemu_x-Struct2') -doc symbol=__org.qemu_x-Union2 expr=('union', '__org.qemu_x-Union2') -doc symbol=__org.qemu_x-Alt expr=('alternate', '__org.qemu_x-Alt') -doc symbol=__ORG.QEMU_X-EVENT expr=('event', '__ORG.QEMU_X-EVENT') -doc symbol=__org.qemu_x-command expr=('command', '__org.qemu_x-command') diff --git a/tests/qapi-schema/redefined-builtin.err b/tests/qapi-schema/redefined-builtin.err index ee0a2adf0b..b2757225c4 100644 --- a/tests/qapi-schema/redefined-builtin.err +++ b/tests/qapi-schema/redefined-builtin.err @@ -1 +1 @@ -tests/qapi-schema/redefined-builtin.json:6: built-in 'size' is already defined +tests/qapi-schema/redefined-builtin.json:2: built-in 'size' is already defined diff --git a/tests/qapi-schema/redefined-builtin.json b/tests/qapi-schema/redefined-builtin.json index 6d3a940d5e..45b8a550ad 100644 --- a/tests/qapi-schema/redefined-builtin.json +++ b/tests/qapi-schema/redefined-builtin.json @@ -1,6 +1,2 @@ # we reject types that duplicate builtin names - -## -# @size: -## { 'struct': 'size', 'data': { 'myint': 'size' } } diff --git a/tests/qapi-schema/redefined-command.err b/tests/qapi-schema/redefined-command.err index 1e297c43ba..82ae256e63 100644 --- a/tests/qapi-schema/redefined-command.err +++ b/tests/qapi-schema/redefined-command.err @@ -1 +1 @@ -tests/qapi-schema/redefined-command.json:10: command 'foo' is already defined +tests/qapi-schema/redefined-command.json:3: command 'foo' is already defined diff --git a/tests/qapi-schema/redefined-command.json b/tests/qapi-schema/redefined-command.json index 3a8cb9024c..247e401948 100644 --- a/tests/qapi-schema/redefined-command.json +++ b/tests/qapi-schema/redefined-command.json @@ -1,10 +1,3 @@ # we reject commands defined more than once - -## -# @foo: -## { 'command': 'foo', 'data': { 'one': 'str' } } -## -# @foo: -## { 'command': 'foo', 'data': { '*two': 'str' } } diff --git a/tests/qapi-schema/redefined-event.err b/tests/qapi-schema/redefined-event.err index 912c785119..35429cb481 100644 --- a/tests/qapi-schema/redefined-event.err +++ b/tests/qapi-schema/redefined-event.err @@ -1 +1 @@ -tests/qapi-schema/redefined-event.json:10: event 'EVENT_A' is already defined +tests/qapi-schema/redefined-event.json:3: event 'EVENT_A' is already defined diff --git a/tests/qapi-schema/redefined-event.json b/tests/qapi-schema/redefined-event.json index ec7aeea0f0..7717e91c18 100644 --- a/tests/qapi-schema/redefined-event.json +++ b/tests/qapi-schema/redefined-event.json @@ -1,10 +1,3 @@ # we reject duplicate events - -## -# @EVENT_A: -## { 'event': 'EVENT_A', 'data': { 'myint': 'int' } } -## -# @EVENT_A: -## { 'event': 'EVENT_A', 'data': { 'myint': 'int' } } diff --git a/tests/qapi-schema/redefined-type.err b/tests/qapi-schema/redefined-type.err index 28d87c098c..06ea78c478 100644 --- a/tests/qapi-schema/redefined-type.err +++ b/tests/qapi-schema/redefined-type.err @@ -1 +1 @@ -tests/qapi-schema/redefined-type.json:10: struct 'foo' is already defined +tests/qapi-schema/redefined-type.json:3: struct 'foo' is already defined diff --git a/tests/qapi-schema/redefined-type.json b/tests/qapi-schema/redefined-type.json index 7a8f3e1ec8..a09e768bae 100644 --- a/tests/qapi-schema/redefined-type.json +++ b/tests/qapi-schema/redefined-type.json @@ -1,10 +1,3 @@ # we reject types defined more than once - -## -# @foo: -## { 'struct': 'foo', 'data': { 'one': 'str' } } -## -# @foo: -## { 'enum': 'foo', 'data': [ 'two' ] } diff --git a/tests/qapi-schema/reserved-command-q.err b/tests/qapi-schema/reserved-command-q.err index 5e17f3169b..f939e044eb 100644 --- a/tests/qapi-schema/reserved-command-q.err +++ b/tests/qapi-schema/reserved-command-q.err @@ -1 +1 @@ -tests/qapi-schema/reserved-command-q.json:12: 'command' uses invalid name 'q-unix' +tests/qapi-schema/reserved-command-q.json:5: 'command' uses invalid name 'q-unix' diff --git a/tests/qapi-schema/reserved-command-q.json b/tests/qapi-schema/reserved-command-q.json index bba0860c99..99f8aae314 100644 --- a/tests/qapi-schema/reserved-command-q.json +++ b/tests/qapi-schema/reserved-command-q.json @@ -1,12 +1,5 @@ # C entity name collision # We reject names like 'q-unix', because they can collide with the mangled # name for 'unix' in generated C. - -## -# @unix: -## { 'command': 'unix' } -## -# @q-unix: -## { 'command': 'q-unix' } diff --git a/tests/qapi-schema/reserved-enum-q.err b/tests/qapi-schema/reserved-enum-q.err index acb2df811d..e1c3480ee2 100644 --- a/tests/qapi-schema/reserved-enum-q.err +++ b/tests/qapi-schema/reserved-enum-q.err @@ -1 +1 @@ -tests/qapi-schema/reserved-enum-q.json:8: Member of enum 'Foo' uses invalid name 'q-Unix' +tests/qapi-schema/reserved-enum-q.json:4: Member of enum 'Foo' uses invalid name 'q-Unix' diff --git a/tests/qapi-schema/reserved-enum-q.json b/tests/qapi-schema/reserved-enum-q.json index 6c7e7177c3..3593a765ea 100644 --- a/tests/qapi-schema/reserved-enum-q.json +++ b/tests/qapi-schema/reserved-enum-q.json @@ -1,8 +1,4 @@ # C entity name collision # We reject names like 'q-unix', because they can collide with the mangled # name for 'unix' in generated C. - -## -# @Foo: -## { 'enum': 'Foo', 'data': [ 'unix', 'q-Unix' ] } diff --git a/tests/qapi-schema/reserved-member-has.err b/tests/qapi-schema/reserved-member-has.err index 9ace796055..e755771446 100644 --- a/tests/qapi-schema/reserved-member-has.err +++ b/tests/qapi-schema/reserved-member-has.err @@ -1 +1 @@ -tests/qapi-schema/reserved-member-has.json:9: Member of 'data' for command 'oops' uses reserved name 'has-a' +tests/qapi-schema/reserved-member-has.json:5: Member of 'data' for command 'oops' uses reserved name 'has-a' diff --git a/tests/qapi-schema/reserved-member-has.json b/tests/qapi-schema/reserved-member-has.json index f0d8905ca2..45b9109bdc 100644 --- a/tests/qapi-schema/reserved-member-has.json +++ b/tests/qapi-schema/reserved-member-has.json @@ -2,8 +2,4 @@ # We reject names like 'has-a', because they can collide with the flag # for an optional 'a' in generated C. # TODO we could munge the optional flag name to avoid the collision. - -## -# @oops: -## { 'command': 'oops', 'data': { '*a': 'str', 'has-a': 'str' } } diff --git a/tests/qapi-schema/reserved-member-q.err b/tests/qapi-schema/reserved-member-q.err index 1709a88462..f3d5dd7818 100644 --- a/tests/qapi-schema/reserved-member-q.err +++ b/tests/qapi-schema/reserved-member-q.err @@ -1 +1 @@ -tests/qapi-schema/reserved-member-q.json:8: Member of 'data' for struct 'Foo' uses invalid name 'q-unix' +tests/qapi-schema/reserved-member-q.json:4: Member of 'data' for struct 'Foo' uses invalid name 'q-unix' diff --git a/tests/qapi-schema/reserved-member-q.json b/tests/qapi-schema/reserved-member-q.json index f51e312917..62fed8fddf 100644 --- a/tests/qapi-schema/reserved-member-q.json +++ b/tests/qapi-schema/reserved-member-q.json @@ -1,8 +1,4 @@ # C member name collision # We reject names like 'q-unix', because they can collide with the mangled # name for 'unix' in generated C. - -## -# @Foo: -## { 'struct': 'Foo', 'data': { 'unix':'int', 'q-unix':'bool' } } diff --git a/tests/qapi-schema/reserved-member-u.err b/tests/qapi-schema/reserved-member-u.err index 6ec69a712a..87d42296cc 100644 --- a/tests/qapi-schema/reserved-member-u.err +++ b/tests/qapi-schema/reserved-member-u.err @@ -1 +1 @@ -tests/qapi-schema/reserved-member-u.json:11: Member of 'data' for struct 'Oops' uses reserved name 'u' +tests/qapi-schema/reserved-member-u.json:7: Member of 'data' for struct 'Oops' uses reserved name 'u' diff --git a/tests/qapi-schema/reserved-member-u.json b/tests/qapi-schema/reserved-member-u.json index 3a578e5b56..1eaf0f301c 100644 --- a/tests/qapi-schema/reserved-member-u.json +++ b/tests/qapi-schema/reserved-member-u.json @@ -4,8 +4,4 @@ # This is true even for non-unions, because it is possible to convert a # struct to flat union while remaining backwards compatible in QMP. # TODO - we could munge the member name to 'q_u' to avoid the collision - -## -# @Oops: -## { 'struct': 'Oops', 'data': { 'u': 'str' } } diff --git a/tests/qapi-schema/reserved-member-underscore.err b/tests/qapi-schema/reserved-member-underscore.err index c9aefee3a8..65ff0da8ce 100644 --- a/tests/qapi-schema/reserved-member-underscore.err +++ b/tests/qapi-schema/reserved-member-underscore.err @@ -1 +1 @@ -tests/qapi-schema/reserved-member-underscore.json:8: Member of 'data' for struct 'Oops' uses invalid name '_oops' +tests/qapi-schema/reserved-member-underscore.json:4: Member of 'data' for struct 'Oops' uses invalid name '_oops' diff --git a/tests/qapi-schema/reserved-member-underscore.json b/tests/qapi-schema/reserved-member-underscore.json index cc34b54b02..4a3a017638 100644 --- a/tests/qapi-schema/reserved-member-underscore.json +++ b/tests/qapi-schema/reserved-member-underscore.json @@ -1,8 +1,4 @@ # C member name collision # We reject use of a single leading underscore in all names (names must # begin with a letter or a downstream extension double-underscore prefix). - -## -# @Oops: -## { 'struct': 'Oops', 'data': { '_oops': 'str' } } diff --git a/tests/qapi-schema/reserved-type-kind.err b/tests/qapi-schema/reserved-type-kind.err index 8698073062..0a38efaad8 100644 --- a/tests/qapi-schema/reserved-type-kind.err +++ b/tests/qapi-schema/reserved-type-kind.err @@ -1 +1 @@ -tests/qapi-schema/reserved-type-kind.json:6: enum 'UnionKind' should not end in 'Kind' +tests/qapi-schema/reserved-type-kind.json:2: enum 'UnionKind' should not end in 'Kind' diff --git a/tests/qapi-schema/reserved-type-kind.json b/tests/qapi-schema/reserved-type-kind.json index a094941561..9ecaba12bc 100644 --- a/tests/qapi-schema/reserved-type-kind.json +++ b/tests/qapi-schema/reserved-type-kind.json @@ -1,6 +1,2 @@ # we reject types that would conflict with implicit union enum - -## -# @UnionKind: -## { 'enum': 'UnionKind', 'data': [ 'oops' ] } diff --git a/tests/qapi-schema/reserved-type-list.err b/tests/qapi-schema/reserved-type-list.err index ec0531c4b9..4510fa6d90 100644 --- a/tests/qapi-schema/reserved-type-list.err +++ b/tests/qapi-schema/reserved-type-list.err @@ -1 +1 @@ -tests/qapi-schema/reserved-type-list.json:9: struct 'FooList' should not end in 'List' +tests/qapi-schema/reserved-type-list.json:5: struct 'FooList' should not end in 'List' diff --git a/tests/qapi-schema/reserved-type-list.json b/tests/qapi-schema/reserved-type-list.json index 6effb78e7f..98d53bf808 100644 --- a/tests/qapi-schema/reserved-type-list.json +++ b/tests/qapi-schema/reserved-type-list.json @@ -2,8 +2,4 @@ # We reserve names ending in 'List' for use by array types. # TODO - we could choose array names to avoid collision with user types, # in order to let this compile - -## -# @FooList: -## { 'struct': 'FooList', 'data': { 's': 'str' } } diff --git a/tests/qapi-schema/returns-alternate.err b/tests/qapi-schema/returns-alternate.err index 2b81623ca3..dfbb419cac 100644 --- a/tests/qapi-schema/returns-alternate.err +++ b/tests/qapi-schema/returns-alternate.err @@ -1 +1 @@ -tests/qapi-schema/returns-alternate.json:10: 'returns' for command 'oops' cannot use alternate type 'Alt' +tests/qapi-schema/returns-alternate.json:3: 'returns' for command 'oops' cannot use alternate type 'Alt' diff --git a/tests/qapi-schema/returns-alternate.json b/tests/qapi-schema/returns-alternate.json index 005bf2d148..972390c06b 100644 --- a/tests/qapi-schema/returns-alternate.json +++ b/tests/qapi-schema/returns-alternate.json @@ -1,10 +1,3 @@ # we reject returns if it is an alternate type - -## -# @Alt: -## { 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } } -## -# @oops: -## { 'command': 'oops', 'returns': 'Alt' } diff --git a/tests/qapi-schema/returns-array-bad.err b/tests/qapi-schema/returns-array-bad.err index b53bdb0ade..138095ccde 100644 --- a/tests/qapi-schema/returns-array-bad.err +++ b/tests/qapi-schema/returns-array-bad.err @@ -1 +1 @@ -tests/qapi-schema/returns-array-bad.json:6: 'returns' for command 'oops': array type must contain single type name +tests/qapi-schema/returns-array-bad.json:2: 'returns' for command 'oops': array type must contain single type name diff --git a/tests/qapi-schema/returns-array-bad.json b/tests/qapi-schema/returns-array-bad.json index 30528fed29..09b0b1f182 100644 --- a/tests/qapi-schema/returns-array-bad.json +++ b/tests/qapi-schema/returns-array-bad.json @@ -1,6 +1,2 @@ # we reject an array return that is not a single type - -## -# @oops: -## { 'command': 'oops', 'returns': [ 'str', 'str' ] } diff --git a/tests/qapi-schema/returns-dict.err b/tests/qapi-schema/returns-dict.err index 1570a35d49..eb2d0c4661 100644 --- a/tests/qapi-schema/returns-dict.err +++ b/tests/qapi-schema/returns-dict.err @@ -1 +1 @@ -tests/qapi-schema/returns-dict.json:6: 'returns' for command 'oops' should be a type name +tests/qapi-schema/returns-dict.json:2: 'returns' for command 'oops' should be a type name diff --git a/tests/qapi-schema/returns-dict.json b/tests/qapi-schema/returns-dict.json index 6a3ed0f34d..1cfef3ede7 100644 --- a/tests/qapi-schema/returns-dict.json +++ b/tests/qapi-schema/returns-dict.json @@ -1,6 +1,2 @@ # we reject inline struct return type - -## -# @oops: -## { 'command': 'oops', 'returns': { 'a': 'str' } } diff --git a/tests/qapi-schema/returns-unknown.err b/tests/qapi-schema/returns-unknown.err index d76bcfe455..1f43e3ac9f 100644 --- a/tests/qapi-schema/returns-unknown.err +++ b/tests/qapi-schema/returns-unknown.err @@ -1 +1 @@ -tests/qapi-schema/returns-unknown.json:6: 'returns' for command 'oops' uses unknown type 'NoSuchType' +tests/qapi-schema/returns-unknown.json:2: 'returns' for command 'oops' uses unknown type 'NoSuchType' diff --git a/tests/qapi-schema/returns-unknown.json b/tests/qapi-schema/returns-unknown.json index 3837f0e607..25bd498bff 100644 --- a/tests/qapi-schema/returns-unknown.json +++ b/tests/qapi-schema/returns-unknown.json @@ -1,6 +1,2 @@ # we reject returns if it does not contain a known type - -## -# @oops: -## { 'command': 'oops', 'returns': 'NoSuchType' } diff --git a/tests/qapi-schema/returns-whitelist.err b/tests/qapi-schema/returns-whitelist.err index e77ea2da3f..f47c1ee7ca 100644 --- a/tests/qapi-schema/returns-whitelist.err +++ b/tests/qapi-schema/returns-whitelist.err @@ -1 +1 @@ -tests/qapi-schema/returns-whitelist.json:26: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'int' +tests/qapi-schema/returns-whitelist.json:10: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'int' diff --git a/tests/qapi-schema/returns-whitelist.json b/tests/qapi-schema/returns-whitelist.json index 0bc952db87..e8b3cea396 100644 --- a/tests/qapi-schema/returns-whitelist.json +++ b/tests/qapi-schema/returns-whitelist.json @@ -1,27 +1,11 @@ # we enforce that 'returns' be a dict or array of dict unless whitelisted - -## -# @human-monitor-command: -## { 'command': 'human-monitor-command', 'data': {'command-line': 'str', '*cpu-index': 'int'}, 'returns': 'str' } -## -# @TpmModel: -## { 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] } -## -# @query-tpm-models: -## { 'command': 'query-tpm-models', 'returns': ['TpmModel'] } -## -# @guest-get-time: -## { 'command': 'guest-get-time', 'returns': 'int' } -## -# @no-way-this-will-get-whitelisted: -## { 'command': 'no-way-this-will-get-whitelisted', 'returns': [ 'int' ] } diff --git a/tests/qapi-schema/struct-base-clash-deep.err b/tests/qapi-schema/struct-base-clash-deep.err index 1b7c0e9d12..e2d7943f21 100644 --- a/tests/qapi-schema/struct-base-clash-deep.err +++ b/tests/qapi-schema/struct-base-clash-deep.err @@ -1 +1 @@ -tests/qapi-schema/struct-base-clash-deep.json:20: 'name' (member of Sub) collides with 'name' (member of Base) +tests/qapi-schema/struct-base-clash-deep.json:10: 'name' (member of Sub) collides with 'name' (member of Base) diff --git a/tests/qapi-schema/struct-base-clash-deep.json b/tests/qapi-schema/struct-base-clash-deep.json index 646d680ad6..fa873ab5d4 100644 --- a/tests/qapi-schema/struct-base-clash-deep.json +++ b/tests/qapi-schema/struct-base-clash-deep.json @@ -2,21 +2,11 @@ # Here, 'name' would have to appear twice on the wire, locally and # indirectly for the grandparent base; the collision doesn't care that # one instance is optional. - -## -# @Base: -## { 'struct': 'Base', 'data': { 'name': 'str' } } -## -# @Mid: -## { 'struct': 'Mid', 'base': 'Base', 'data': { 'value': 'int' } } -## -# @Sub: -## { 'struct': 'Sub', 'base': 'Mid', 'data': { '*name': 'str' } } diff --git a/tests/qapi-schema/struct-base-clash.err b/tests/qapi-schema/struct-base-clash.err index 5fe6393efa..c52f33d27b 100644 --- a/tests/qapi-schema/struct-base-clash.err +++ b/tests/qapi-schema/struct-base-clash.err @@ -1 +1 @@ -tests/qapi-schema/struct-base-clash.json:12: 'name' (member of Sub) collides with 'name' (member of Base) +tests/qapi-schema/struct-base-clash.json:5: 'name' (member of Sub) collides with 'name' (member of Base) diff --git a/tests/qapi-schema/struct-base-clash.json b/tests/qapi-schema/struct-base-clash.json index a8539958b5..11aec80fe5 100644 --- a/tests/qapi-schema/struct-base-clash.json +++ b/tests/qapi-schema/struct-base-clash.json @@ -1,14 +1,7 @@ # Reject attempts to duplicate QMP members # Here, 'name' would have to appear twice on the wire, locally and for base. - -## -# @Base: -## { 'struct': 'Base', 'data': { 'name': 'str' } } -## -# @Sub: -## { 'struct': 'Sub', 'base': 'Base', 'data': { 'name': 'str' } } diff --git a/tests/qapi-schema/struct-data-invalid.err b/tests/qapi-schema/struct-data-invalid.err index 27163355bd..6644f4c2ad 100644 --- a/tests/qapi-schema/struct-data-invalid.err +++ b/tests/qapi-schema/struct-data-invalid.err @@ -1 +1 @@ -tests/qapi-schema/struct-data-invalid.json:4: 'data' for struct 'foo' should be a dictionary or type name +tests/qapi-schema/struct-data-invalid.json:1: 'data' for struct 'foo' should be a dictionary or type name diff --git a/tests/qapi-schema/struct-data-invalid.json b/tests/qapi-schema/struct-data-invalid.json index aa817bda34..9adbc3bb6b 100644 --- a/tests/qapi-schema/struct-data-invalid.json +++ b/tests/qapi-schema/struct-data-invalid.json @@ -1,5 +1,2 @@ -## -# @foo: -## { 'struct': 'foo', 'data': false } diff --git a/tests/qapi-schema/struct-member-invalid.err b/tests/qapi-schema/struct-member-invalid.err index f2b105ba88..69a326d450 100644 --- a/tests/qapi-schema/struct-member-invalid.err +++ b/tests/qapi-schema/struct-member-invalid.err @@ -1 +1 @@ -tests/qapi-schema/struct-member-invalid.json:4: Member 'a' of 'data' for struct 'foo' should be a type name +tests/qapi-schema/struct-member-invalid.json:1: Member 'a' of 'data' for struct 'foo' should be a type name diff --git a/tests/qapi-schema/struct-member-invalid.json b/tests/qapi-schema/struct-member-invalid.json index 10c74262d3..8f172f7a87 100644 --- a/tests/qapi-schema/struct-member-invalid.json +++ b/tests/qapi-schema/struct-member-invalid.json @@ -1,5 +1,2 @@ -## -# @foo: -## { 'struct': 'foo', 'data': { 'a': false } } diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index b4cde4ff4f..ef74e2c4c8 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -55,17 +55,3 @@ def _print_variants(variants): schema = QAPISchema(sys.argv[1]) schema.visit(QAPISchemaTestVisitor()) - -for doc in schema.docs: - if doc.symbol: - print 'doc symbol=%s expr=%s' % \ - (doc.symbol, doc.expr.items()[0]) - else: - print 'doc freeform' - for arg, section in doc.args.iteritems(): - print ' arg=%s\n%s' % (arg, section) - for section in doc.sections: - print ' section=%s\n%s' % (section.name, section) - body = str(doc.body) - if body: - print ' body=\n%s' % body diff --git a/tests/qapi-schema/type-bypass-bad-gen.err b/tests/qapi-schema/type-bypass-bad-gen.err index bd5431f60b..a83c3c655d 100644 --- a/tests/qapi-schema/type-bypass-bad-gen.err +++ b/tests/qapi-schema/type-bypass-bad-gen.err @@ -1 +1 @@ -tests/qapi-schema/type-bypass-bad-gen.json:6: 'gen' of command 'foo' should only use false value +tests/qapi-schema/type-bypass-bad-gen.json:2: 'gen' of command 'foo' should only use false value diff --git a/tests/qapi-schema/type-bypass-bad-gen.json b/tests/qapi-schema/type-bypass-bad-gen.json index 7162c1a0ca..e8dec34249 100644 --- a/tests/qapi-schema/type-bypass-bad-gen.json +++ b/tests/qapi-schema/type-bypass-bad-gen.json @@ -1,6 +1,2 @@ # 'gen' should only appear with value false - -## -# @foo: -## { 'command': 'foo', 'gen': 'whatever' } diff --git a/tests/qapi-schema/unicode-str.err b/tests/qapi-schema/unicode-str.err index 92ee277370..f621cd6448 100644 --- a/tests/qapi-schema/unicode-str.err +++ b/tests/qapi-schema/unicode-str.err @@ -1 +1 @@ -tests/qapi-schema/unicode-str.json:6: 'command' uses invalid name 'é' +tests/qapi-schema/unicode-str.json:2: 'command' uses invalid name 'é' diff --git a/tests/qapi-schema/unicode-str.json b/tests/qapi-schema/unicode-str.json index 75a08b3d93..5253a1b9f3 100644 --- a/tests/qapi-schema/unicode-str.json +++ b/tests/qapi-schema/unicode-str.json @@ -1,6 +1,2 @@ # we don't support full Unicode strings, yet - -## -# @e: -## { 'command': 'é' } diff --git a/tests/qapi-schema/union-base-no-discriminator.err b/tests/qapi-schema/union-base-no-discriminator.err index ca6ee92357..8b7a24260f 100644 --- a/tests/qapi-schema/union-base-no-discriminator.err +++ b/tests/qapi-schema/union-base-no-discriminator.err @@ -1 +1 @@ -tests/qapi-schema/union-base-no-discriminator.json:23: Simple union 'TestUnion' must not have a base +tests/qapi-schema/union-base-no-discriminator.json:11: Simple union 'TestUnion' must not have a base diff --git a/tests/qapi-schema/union-base-no-discriminator.json b/tests/qapi-schema/union-base-no-discriminator.json index cc6bac1424..1409cf5c9e 100644 --- a/tests/qapi-schema/union-base-no-discriminator.json +++ b/tests/qapi-schema/union-base-no-discriminator.json @@ -1,25 +1,13 @@ -## -# @TestTypeA: -## # we reject simple unions with a base (or flat unions without discriminator) { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @Base: -## { 'struct': 'Base', 'data': { 'string': 'str' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'Base', 'data': { 'value1': 'TestTypeA', diff --git a/tests/qapi-schema/union-branch-case.err b/tests/qapi-schema/union-branch-case.err index 9095bae565..11521901d8 100644 --- a/tests/qapi-schema/union-branch-case.err +++ b/tests/qapi-schema/union-branch-case.err @@ -1 +1 @@ -tests/qapi-schema/union-branch-case.json:6: 'Branch' (branch of NoWayThisWillGetWhitelisted) should not use uppercase +tests/qapi-schema/union-branch-case.json:2: 'Branch' (branch of NoWayThisWillGetWhitelisted) should not use uppercase diff --git a/tests/qapi-schema/union-branch-case.json b/tests/qapi-schema/union-branch-case.json index 6de131548c..e6565dc3b3 100644 --- a/tests/qapi-schema/union-branch-case.json +++ b/tests/qapi-schema/union-branch-case.json @@ -1,6 +1,2 @@ # Branch names should be 'lower-case' unless the union is whitelisted - -## -# @NoWayThisWillGetWhitelisted: -## { 'union': 'NoWayThisWillGetWhitelisted', 'data': { 'Branch': 'int' } } diff --git a/tests/qapi-schema/union-clash-branches.err b/tests/qapi-schema/union-clash-branches.err index 640caeab8c..e5b21135bb 100644 --- a/tests/qapi-schema/union-clash-branches.err +++ b/tests/qapi-schema/union-clash-branches.err @@ -1 +1 @@ -tests/qapi-schema/union-clash-branches.json:8: 'a_b' (branch of TestUnion) collides with 'a-b' (branch of TestUnion) +tests/qapi-schema/union-clash-branches.json:4: 'a_b' (branch of TestUnion) collides with 'a-b' (branch of TestUnion) diff --git a/tests/qapi-schema/union-clash-branches.json b/tests/qapi-schema/union-clash-branches.json index 6615665dfe..3bece8c948 100644 --- a/tests/qapi-schema/union-clash-branches.json +++ b/tests/qapi-schema/union-clash-branches.json @@ -1,9 +1,5 @@ # Union branch name collision # Reject a union that would result in a collision in generated C names (this # would try to generate two members 'a_b'). - -## -# @TestUnion: -## { 'union': 'TestUnion', 'data': { 'a-b': 'int', 'a_b': 'str' } } diff --git a/tests/qapi-schema/union-empty.err b/tests/qapi-schema/union-empty.err index 749bc76fc5..12c20221bd 100644 --- a/tests/qapi-schema/union-empty.err +++ b/tests/qapi-schema/union-empty.err @@ -1 +1 @@ -tests/qapi-schema/union-empty.json:6: Union 'Union' cannot have empty 'data' +tests/qapi-schema/union-empty.json:2: Union 'Union' cannot have empty 'data' diff --git a/tests/qapi-schema/union-empty.json b/tests/qapi-schema/union-empty.json index c9b0a1ef33..1f0b13ca21 100644 --- a/tests/qapi-schema/union-empty.json +++ b/tests/qapi-schema/union-empty.json @@ -1,6 +1,2 @@ # unions cannot be empty - -## -# @Union: -## { 'union': 'Union', 'data': { } } diff --git a/tests/qapi-schema/union-invalid-base.err b/tests/qapi-schema/union-invalid-base.err index 41e238f453..03d7b97a93 100644 --- a/tests/qapi-schema/union-invalid-base.err +++ b/tests/qapi-schema/union-invalid-base.err @@ -1 +1 @@ -tests/qapi-schema/union-invalid-base.json:18: 'base' for union 'TestUnion' cannot use built-in type 'int' +tests/qapi-schema/union-invalid-base.json:8: 'base' for union 'TestUnion' cannot use built-in type 'int' diff --git a/tests/qapi-schema/union-invalid-base.json b/tests/qapi-schema/union-invalid-base.json index fd837cb80b..92be39df69 100644 --- a/tests/qapi-schema/union-invalid-base.json +++ b/tests/qapi-schema/union-invalid-base.json @@ -1,20 +1,10 @@ # a union base type must be a struct - -## -# @TestTypeA: -## { 'struct': 'TestTypeA', 'data': { 'string': 'str' } } -## -# @TestTypeB: -## { 'struct': 'TestTypeB', 'data': { 'integer': 'int' } } -## -# @TestUnion: -## { 'union': 'TestUnion', 'base': 'int', 'discriminator': 'int', diff --git a/tests/qapi-schema/union-optional-branch.err b/tests/qapi-schema/union-optional-branch.err index 60523c07e4..3ada1334dc 100644 --- a/tests/qapi-schema/union-optional-branch.err +++ b/tests/qapi-schema/union-optional-branch.err @@ -1 +1 @@ -tests/qapi-schema/union-optional-branch.json:6: Member of union 'Union' does not allow optional name '*a' +tests/qapi-schema/union-optional-branch.json:2: Member of union 'Union' does not allow optional name '*a' diff --git a/tests/qapi-schema/union-optional-branch.json b/tests/qapi-schema/union-optional-branch.json index 7d2ee4c730..591615fc68 100644 --- a/tests/qapi-schema/union-optional-branch.json +++ b/tests/qapi-schema/union-optional-branch.json @@ -1,6 +1,2 @@ # union branches cannot be optional - -## -# @Union: -## { 'union': 'Union', 'data': { '*a': 'int', 'b': 'str' } } diff --git a/tests/qapi-schema/union-unknown.err b/tests/qapi-schema/union-unknown.err index 5568302205..54fe456f9c 100644 --- a/tests/qapi-schema/union-unknown.err +++ b/tests/qapi-schema/union-unknown.err @@ -1 +1 @@ -tests/qapi-schema/union-unknown.json:6: Member 'unknown' of union 'Union' uses unknown type 'MissingType' +tests/qapi-schema/union-unknown.json:2: Member 'unknown' of union 'Union' uses unknown type 'MissingType' diff --git a/tests/qapi-schema/union-unknown.json b/tests/qapi-schema/union-unknown.json index 5042b23197..aa7e8143d8 100644 --- a/tests/qapi-schema/union-unknown.json +++ b/tests/qapi-schema/union-unknown.json @@ -1,7 +1,3 @@ # we reject a union with unknown type in branch - -## -# @Union: -## { 'union': 'Union', 'data': { 'unknown': 'MissingType' } } diff --git a/tests/qapi-schema/unknown-escape.err b/tests/qapi-schema/unknown-escape.err index 1a4ead632b..000e30ddf3 100644 --- a/tests/qapi-schema/unknown-escape.err +++ b/tests/qapi-schema/unknown-escape.err @@ -1 +1 @@ -tests/qapi-schema/unknown-escape.json:7:21: Unknown escape \x +tests/qapi-schema/unknown-escape.json:3:21: Unknown escape \x diff --git a/tests/qapi-schema/unknown-escape.json b/tests/qapi-schema/unknown-escape.json index e3ae6793f2..8e6891e52a 100644 --- a/tests/qapi-schema/unknown-escape.json +++ b/tests/qapi-schema/unknown-escape.json @@ -1,7 +1,3 @@ # we only recognize JSON escape sequences, plus our \' extension (no \x) - -## -# @foo: -## # { 'command': 'foo', 'data': {} } { 'command': 'foo', 'dat\x61':{} } diff --git a/tests/qapi-schema/unknown-expr-key.err b/tests/qapi-schema/unknown-expr-key.err index b19a668bd6..12f5ed5b43 100644 --- a/tests/qapi-schema/unknown-expr-key.err +++ b/tests/qapi-schema/unknown-expr-key.err @@ -1 +1 @@ -tests/qapi-schema/unknown-expr-key.json:6: Unknown key 'bogus' in struct 'bar' +tests/qapi-schema/unknown-expr-key.json:2: Unknown key 'bogus' in struct 'bar' diff --git a/tests/qapi-schema/unknown-expr-key.json b/tests/qapi-schema/unknown-expr-key.json index 1b764c7b9d..3b2be00cc4 100644 --- a/tests/qapi-schema/unknown-expr-key.json +++ b/tests/qapi-schema/unknown-expr-key.json @@ -1,6 +1,2 @@ # we reject an expression with unknown top-level keys - -## -# @bar: -## { 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { } } From 700dc9f503c61cdd1180e9bf84a225105b22b227 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:53 +0100 Subject: [PATCH 06/49] docs/qapi-code-gen.txt: Drop confusing reference to 'gen' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Section "Commands" qualifies its rules on permitted argument and return types "with one exception noted below when 'gen' is used". The note went away in commit 2d21291. Clean up the dangling references. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau Message-Id: <1489582656-31133-5-git-send-email-armbru@redhat.com> --- docs/qapi-code-gen.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 4b64ee7364..5532b60d91 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -558,22 +558,20 @@ The 'data' argument maps to the "arguments" dictionary passed in as part of a Client JSON Protocol command. The 'data' member is optional and defaults to {} (an empty dictionary). If present, it must be the string name of a complex type, or a dictionary that declares an -anonymous type with the same semantics as a 'struct' expression, with -one exception noted below when 'gen' is used. +anonymous type with the same semantics as a 'struct' expression. The 'returns' member describes what will appear in the "return" member of a Client JSON Protocol reply on successful completion of a command. The member is optional from the command declaration; if absent, the "return" member will be an empty dictionary. If 'returns' is present, it must be the string name of a complex or built-in type, a -one-element array containing the name of a complex or built-in type, -with one exception noted below when 'gen' is used. Although it is -permitted to have the 'returns' member name a built-in type or an -array of built-in types, any command that does this cannot be extended -to return additional information in the future; thus, new commands -should strongly consider returning a dictionary-based type or an array -of dictionaries, even if the dictionary only contains one member at the -present. +one-element array containing the name of a complex or built-in type. +Although it is permitted to have the 'returns' member name a built-in +type or an array of built-in types, any command that does this cannot +be extended to return additional information in the future; thus, new +commands should strongly consider returning a dictionary-based type or +an array of dictionaries, even if the dictionary only contains one +member at the present. All commands in Client JSON Protocol use a dictionary to report failure, with no way to specify that in QAPI. Where the error return From 1554a8fae984cad4704fb94a8cef3c9b42ef6185 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:54 +0100 Subject: [PATCH 07/49] qapi: Have each QAPI schema declare its returns white-list qapi.py has a hardcoded white-list of command names that may violate the rules on permitted return types. Add a new pragma directive 'returns-whitelist', and use it to replace the hard-coded white-list. Signed-off-by: Markus Armbruster Message-Id: <1489582656-31133-6-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake --- docs/qapi-code-gen.txt | 13 ++++---- qapi-schema.json | 12 ++++++++ qga/qapi-schema.json | 15 ++++++++++ scripts/qapi.py | 30 ++++++------------- tests/Makefile.include | 1 + .../pragma-returns-whitelist-crap.err | 1 + .../pragma-returns-whitelist-crap.exit | 1 + .../pragma-returns-whitelist-crap.json | 3 ++ .../pragma-returns-whitelist-crap.out | 0 tests/qapi-schema/qapi-schema-test.json | 7 +++++ tests/qapi-schema/returns-whitelist.err | 2 +- tests/qapi-schema/returns-whitelist.json | 4 +++ 12 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 tests/qapi-schema/pragma-returns-whitelist-crap.err create mode 100644 tests/qapi-schema/pragma-returns-whitelist-crap.exit create mode 100644 tests/qapi-schema/pragma-returns-whitelist-crap.json create mode 100644 tests/qapi-schema/pragma-returns-whitelist-crap.out diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 5532b60d91..3d17005cf6 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -318,6 +318,9 @@ pragma to different values in parts of the schema doesn't work. Pragma 'doc-required' takes a boolean value. If true, documentation is required. Default is false. +Pragma 'returns-whitelist' takes a list of command names that may +violate the rules on permitted return types. Default is none. + === Struct types === @@ -566,12 +569,10 @@ The member is optional from the command declaration; if absent, the "return" member will be an empty dictionary. If 'returns' is present, it must be the string name of a complex or built-in type, a one-element array containing the name of a complex or built-in type. -Although it is permitted to have the 'returns' member name a built-in -type or an array of built-in types, any command that does this cannot -be extended to return additional information in the future; thus, new -commands should strongly consider returning a dictionary-based type or -an array of dictionaries, even if the dictionary only contains one -member at the present. +To return anything else, you have to list the command in pragma +'returns-whitelist'. If you do this, the command cannot be extended +to return additional information in the future. Use of +'returns-whitelist' for new commands is strongly discouraged. All commands in Client JSON Protocol use a dictionary to report failure, with no way to specify that in QAPI. Where the error return diff --git a/qapi-schema.json b/qapi-schema.json index d5438ee2b1..93e9e98b0b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -51,6 +51,18 @@ { 'pragma': { 'doc-required': true } } +# Whitelists to permit QAPI rule violations; think twice before you +# add to them! +{ 'pragma': { + # Commands allowed to return a non-dictionary: + 'returns-whitelist': [ + 'human-monitor-command', + 'qom-get', + 'query-migrate-cache-size', + 'query-tpm-models', + 'query-tpm-types', + 'ringbuf-read' ] } } + # QAPI common definitions { 'include': 'qapi/common.json' } diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 3f3d428fce..a8e4bdabc3 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -13,6 +13,21 @@ { 'pragma': { 'doc-required': true } } +# Whitelists to permit QAPI rule violations; think twice before you +# add to them! +{ 'pragma': { + # Commands allowed to return a non-dictionary: + 'returns-whitelist': [ + 'guest-file-open', + 'guest-fsfreeze-freeze', + 'guest-fsfreeze-freeze-list', + 'guest-fsfreeze-status', + 'guest-fsfreeze-thaw', + 'guest-get-time', + 'guest-set-vcpus', + 'guest-sync', + 'guest-sync-delimited' ] } } + ## # @guest-sync-delimited: # diff --git a/scripts/qapi.py b/scripts/qapi.py index fe9d3cf36d..1d86d85d49 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -41,26 +41,7 @@ doc_required = False # Whitelist of commands allowed to return a non-dictionary -returns_whitelist = [ - # From QMP: - 'human-monitor-command', - 'qom-get', - 'query-migrate-cache-size', - 'query-tpm-models', - 'query-tpm-types', - 'ringbuf-read', - - # From QGA: - 'guest-file-open', - 'guest-fsfreeze-freeze', - 'guest-fsfreeze-freeze-list', - 'guest-fsfreeze-status', - 'guest-fsfreeze-thaw', - 'guest-get-time', - 'guest-set-vcpus', - 'guest-sync', - 'guest-sync-delimited', -] +returns_whitelist = [] # Whitelist of entities allowed to violate case conventions case_whitelist = [ @@ -321,12 +302,19 @@ def _include(self, include, info, base_dir, previously_included): self.docs.extend(exprs_include.docs) def _pragma(self, name, value, info): - global doc_required + global doc_required, returns_whitelist if name == 'doc-required': if not isinstance(value, bool): raise QAPISemError(info, "Pragma 'doc-required' must be boolean") doc_required = value + elif name == 'returns-whitelist': + if (not isinstance(value, list) + or any([not isinstance(elt, str) for elt in value])): + raise QAPISemError(info, + "Pragma returns-whitelist must be" + " a list of strings") + returns_whitelist = value else: raise QAPISemError(info, "Unknown pragma '%s'" % name) diff --git a/tests/Makefile.include b/tests/Makefile.include index 7a58c12a7e..f9da3aa2d4 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -444,6 +444,7 @@ qapi-schema += non-objects.json qapi-schema += pragma-doc-required-crap.json qapi-schema += pragma-extra-junk.json qapi-schema += pragma-non-dict.json +qapi-schema += pragma-returns-whitelist-crap.json qapi-schema += qapi-schema-test.json qapi-schema += quoted-structural-chars.json qapi-schema += redefined-builtin.json diff --git a/tests/qapi-schema/pragma-returns-whitelist-crap.err b/tests/qapi-schema/pragma-returns-whitelist-crap.err new file mode 100644 index 0000000000..5d77021674 --- /dev/null +++ b/tests/qapi-schema/pragma-returns-whitelist-crap.err @@ -0,0 +1 @@ +tests/qapi-schema/pragma-returns-whitelist-crap.json:3: Pragma returns-whitelist must be a list of strings diff --git a/tests/qapi-schema/pragma-returns-whitelist-crap.exit b/tests/qapi-schema/pragma-returns-whitelist-crap.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/pragma-returns-whitelist-crap.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/pragma-returns-whitelist-crap.json b/tests/qapi-schema/pragma-returns-whitelist-crap.json new file mode 100644 index 0000000000..f6b81b093f --- /dev/null +++ b/tests/qapi-schema/pragma-returns-whitelist-crap.json @@ -0,0 +1,3 @@ +# 'returns-whitelist' must be list of strings + +{ 'pragma': { 'returns-whitelist': [ 'good', [ 'bad' ] ] } } diff --git a/tests/qapi-schema/pragma-returns-whitelist-crap.out b/tests/qapi-schema/pragma-returns-whitelist-crap.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 17194637ba..842ea3c5e3 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -3,6 +3,13 @@ # This file is a stress test of supported qapi constructs that must # parse and compile correctly. +# Whitelists to permit QAPI rule violations +{ 'pragma': { + # Commands allowed to return a non-dictionary: + 'returns-whitelist': [ + 'guest-get-time', + 'guest-sync' ] } } + { 'struct': 'TestStruct', 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } } diff --git a/tests/qapi-schema/returns-whitelist.err b/tests/qapi-schema/returns-whitelist.err index f47c1ee7ca..b2ba7a9deb 100644 --- a/tests/qapi-schema/returns-whitelist.err +++ b/tests/qapi-schema/returns-whitelist.err @@ -1 +1 @@ -tests/qapi-schema/returns-whitelist.json:10: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'int' +tests/qapi-schema/returns-whitelist.json:14: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'int' diff --git a/tests/qapi-schema/returns-whitelist.json b/tests/qapi-schema/returns-whitelist.json index e8b3cea396..da209329b1 100644 --- a/tests/qapi-schema/returns-whitelist.json +++ b/tests/qapi-schema/returns-whitelist.json @@ -1,4 +1,8 @@ # we enforce that 'returns' be a dict or array of dict unless whitelisted + +{ 'pragma': { 'returns-whitelist': [ + 'human-monitor-command', 'query-tpm-models', 'guest-get-time' ] } } + { 'command': 'human-monitor-command', 'data': {'command-line': 'str', '*cpu-index': 'int'}, 'returns': 'str' } From 2cfbae3c423ecd13a7722ac7a7dca7ec4168e2ff Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:55 +0100 Subject: [PATCH 08/49] qapi: Have each QAPI schema declare its name rule violations qapi.py has a hardcoded white-list of type names that may violate the rule on use of upper and lower case. Add a new pragma directive 'name-case-whitelist', and use it to replace the hard-coded white-list. Signed-off-by: Markus Armbruster Message-Id: <1489582656-31133-7-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake --- docs/qapi-code-gen.txt | 6 +++++ qapi-schema.json | 11 +++++++++- scripts/qapi.py | 22 +++++++++---------- tests/Makefile.include | 1 + tests/qapi-schema/enum-member-case.err | 2 +- tests/qapi-schema/enum-member-case.json | 1 + .../pragma-name-case-whitelist-crap.err | 1 + .../pragma-name-case-whitelist-crap.exit | 1 + .../pragma-name-case-whitelist-crap.json | 3 +++ .../pragma-name-case-whitelist-crap.out | 0 10 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 tests/qapi-schema/pragma-name-case-whitelist-crap.err create mode 100644 tests/qapi-schema/pragma-name-case-whitelist-crap.exit create mode 100644 tests/qapi-schema/pragma-name-case-whitelist-crap.json create mode 100644 tests/qapi-schema/pragma-name-case-whitelist-crap.out diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 3d17005cf6..2f67900b4c 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -252,6 +252,9 @@ Any name (command, event, type, member, or enum value) beginning with "x-" is marked experimental, and may be withdrawn or changed incompatibly in a future release. +Pragma 'name-case-whitelist' lets you violate the rules on use of +upper and lower case. Use for new code is strongly discouraged. + In the rest of this document, usage lines are given for each expression type, with literal strings written in lower case and placeholders written in capitals. If a literal string includes a @@ -321,6 +324,9 @@ is required. Default is false. Pragma 'returns-whitelist' takes a list of command names that may violate the rules on permitted return types. Default is none. +Pragma 'name-case-whitelist' takes a list of names that may violate +rules on use of upper- vs. lower-case letters. Default is none. + === Struct types === diff --git a/qapi-schema.json b/qapi-schema.json index 93e9e98b0b..17c766ee3b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -61,7 +61,16 @@ 'query-migrate-cache-size', 'query-tpm-models', 'query-tpm-types', - 'ringbuf-read' ] } } + 'ringbuf-read' ], + 'name-case-whitelist': [ + 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status + 'CpuInfoMIPS', # PC, visible through query-cpu + 'CpuInfoTricore', # PC, visible through query-cpu + 'QapiErrorClass', # all members, visible through errors + 'UuidInfo', # UUID, visible through query-uuid + 'X86CPURegister32', # all members, visible indirectly through qom-get + 'q_obj_CpuInfo-base' # CPU, visible through query-cpu + ] } } # QAPI common definitions { 'include': 'qapi/common.json' } diff --git a/scripts/qapi.py b/scripts/qapi.py index 1d86d85d49..78db319831 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -44,16 +44,7 @@ returns_whitelist = [] # Whitelist of entities allowed to violate case conventions -case_whitelist = [ - # From QMP: - 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status - 'CpuInfoMIPS', # PC, visible through query-cpu - 'CpuInfoTricore', # PC, visible through query-cpu - 'QapiErrorClass', # all members, visible through errors - 'UuidInfo', # UUID, visible through query-uuid - 'X86CPURegister32', # all members, visible indirectly through qom-get - 'q_obj_CpuInfo-base', # CPU, visible through query-cpu -] +name_case_whitelist = [] enum_types = [] struct_types = [] @@ -302,7 +293,7 @@ def _include(self, include, info, base_dir, previously_included): self.docs.extend(exprs_include.docs) def _pragma(self, name, value, info): - global doc_required, returns_whitelist + global doc_required, returns_whitelist, name_case_whitelist if name == 'doc-required': if not isinstance(value, bool): raise QAPISemError(info, @@ -315,6 +306,13 @@ def _pragma(self, name, value, info): "Pragma returns-whitelist must be" " a list of strings") returns_whitelist = value + elif name == 'name-case-whitelist': + if (not isinstance(value, list) + or any([not isinstance(elt, str) for elt in value])): + raise QAPISemError(info, + "Pragma name-case-whitelist must be" + " a list of strings") + name_case_whitelist = value else: raise QAPISemError(info, "Unknown pragma '%s'" % name) @@ -1287,7 +1285,7 @@ def set_owner(self, name): def check_clash(self, info, seen): cname = c_name(self.name) - if cname.lower() != cname and self.owner not in case_whitelist: + if cname.lower() != cname and self.owner not in name_case_whitelist: raise QAPISemError(info, "%s should not use uppercase" % self.describe()) if cname in seen: diff --git a/tests/Makefile.include b/tests/Makefile.include index f9da3aa2d4..16e0a9f615 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -443,6 +443,7 @@ qapi-schema += nested-struct-data.json qapi-schema += non-objects.json qapi-schema += pragma-doc-required-crap.json qapi-schema += pragma-extra-junk.json +qapi-schema += pragma-name-case-whitelist-crap.json qapi-schema += pragma-non-dict.json qapi-schema += pragma-returns-whitelist-crap.json qapi-schema += qapi-schema-test.json diff --git a/tests/qapi-schema/enum-member-case.err b/tests/qapi-schema/enum-member-case.err index b652e9aacc..3c67a3a067 100644 --- a/tests/qapi-schema/enum-member-case.err +++ b/tests/qapi-schema/enum-member-case.err @@ -1 +1 @@ -tests/qapi-schema/enum-member-case.json:3: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase +tests/qapi-schema/enum-member-case.json:4: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase diff --git a/tests/qapi-schema/enum-member-case.json b/tests/qapi-schema/enum-member-case.json index 2096b350ca..f8af3e4622 100644 --- a/tests/qapi-schema/enum-member-case.json +++ b/tests/qapi-schema/enum-member-case.json @@ -1,3 +1,4 @@ # Member names should be 'lower-case' unless the enum is whitelisted +{ 'pragma': { 'name-case-whitelist': [ 'UuidInfo' ] } } { 'enum': 'UuidInfo', 'data': [ 'Value' ] } # UuidInfo is whitelisted { 'enum': 'NoWayThisWillGetWhitelisted', 'data': [ 'Value' ] } diff --git a/tests/qapi-schema/pragma-name-case-whitelist-crap.err b/tests/qapi-schema/pragma-name-case-whitelist-crap.err new file mode 100644 index 0000000000..f83b97e075 --- /dev/null +++ b/tests/qapi-schema/pragma-name-case-whitelist-crap.err @@ -0,0 +1 @@ +tests/qapi-schema/pragma-name-case-whitelist-crap.json:3: Pragma name-case-whitelist must be a list of strings diff --git a/tests/qapi-schema/pragma-name-case-whitelist-crap.exit b/tests/qapi-schema/pragma-name-case-whitelist-crap.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/pragma-name-case-whitelist-crap.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/pragma-name-case-whitelist-crap.json b/tests/qapi-schema/pragma-name-case-whitelist-crap.json new file mode 100644 index 0000000000..58382bf4e4 --- /dev/null +++ b/tests/qapi-schema/pragma-name-case-whitelist-crap.json @@ -0,0 +1,3 @@ +# 'name-case-whitelist' must be list of strings + +{ 'pragma': { 'name-case-whitelist': null } } diff --git a/tests/qapi-schema/pragma-name-case-whitelist-crap.out b/tests/qapi-schema/pragma-name-case-whitelist-crap.out new file mode 100644 index 0000000000..e69de29bb2 From bd7f974796872fc754c2d01b3a8499e8bb85f844 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:56 +0100 Subject: [PATCH 09/49] qapi: Clean up build of generated documentation Rename intermediate qemu-qapi.texi to qemu-qmp-qapi.texi to match its user qemu-qmp-ref.texi, just like qemu-ga-qapi.texi matches qemu-ga-ref.texi. Build the intermediate .texi next to the sources and the final output in docs/ instead of dumping them into the build root. Fix version.texi dependencies so that only the targets that actually need it depend on it. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-8-git-send-email-armbru@redhat.com> --- .gitignore | 10 +++++----- Makefile | 27 +++++++++++++++------------ docs/qemu-qmp-ref.texi | 2 +- rules.mak | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 2849d756cc..55a001e3b8 100644 --- a/.gitignore +++ b/.gitignore @@ -99,15 +99,15 @@ /pc-bios/optionrom/kvmvapic.img /pc-bios/s390-ccw/s390-ccw.elf /pc-bios/s390-ccw/s390-ccw.img +/docs/qemu-ga-qapi.texi /docs/qemu-ga-ref.html +/docs/qemu-ga-ref.info* /docs/qemu-ga-ref.txt +/docs/qemu-qmp-qapi.texi /docs/qemu-qmp-ref.html +/docs/qemu-qmp-ref.info* /docs/qemu-qmp-ref.txt -docs/qemu-ga-ref.info* -docs/qemu-qmp-ref.info* -/qemu-ga-qapi.texi -/qemu-qapi.texi -/version.texi +/docs/version.texi *.tps .stgit-* cscope.* diff --git a/Makefile b/Makefile index 1c4c04f6f2..35d32ee00a 100644 --- a/Makefile +++ b/Makefile @@ -516,7 +516,7 @@ distclean: clean rm -f qemu-doc.vr qemu-doc.txt rm -f config.log rm -f linux-headers/asm - rm -f qemu-ga-qapi.texi qemu-qapi.texi version.texi + rm -f docs/qemu-ga-qapi.texi docs/qemu-qmp-qapi.texi docs/version.texi rm -f docs/qemu-qmp-ref.7 docs/qemu-ga-ref.7 rm -f docs/qemu-qmp-ref.txt docs/qemu-ga-ref.txt rm -f docs/qemu-qmp-ref.pdf docs/qemu-ga-ref.pdf @@ -663,25 +663,28 @@ ui/console-gl.o: $(SRC_PATH)/ui/console-gl.c \ # documentation MAKEINFO=makeinfo -MAKEINFOFLAGS=--no-split --number-sections +MAKEINFOFLAGS=--no-split --number-sections -I docs TEXIFLAG=$(if $(V),,--quiet) -version.texi: $(SRC_PATH)/VERSION +docs/version.texi: $(SRC_PATH)/VERSION $(call quiet-command,echo "@set VERSION $(VERSION)" > $@,"GEN","$@") -%.html: %.texi version.texi +%.html: %.texi $(call quiet-command,LC_ALL=C $(MAKEINFO) $(MAKEINFOFLAGS) --no-headers \ --html $< -o $@,"GEN","$@") -%.info: %.texi version.texi +%.info: %.texi $(call quiet-command,$(MAKEINFO) $(MAKEINFOFLAGS) $< -o $@,"GEN","$@") -%.txt: %.texi version.texi +%.txt: %.texi $(call quiet-command,LC_ALL=C $(MAKEINFO) $(MAKEINFOFLAGS) --no-headers \ --plaintext $< -o $@,"GEN","$@") -%.pdf: %.texi version.texi - $(call quiet-command,texi2pdf $(TEXIFLAG) -I $(SRC_PATH) -I . $< -o $@,"GEN","$@") +%.pdf: %.texi + $(call quiet-command,texi2pdf $(TEXIFLAG) -I $(SRC_PATH) -I docs $< -o $@,"GEN","$@") + +docs/qemu-ga-ref.html docs/qemu-ga-ref.info docs/qemu-ga-ref.txt docs/qemu-ga-ref.pdf docs/qemu-ga-ref.7.pod: docs/version.texi +docs/qemu-qmp-ref.html docs/qemu-qmp-ref.info docs/qemu-qmp-ref.txt docs/qemu-qmp-ref.pdf docs/qemu-qmp-ref.pod: docs/version.texi qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@") @@ -695,10 +698,10 @@ qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxt qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@") -qemu-qapi.texi: $(qapi-modules) $(qapi-py) +docs/qemu-qmp-qapi.texi: $(qapi-modules) $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi2texi.py $< > $@,"GEN","$@") -qemu-ga-qapi.texi: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py) +docs/qemu-ga-qapi.texi: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi2texi.py $< > $@,"GEN","$@") qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi @@ -719,10 +722,10 @@ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \ qemu-monitor-info.texi docs/qemu-ga-ref.dvi docs/qemu-ga-ref.html docs/qemu-ga-ref.info docs/qemu-ga-ref.pdf docs/qemu-ga-ref.txt docs/qemu-ga-ref.7: \ -docs/qemu-ga-ref.texi qemu-ga-qapi.texi +docs/qemu-ga-ref.texi docs/qemu-ga-qapi.texi docs/qemu-qmp-ref.dvi docs/qemu-qmp-ref.html docs/qemu-qmp-ref.info docs/qemu-qmp-ref.pdf docs/qemu-qmp-ref.txt docs/qemu-qmp-ref.7: \ -docs/qemu-qmp-ref.texi qemu-qapi.texi +docs/qemu-qmp-ref.texi docs/qemu-qmp-qapi.texi ifdef CONFIG_WIN32 diff --git a/docs/qemu-qmp-ref.texi b/docs/qemu-qmp-ref.texi index 0a0056930a..bb25758bd0 100644 --- a/docs/qemu-qmp-ref.texi +++ b/docs/qemu-qmp-ref.texi @@ -65,7 +65,7 @@ along with this manual. If not, see http://www.gnu.org/licenses/. @c for texi2pod: @c man begin DESCRIPTION -@include qemu-qapi.texi +@include qemu-qmp-qapi.texi @c man end diff --git a/rules.mak b/rules.mak index 83d6dd1dae..1c0eabb367 100644 --- a/rules.mak +++ b/rules.mak @@ -380,7 +380,7 @@ define unnest-vars endef TEXI2MAN = $(call quiet-command, \ - perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< $@.pod && \ + perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl -I docs $< $@.pod && \ $(POD2MAN) --section=$(subst .,,$(suffix $@)) --center=" " --release=" " $@.pod > $@, \ "GEN","$@") From 707fb2d381de7a03e5bf9d2bd305dc7883fd992e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:57 +0100 Subject: [PATCH 10/49] tests/qapi-schema: Cover empty union base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new test case shows off qapi.py choking on an empty union base. Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Reviewed-by: Eric Blake Message-Id: <1489582656-31133-9-git-send-email-armbru@redhat.com> --- tests/Makefile.include | 1 + tests/qapi-schema/union-base-empty.err | 10 ++++++++++ tests/qapi-schema/union-base-empty.exit | 1 + tests/qapi-schema/union-base-empty.json | 9 +++++++++ tests/qapi-schema/union-base-empty.out | 0 5 files changed, 21 insertions(+) create mode 100644 tests/qapi-schema/union-base-empty.err create mode 100644 tests/qapi-schema/union-base-empty.exit create mode 100644 tests/qapi-schema/union-base-empty.json create mode 100644 tests/qapi-schema/union-base-empty.out diff --git a/tests/Makefile.include b/tests/Makefile.include index 16e0a9f615..3e640a846c 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -476,6 +476,7 @@ qapi-schema += unclosed-list.json qapi-schema += unclosed-object.json qapi-schema += unclosed-string.json qapi-schema += unicode-str.json +qapi-schema += union-base-empty.json qapi-schema += union-base-no-discriminator.json qapi-schema += union-branch-case.json qapi-schema += union-clash-branches.json diff --git a/tests/qapi-schema/union-base-empty.err b/tests/qapi-schema/union-base-empty.err new file mode 100644 index 0000000000..26bfa07bc9 --- /dev/null +++ b/tests/qapi-schema/union-base-empty.err @@ -0,0 +1,10 @@ +Traceback (most recent call last): + File "tests/qapi-schema/test-qapi.py", line 56, in + schema = QAPISchema(sys.argv[1]) + File "scripts/qapi.py", line 1487, in __init__ + self.exprs = check_exprs(parser.exprs) + File "scripts/qapi.py", line 921, in check_exprs + check_union(expr, info) + File "scripts/qapi.py", line 738, in check_union + assert base_members +AssertionError diff --git a/tests/qapi-schema/union-base-empty.exit b/tests/qapi-schema/union-base-empty.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/union-base-empty.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/union-base-empty.json b/tests/qapi-schema/union-base-empty.json new file mode 100644 index 0000000000..d1843d33b4 --- /dev/null +++ b/tests/qapi-schema/union-base-empty.json @@ -0,0 +1,9 @@ +# Flat union with empty base and therefore without discriminator + +{ 'struct': 'Empty', 'data': { } } + +{ 'union': 'TestUnion', + 'base': 'Empty', + 'discriminator': 'type', + 'data': { 'value1': 'int', + 'value2': 'str' } } diff --git a/tests/qapi-schema/union-base-empty.out b/tests/qapi-schema/union-base-empty.out new file mode 100644 index 0000000000..e69de29bb2 From 481537451302fc63eee5cf3663a92629bb78954f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:58 +0100 Subject: [PATCH 11/49] qapi: Fix to reject empty union base gracefully MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Common Python pitfall: 'assert base_members' fires on [] in addition to None. Correct to 'assert base_members is not None'. Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Reviewed-by: Eric Blake Message-Id: <1489582656-31133-10-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 2 +- tests/qapi-schema/union-base-empty.err | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 78db319831..f4c82100f4 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -735,7 +735,7 @@ def check_union(expr, info): raise QAPISemError(info, "Flat union '%s' must have a base" % name) base_members = find_base_members(base) - assert base_members + assert base_members is not None # The value of member 'discriminator' must name a non-optional # member of the base struct. diff --git a/tests/qapi-schema/union-base-empty.err b/tests/qapi-schema/union-base-empty.err index 26bfa07bc9..7695806d81 100644 --- a/tests/qapi-schema/union-base-empty.err +++ b/tests/qapi-schema/union-base-empty.err @@ -1,10 +1 @@ -Traceback (most recent call last): - File "tests/qapi-schema/test-qapi.py", line 56, in - schema = QAPISchema(sys.argv[1]) - File "scripts/qapi.py", line 1487, in __init__ - self.exprs = check_exprs(parser.exprs) - File "scripts/qapi.py", line 921, in check_exprs - check_union(expr, info) - File "scripts/qapi.py", line 738, in check_union - assert base_members -AssertionError +tests/qapi-schema/union-base-empty.json:5: Discriminator 'type' is not a member of base struct 'Empty' From 42bebcc129a8bf235f41d65788eb54e199ba5e64 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:56:59 +0100 Subject: [PATCH 12/49] qapi2texi: Fix up output around #optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use tag #optional to mark optional members, like this: # @name: #optional The name of the guest texi_body() strips #optional, but not whitespace around it. For the above, we get in qemu-qmp-qapi.texi @item @code{'name'} (optional) The name of the guest @end table The extra space can lead to artifacts in output, e.g in qemu-qmp-ref.7.pod =item C<'name'> (optional) The name of the guest and then in qemu-qmp-ref.7 .IX Item "name (optional)" .Vb 1 \& The name of the guest .Ve instead of intended plain .IX Item "name (optional)" The name of the guest Get rid of these artifacts by removing whitespace around #optional along with it. This turns three minus signs in qapi-schema.json into markup, because they're now at the beginning of the line. Drop them, they're unwanted there. Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Message-Id: <1489582656-31133-11-git-send-email-armbru@redhat.com> --- qapi-schema.json | 6 +++--- scripts/qapi2texi.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 17c766ee3b..52141cd51e 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3779,11 +3779,11 @@ # # @dstport: #optional destination port - mandatory for udp, optional for ip # -# @ipv6: #optional - force the use of ipv6 +# @ipv6: #optional force the use of ipv6 # -# @udp: #optional - use the udp version of l2tpv3 encapsulation +# @udp: #optional use the udp version of l2tpv3 encapsulation # -# @cookie64: #optional - use 64 bit coookies +# @cookie64: #optional use 64 bit coookies # # @counter: #optional have sequence counter # diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 06d6abfa5a..0f3e5738c8 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -137,7 +137,8 @@ def texi_body(doc): desc = str(section) opt = '' if "#optional" in desc: - desc = desc.replace("#optional", "") + desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', + '', desc) opt = ' (optional)' body += "@item @code{'%s'}%s\n%s\n" % (arg, opt, texi_format(desc)) From b116fd8e302d0ff7cabf431e78ce078127b51f85 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:00 +0100 Subject: [PATCH 13/49] qapi: Avoid unwanted blank lines in QAPIDoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We silently fix missing #optional tags for QAPIDoc by appending a line "#optional" to the section's .content. However, this interferes with .__repr__ stripping trailing blank lines from .content. Use new ArgSection instance variable .optional instead, and leave .content alone. To permit testing .optional in texi_body(), clean up texi_enum()'s hack to add empty documentation for undocumented enum values: add an ArgSection instead of ''. Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Message-Id: <1489582656-31133-12-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 5 +++-- scripts/qapi2texi.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index f4c82100f4..fb10d937aa 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -107,6 +107,7 @@ def __init__(self, name=None): self.name = name # the list of lines for this section self.content = [] + self.optional = False def append(self, line): self.content.append(line) @@ -982,15 +983,15 @@ def check_definition_doc(doc, expr, info): desc = doc.args.get(arg) if not desc: continue + desc.optional = opt desc_opt = "#optional" in str(desc) if desc_opt and not opt: raise QAPISemError(info, "Description has #optional, " "but the declaration doesn't") if not desc_opt and opt: - # silently fix the doc # TODO either fix the schema and make this an error, # or drop #optional entirely - desc.append("#optional") + pass doc_args = set(doc.args.keys()) args = set([name.strip('*') for name in args]) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 0f3e5738c8..0aaf45c98c 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -136,7 +136,7 @@ def texi_body(doc): for arg, section in doc.args.iteritems(): desc = str(section) opt = '' - if "#optional" in desc: + if section.optional: desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', '', desc) opt = ' (optional)' @@ -185,7 +185,7 @@ def texi_enum(expr, doc): """Format an enum to texi""" for i in expr['data']: if i not in doc.args: - doc.args[i] = '' + doc.args[i] = qapi.QAPIDoc.ArgSection(i) body = texi_body(doc) return TYPE_FMT(type="Enum", name=doc.symbol, From 8c0aa61318a63d42099ee0e3d40e80e8108cbc21 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:01 +0100 Subject: [PATCH 14/49] qapi/rocker: Fix up doc comment notes on optional members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Talking about #optional like this # Note: fields are marked #optional to indicate that they may or may # not appear ... doesn't work so well in generated documentation, because the #optional tag is not visible there. Replace by # Note: optional members may or may not appear ... Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Message-Id: <1489582656-31133-13-git-send-email-armbru@redhat.com> --- qapi/rocker.json | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/qapi/rocker.json b/qapi/rocker.json index 97e2b8376f..f374038c60 100644 --- a/qapi/rocker.json +++ b/qapi/rocker.json @@ -1,3 +1,5 @@ +# -*- Mode: Python -*- + ## # = Rocker switch device ## @@ -137,8 +139,8 @@ # # @ip-dst: #optional IP header destination address # -# Note: fields are marked #optional to indicate that they may or may not -# appear in the flow key depending if they're relevant to the flow key. +# Note: optional members may or may not appear in the flow key +# depending if they're relevant to the flow key. # # Since: 2.4 ## @@ -167,8 +169,8 @@ # # @ip-tos: #optional IP header TOS field # -# Note: fields are marked #optional to indicate that they may or may not -# appear in the flow mask depending if they're relevant to the flow mask. +# Note: optional members may or may not appear in the flow mask +# depending if they're relevant to the flow mask. # # Since: 2.4 ## @@ -194,8 +196,8 @@ # # @out-pport: #optional physical output port # -# Note: fields are marked #optional to indicate that they may or may not -# appear in the flow action depending if they're relevant to the flow action. +# Note: optional members may or may not appear in the flow action +# depending if they're relevant to the flow action. # # Since: 2.4 ## @@ -288,8 +290,8 @@ # # @ttl-check: #optional perform TTL check # -# Note: fields are marked #optional to indicate that they may or may not -# appear in the group depending if they're relevant to the group type. +# Note: optional members may or may not appear in the group depending +# if they're relevant to the group type. # # Since: 2.4 ## From 4636211e4dddfc798d9e9072546a87f9adf7ce5a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:02 +0100 Subject: [PATCH 15/49] qapi: Fix QAPISchemaEnumType.is_implicit() for 'QType' Missed in commit 7264f5c. Harmless, because nothing checks whether an enumeration type is implicit so far. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-14-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index fb10d937aa..dd083b703c 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1152,8 +1152,8 @@ def check(self, schema): v.check_clash(self.info, seen) def is_implicit(self): - # See QAPISchema._make_implicit_enum_type() - return self.name.endswith('Kind') + # See QAPISchema._make_implicit_enum_type() and ._def_predefineds() + return self.name.endswith('Kind') or self.name == 'QType' def c_type(self): return c_name(self.name) From 069fb5b250c8f90caeb84dcc003e2147ccc4a782 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:03 +0100 Subject: [PATCH 16/49] qapi: Prepare for requiring more complete documentation We currently neglect to check all enumeration values, common members of object types and members of alternate types are documented. Unsurprisingly, many aren't. Add the necessary plumbing to find undocumented ones, except for variant members of object types. Don't enforce anything just yet, but connect each QAPIDoc.ArgSection to its QAPISchemaMember. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-15-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 110 ++++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index dd083b703c..c1e0bed087 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -116,7 +116,12 @@ def __repr__(self): return "\n".join(self.content).strip() class ArgSection(Section): - pass + def __init__(self, name): + QAPIDoc.Section.__init__(self, name) + self.member = None + + def connect(self, member): + self.member = member def __init__(self, parser, info): # self.parser is used to report errors with QAPIParseError. The @@ -216,6 +221,13 @@ def _append_freeform(self, line): line = line.strip() self.section.append(line) + def connect_member(self, member): + if member.name not in self.args: + # Undocumented TODO outlaw + pass + else: + self.args[member.name].connect(member) + class QAPISchemaParser(object): @@ -1021,7 +1033,7 @@ def check_docs(docs): # class QAPISchemaEntity(object): - def __init__(self, name, info): + def __init__(self, name, info, doc): assert isinstance(name, str) self.name = name # For explicitly defined entities, info points to the (explicit) @@ -1030,6 +1042,7 @@ def __init__(self, name, info): # triggered the implicit definition (there may be more than one # such place). self.info = info + self.doc = doc def c_name(self): return c_name(self.name) @@ -1111,7 +1124,7 @@ def alternate_qtype(self): class QAPISchemaBuiltinType(QAPISchemaType): def __init__(self, name, json_type, c_type): - QAPISchemaType.__init__(self, name, None) + QAPISchemaType.__init__(self, name, None, None) assert not c_type or isinstance(c_type, str) assert json_type in ('string', 'number', 'int', 'boolean', 'null', 'value') @@ -1137,8 +1150,8 @@ def visit(self, visitor): class QAPISchemaEnumType(QAPISchemaType): - def __init__(self, name, info, values, prefix): - QAPISchemaType.__init__(self, name, info) + def __init__(self, name, info, doc, values, prefix): + QAPISchemaType.__init__(self, name, info, doc) for v in values: assert isinstance(v, QAPISchemaMember) v.set_owner(name) @@ -1150,6 +1163,8 @@ def check(self, schema): seen = {} for v in self.values: v.check_clash(self.info, seen) + if self.doc: + self.doc.connect_member(v) def is_implicit(self): # See QAPISchema._make_implicit_enum_type() and ._def_predefineds() @@ -1171,7 +1186,7 @@ def visit(self, visitor): class QAPISchemaArrayType(QAPISchemaType): def __init__(self, name, info, element_type): - QAPISchemaType.__init__(self, name, info) + QAPISchemaType.__init__(self, name, info, None) assert isinstance(element_type, str) self._element_type_name = element_type self.element_type = None @@ -1194,11 +1209,11 @@ def visit(self, visitor): class QAPISchemaObjectType(QAPISchemaType): - def __init__(self, name, info, base, local_members, variants): + def __init__(self, name, info, doc, base, local_members, variants): # struct has local_members, optional base, and no variants # flat union has base, variants, and no local_members # simple union has local_members, variants, and no base - QAPISchemaType.__init__(self, name, info) + QAPISchemaType.__init__(self, name, info, doc) assert base is None or isinstance(base, str) for m in local_members: assert isinstance(m, QAPISchemaObjectTypeMember) @@ -1228,6 +1243,8 @@ def check(self, schema): for m in self.local_members: m.check(schema) m.check_clash(self.info, seen) + if self.doc: + self.doc.connect_member(m) self.members = seen.values() if self.variants: self.variants.check(schema, seen) @@ -1382,8 +1399,8 @@ def __init__(self, name, typ): class QAPISchemaAlternateType(QAPISchemaType): - def __init__(self, name, info, variants): - QAPISchemaType.__init__(self, name, info) + def __init__(self, name, info, doc, variants): + QAPISchemaType.__init__(self, name, info, doc) assert isinstance(variants, QAPISchemaObjectTypeVariants) assert variants.tag_member variants.set_owner(name) @@ -1400,6 +1417,8 @@ def check(self, schema): seen = {} for v in self.variants.variants: v.check_clash(self.info, seen) + if self.doc: + self.doc.connect_member(v) def c_type(self): return c_name(self.name) + pointer_suffix @@ -1415,9 +1434,9 @@ def is_empty(self): class QAPISchemaCommand(QAPISchemaEntity): - def __init__(self, name, info, arg_type, ret_type, gen, success_response, - boxed): - QAPISchemaEntity.__init__(self, name, info) + def __init__(self, name, info, doc, arg_type, ret_type, + gen, success_response, boxed): + QAPISchemaEntity.__init__(self, name, info, doc) assert not arg_type or isinstance(arg_type, str) assert not ret_type or isinstance(ret_type, str) self._arg_type_name = arg_type @@ -1454,8 +1473,8 @@ def visit(self, visitor): class QAPISchemaEvent(QAPISchemaEntity): - def __init__(self, name, info, arg_type, boxed): - QAPISchemaEntity.__init__(self, name, info) + def __init__(self, name, info, doc, arg_type, boxed): + QAPISchemaEntity.__init__(self, name, info, doc) assert not arg_type or isinstance(arg_type, str) self._arg_type_name = arg_type self.arg_type = None @@ -1537,14 +1556,14 @@ def _def_predefineds(self): ('bool', 'boolean', 'bool'), ('any', 'value', 'QObject' + pointer_suffix)]: self._def_builtin_type(*t) - self.the_empty_object_type = QAPISchemaObjectType('q_empty', None, - None, [], None) + self.the_empty_object_type = QAPISchemaObjectType( + 'q_empty', None, None, None, [], None) self._def_entity(self.the_empty_object_type) qtype_values = self._make_enum_members(['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']) - self._def_entity(QAPISchemaEnumType('QType', None, qtype_values, - 'QTYPE')) + self._def_entity(QAPISchemaEnumType('QType', None, None, + qtype_values, 'QTYPE')) def _make_enum_members(self, values): return [QAPISchemaMember(v) for v in values] @@ -1553,7 +1572,7 @@ def _make_implicit_enum_type(self, name, info, values): # See also QAPISchemaObjectTypeMember._pretty_owner() name = name + 'Kind' # Use namespace reserved by add_name() self._def_entity(QAPISchemaEnumType( - name, info, self._make_enum_members(values), None)) + name, info, None, self._make_enum_members(values), None)) return name def _make_array_type(self, element_type, info): @@ -1562,22 +1581,22 @@ def _make_array_type(self, element_type, info): self._def_entity(QAPISchemaArrayType(name, info, element_type)) return name - def _make_implicit_object_type(self, name, info, role, members): + def _make_implicit_object_type(self, name, info, doc, role, members): if not members: return None # See also QAPISchemaObjectTypeMember._pretty_owner() name = 'q_obj_%s-%s' % (name, role) if not self.lookup_entity(name, QAPISchemaObjectType): - self._def_entity(QAPISchemaObjectType(name, info, None, + self._def_entity(QAPISchemaObjectType(name, info, doc, None, members, None)) return name - def _def_enum_type(self, expr, info): + def _def_enum_type(self, expr, info, doc): name = expr['enum'] data = expr['data'] prefix = expr.get('prefix') self._def_entity(QAPISchemaEnumType( - name, info, self._make_enum_members(data), prefix)) + name, info, doc, self._make_enum_members(data), prefix)) def _make_member(self, name, typ, info): optional = False @@ -1593,11 +1612,11 @@ def _make_members(self, data, info): return [self._make_member(key, value, info) for (key, value) in data.iteritems()] - def _def_struct_type(self, expr, info): + def _def_struct_type(self, expr, info, doc): name = expr['struct'] base = expr.get('base') data = expr['data'] - self._def_entity(QAPISchemaObjectType(name, info, base, + self._def_entity(QAPISchemaObjectType(name, info, doc, base, self._make_members(data, info), None)) @@ -1609,10 +1628,10 @@ def _make_simple_variant(self, case, typ, info): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) typ = self._make_implicit_object_type( - typ, info, 'wrapper', [self._make_member('data', typ, info)]) + typ, info, None, 'wrapper', [self._make_member('data', typ, info)]) return QAPISchemaObjectTypeVariant(case, typ) - def _def_union_type(self, expr, info): + def _def_union_type(self, expr, info, doc): name = expr['union'] data = expr['data'] base = expr.get('base') @@ -1620,7 +1639,7 @@ def _def_union_type(self, expr, info): tag_member = None if isinstance(base, dict): base = (self._make_implicit_object_type( - name, info, 'base', self._make_members(base, info))) + name, info, doc, 'base', self._make_members(base, info))) if tag_name: variants = [self._make_variant(key, value) for (key, value) in data.iteritems()] @@ -1633,24 +1652,24 @@ def _def_union_type(self, expr, info): tag_member = QAPISchemaObjectTypeMember('type', typ, False) members = [tag_member] self._def_entity( - QAPISchemaObjectType(name, info, base, members, + QAPISchemaObjectType(name, info, doc, base, members, QAPISchemaObjectTypeVariants(tag_name, tag_member, variants))) - def _def_alternate_type(self, expr, info): + def _def_alternate_type(self, expr, info, doc): name = expr['alternate'] data = expr['data'] variants = [self._make_variant(key, value) for (key, value) in data.iteritems()] tag_member = QAPISchemaObjectTypeMember('type', 'QType', False) self._def_entity( - QAPISchemaAlternateType(name, info, + QAPISchemaAlternateType(name, info, doc, QAPISchemaObjectTypeVariants(None, tag_member, variants))) - def _def_command(self, expr, info): + def _def_command(self, expr, info, doc): name = expr['command'] data = expr.get('data') rets = expr.get('returns') @@ -1659,38 +1678,39 @@ def _def_command(self, expr, info): boxed = expr.get('boxed', False) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( - name, info, 'arg', self._make_members(data, info)) + name, info, doc, 'arg', self._make_members(data, info)) if isinstance(rets, list): assert len(rets) == 1 rets = self._make_array_type(rets[0], info) - self._def_entity(QAPISchemaCommand(name, info, data, rets, gen, - success_response, boxed)) + self._def_entity(QAPISchemaCommand(name, info, doc, data, rets, + gen, success_response, boxed)) - def _def_event(self, expr, info): + def _def_event(self, expr, info, doc): name = expr['event'] data = expr.get('data') boxed = expr.get('boxed', False) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( - name, info, 'arg', self._make_members(data, info)) - self._def_entity(QAPISchemaEvent(name, info, data, boxed)) + name, info, doc, 'arg', self._make_members(data, info)) + self._def_entity(QAPISchemaEvent(name, info, doc, data, boxed)) def _def_exprs(self): for expr_elem in self.exprs: expr = expr_elem['expr'] info = expr_elem['info'] + doc = expr_elem.get('doc') if 'enum' in expr: - self._def_enum_type(expr, info) + self._def_enum_type(expr, info, doc) elif 'struct' in expr: - self._def_struct_type(expr, info) + self._def_struct_type(expr, info, doc) elif 'union' in expr: - self._def_union_type(expr, info) + self._def_union_type(expr, info, doc) elif 'alternate' in expr: - self._def_alternate_type(expr, info) + self._def_alternate_type(expr, info, doc) elif 'command' in expr: - self._def_command(expr, info) + self._def_command(expr, info, doc) elif 'event' in expr: - self._def_event(expr, info) + self._def_event(expr, info, doc) else: assert False From 860e87786123368a97c879b6e7459b3f519bbc97 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:04 +0100 Subject: [PATCH 17/49] qapi: Conjure up QAPIDoc.ArgSection for undocumented members qapi2texi.py already conjures up ArgSections for undocumented enumeration values, in texi_enum. Drop that, and conjure them up for all kinds of "arguments" (enumeration values, object and alternate type members) in qapi.py instead. Take care to keep generated documentation exactly the same for now. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-16-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 5 ++--- scripts/qapi2texi.py | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index c1e0bed087..f4c8eac8f6 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -224,9 +224,8 @@ def _append_freeform(self, line): def connect_member(self, member): if member.name not in self.args: # Undocumented TODO outlaw - pass - else: - self.args[member.name].connect(member) + self.args[member.name] = QAPIDoc.ArgSection(member.name) + self.args[member.name].connect(member) class QAPISchemaParser(object): diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 0aaf45c98c..299dcf92d8 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -123,7 +123,7 @@ def texi_format(doc): return "\n".join(lines) -def texi_body(doc): +def texi_body(doc, only_documented=False): """ Format the body of a symbol documentation: - main body @@ -131,17 +131,21 @@ def texi_body(doc): - followed by "Returns/Notes/Since/Example" sections """ body = texi_format(str(doc.body)) + "\n" - if doc.args: + + args = '' + for name, section in doc.args.iteritems(): + if not section.content and not only_documented: + continue # Undocumented TODO require doc and drop + desc = str(section) + opt = '' + if section.optional: + desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', + '', desc) + opt = ' (optional)' + args += "@item @code{'%s'}%s\n%s\n" % (name, opt, texi_format(desc)) + if args: body += "@table @asis\n" - for arg, section in doc.args.iteritems(): - desc = str(section) - opt = '' - if section.optional: - desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', - '', desc) - opt = ' (optional)' - body += "@item @code{'%s'}%s\n%s\n" % (arg, opt, - texi_format(desc)) + body += args body += "@end table\n" for section in doc.sections: @@ -183,10 +187,7 @@ def texi_union(expr, doc): def texi_enum(expr, doc): """Format an enum to texi""" - for i in expr['data']: - if i not in doc.args: - doc.args[i] = qapi.QAPIDoc.ArgSection(i) - body = texi_body(doc) + body = texi_body(doc, True) return TYPE_FMT(type="Enum", name=doc.symbol, body=body) From aa964b7fdc2b9c6fd0dd530c44563b2a9d891d0f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:05 +0100 Subject: [PATCH 18/49] qapi2texi: Convert to QAPISchemaVisitor qapi2texi works with schema expression trees. Such a tight coupling to schema language syntax is not a good idea. Convert it to the visitor interface the other generators use. No change to generated documentation. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-17-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 216 ++++++++++++++++++++++--------------------- 1 file changed, 112 insertions(+), 104 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 299dcf92d8..6d4e75713d 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -123,31 +123,39 @@ def texi_format(doc): return "\n".join(lines) -def texi_body(doc, only_documented=False): - """ - Format the body of a symbol documentation: - - main body - - table of arguments - - followed by "Returns/Notes/Since/Example" sections - """ - body = texi_format(str(doc.body)) + "\n" +def texi_body(doc): + """Format the main documentation body""" + return texi_format(str(doc.body)) + '\n' - args = '' - for name, section in doc.args.iteritems(): - if not section.content and not only_documented: - continue # Undocumented TODO require doc and drop - desc = str(section) - opt = '' - if section.optional: - desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', - '', desc) - opt = ' (optional)' - args += "@item @code{'%s'}%s\n%s\n" % (name, opt, texi_format(desc)) - if args: - body += "@table @asis\n" - body += args - body += "@end table\n" +def texi_enum_value(value): + """Format a table of members item for an enumeration value""" + return "@item @code{'%s'}\n" % value.name + + +def texi_member(member): + """Format a table of members item for an object type member""" + return "@item @code{'%s'}%s\n" % ( + member.name, ' (optional)' if member.optional else '') + + +def texi_members(doc, member_func, show_undocumented): + """Format the table of members""" + items = '' + for section in doc.args.itervalues(): + if not section.content and not show_undocumented: + continue # Undocumented TODO require doc and drop + desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', + '', str(section)) + items += member_func(section.member) + texi_format(desc) + '\n' + if not items: + return '' + return '@table @asis\n' + items + '@end table\n' + + +def texi_sections(doc): + """Format additional sections following arguments""" + body = '' for section in doc.sections: name, doc = (section.name, str(section)) func = texi_format @@ -159,94 +167,94 @@ def texi_body(doc, only_documented=False): body += "\n\n@b{%s:}\n" % name body += func(doc) - return body -def texi_alternate(expr, doc): - """Format an alternate to texi""" - body = texi_body(doc) - return TYPE_FMT(type="Alternate", - name=doc.symbol, - body=body) +def texi_entity(doc, member_func=texi_member, show_undocumented=False): + return (texi_body(doc) + + texi_members(doc, member_func, show_undocumented) + + texi_sections(doc)) -def texi_union(expr, doc): - """Format a union to texi""" - discriminator = expr.get("discriminator") - if discriminator: - union = "Flat Union" - else: - union = "Simple Union" +class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor): + def __init__(self): + self.out = None + self.cur_doc = None - body = texi_body(doc) - return TYPE_FMT(type=union, - name=doc.symbol, - body=body) + def visit_begin(self, schema): + self.out = '' + + def visit_enum_type(self, name, info, values, prefix): + doc = self.cur_doc + if self.out: + self.out += '\n' + self.out += TYPE_FMT(type='Enum', + name=doc.symbol, + body=texi_entity(doc, + member_func=texi_enum_value, + show_undocumented=True)) + + def visit_object_type(self, name, info, base, members, variants): + doc = self.cur_doc + if not variants: + typ = 'Struct' + elif variants._tag_name: # TODO unclean member access + typ = 'Flat Union' + else: + typ = 'Simple Union' + if self.out: + self.out += '\n' + self.out += TYPE_FMT(type=typ, + name=doc.symbol, + body=texi_entity(doc)) + + def visit_alternate_type(self, name, info, variants): + doc = self.cur_doc + if self.out: + self.out += '\n' + self.out += TYPE_FMT(type='Alternate', + name=doc.symbol, + body=texi_entity(doc)) + + def visit_command(self, name, info, arg_type, ret_type, + gen, success_response, boxed): + doc = self.cur_doc + if self.out: + self.out += '\n' + self.out += MSG_FMT(type='Command', + name=doc.symbol, + body=texi_entity(doc)) + + def visit_event(self, name, info, arg_type, boxed): + doc = self.cur_doc + if self.out: + self.out += '\n' + self.out += MSG_FMT(type='Event', + name=doc.symbol, + body=texi_entity(doc)) + + def symbol(self, doc, entity): + self.cur_doc = doc + entity.visit(self) + self.cur_doc = None + + def freeform(self, doc): + assert not doc.args + if self.out: + self.out += '\n' + self.out += texi_body(doc) + texi_sections(doc) -def texi_enum(expr, doc): - """Format an enum to texi""" - body = texi_body(doc, True) - return TYPE_FMT(type="Enum", - name=doc.symbol, - body=body) - - -def texi_struct(expr, doc): - """Format a struct to texi""" - body = texi_body(doc) - return TYPE_FMT(type="Struct", - name=doc.symbol, - body=body) - - -def texi_command(expr, doc): - """Format a command to texi""" - body = texi_body(doc) - return MSG_FMT(type="Command", - name=doc.symbol, - body=body) - - -def texi_event(expr, doc): - """Format an event to texi""" - body = texi_body(doc) - return MSG_FMT(type="Event", - name=doc.symbol, - body=body) - - -def texi_expr(expr, doc): - """Format an expr to texi""" - (kind, _) = expr.items()[0] - - fmt = {"command": texi_command, - "struct": texi_struct, - "enum": texi_enum, - "union": texi_union, - "alternate": texi_alternate, - "event": texi_event}[kind] - - return fmt(expr, doc) - - -def texi(docs): - """Convert QAPI schema expressions to texi documentation""" - res = [] - for doc in docs: - expr = doc.expr - if not expr: - res.append(texi_body(doc)) - continue - try: - doc = texi_expr(expr, doc) - res.append(doc) - except: - print >>sys.stderr, "error at @%s" % doc.info - raise - - return '\n'.join(res) +def texi_schema(schema): + """Convert QAPI schema documentation to Texinfo""" + gen = QAPISchemaGenDocVisitor() + gen.visit_begin(schema) + for doc in schema.docs: + if doc.symbol: + gen.symbol(doc, schema.lookup_entity(doc.symbol)) + else: + gen.freeform(doc) + return gen.out def main(argv): @@ -259,7 +267,7 @@ def main(argv): if not qapi.doc_required: print >>sys.stderr, ("%s: need pragma 'doc-required' " "to generate documentation" % argv[0]) - print texi(schema.docs) + print texi_schema(schema) if __name__ == "__main__": From 1d8bda128d2ff1f7e589c90d0ac468b95d260757 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:06 +0100 Subject: [PATCH 19/49] qapi: The #optional tag is redundant, drop We traditionally mark optional members #optional in the doc comment. Before commit 3313b61, this was entirely manual. Commit 3313b61 added some automation because its qapi2texi.py relied on #optional to determine whether a member is optional. This is no longer the case since the previous commit: the only thing qapi2texi.py still does with #optional is stripping it out. We still reject bogus qapi-schema.json and six places for qga/qapi-schema.json. Thus, you can't actually rely on #optional to see whether something is optional. Yet we still make people add it manually. That's just busy-work. Drop the code to check, fix up and strip out #optional, along with all instances of #optional. To keep it out, add code to reject it, to be dropped again once the dust settles. No change to generated documentation. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-18-git-send-email-armbru@redhat.com> --- docs/qapi-code-gen.txt | 12 +- docs/writing-qmp-commands.txt | 4 +- qapi-schema.json | 378 +++++++++++++------------ qapi/block-core.json | 412 ++++++++++++++-------------- qapi/block.json | 8 +- qapi/crypto.json | 22 +- qapi/event.json | 10 +- qapi/introspect.json | 6 +- qapi/rocker.json | 70 ++--- qapi/trace.json | 6 +- qga/qapi-schema.json | 38 +-- scripts/qapi.py | 23 +- scripts/qapi2texi.py | 3 +- tests/Makefile.include | 1 - tests/qapi-schema/doc-optional.err | 1 - tests/qapi-schema/doc-optional.exit | 1 - tests/qapi-schema/doc-optional.json | 7 - tests/qapi-schema/doc-optional.out | 0 18 files changed, 486 insertions(+), 516 deletions(-) delete mode 100644 tests/qapi-schema/doc-optional.err delete mode 100644 tests/qapi-schema/doc-optional.exit delete mode 100644 tests/qapi-schema/doc-optional.json delete mode 100644 tests/qapi-schema/doc-optional.out diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 2f67900b4c..52e3874efe 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -131,10 +131,8 @@ and optional tagged sections. FIXME: the parser accepts these things in almost any order. -Optional arguments / members are tagged with the phrase '#optional', -often with their default value; and extensions added after the -expression was first released are also given a '(since x.y.z)' -comment. +Extensions added after the expression was first released carry a +'(since x.y.z)' comment. A tagged section starts with one of the following words: "Note:"/"Notes:", "Since:", "Example"/"Examples", "Returns:", "TODO:". @@ -150,10 +148,10 @@ For example: # # Statistics of a virtual block device or a block backing device. # -# @device: #optional If the stats are for a virtual block device, the name +# @device: If the stats are for a virtual block device, the name # corresponding to the virtual block device. # -# @node-name: #optional The node name of the device. (since 2.3) +# @node-name: The node name of the device. (since 2.3) # # ... more members ... # @@ -168,7 +166,7 @@ For example: # # Query the @BlockStats for all virtual block devices. # -# @query-nodes: #optional If true, the command will query all the +# @query-nodes: If true, the command will query all the # block nodes ... explain, explain ... (since 2.3) # # Returns: A list of @BlockStats for each virtual block devices. diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt index 44c14db418..1e6375495b 100644 --- a/docs/writing-qmp-commands.txt +++ b/docs/writing-qmp-commands.txt @@ -252,7 +252,7 @@ here goes "hello-world"'s new entry for the qapi-schema.json file: # # Print a client provided string to the standard output stream. # -# @message: #optional string to be printed +# @message: string to be printed # # Returns: Nothing on success. # @@ -358,7 +358,7 @@ The best way to return that data is to create a new QAPI type, as shown below: # # @clock-name: The alarm clock method's name. # -# @next-deadline: #optional The time (in nanoseconds) the next alarm will fire. +# @next-deadline: The time (in nanoseconds) the next alarm will fire. # # Since: 1.0 ## diff --git a/qapi-schema.json b/qapi-schema.json index 52141cd51e..d693033556 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -150,10 +150,10 @@ # # @fdname: file descriptor name previously passed via 'getfd' command # -# @skipauth: #optional whether to skip authentication. Only applies +# @skipauth: whether to skip authentication. Only applies # to "vnc" and "spice" protocols # -# @tls: #optional whether to perform TLS. Only applies to the "spice" +# @tls: whether to perform TLS. Only applies to the "spice" # protocol # # Returns: nothing on success. @@ -176,7 +176,7 @@ # # Guest name information. # -# @name: #optional The name of the guest +# @name: The name of the guest # # Since: 0.14.0 ## @@ -470,7 +470,7 @@ # # @data: data to write # -# @format: #optional data encoding (default 'utf8'). +# @format: data encoding (default 'utf8'). # - base64: data must be base64 encoded text. Its binary # decoding gets written. # - utf8: data's UTF-8 encoding is written @@ -503,7 +503,7 @@ # # @size: how many bytes to read at most # -# @format: #optional data encoding (default 'utf8'). +# @format: data encoding (default 'utf8'). # - base64: the data read is returned in base64 encoding. # - utf8: the data read is interpreted as UTF-8. # Bug: can screw up when the buffer contains invalid UTF-8 @@ -667,45 +667,45 @@ # # Information about current migration process. # -# @status: #optional @MigrationStatus describing the current migration status. +# @status: @MigrationStatus describing the current migration status. # If this field is not returned, no migration process # has been initiated # -# @ram: #optional @MigrationStats containing detailed migration +# @ram: @MigrationStats containing detailed migration # status, only returned if status is 'active' or # 'completed'(since 1.2) # -# @disk: #optional @MigrationStats containing detailed disk migration +# @disk: @MigrationStats containing detailed disk migration # status, only returned if status is 'active' and it is a block # migration # -# @xbzrle-cache: #optional @XBZRLECacheStats containing detailed XBZRLE +# @xbzrle-cache: @XBZRLECacheStats containing detailed XBZRLE # migration statistics, only returned if XBZRLE feature is on and # status is 'active' or 'completed' (since 1.2) # -# @total-time: #optional total amount of milliseconds since migration started. +# @total-time: total amount of milliseconds since migration started. # If migration has ended, it returns the total migration # time. (since 1.2) # -# @downtime: #optional only present when migration finishes correctly +# @downtime: only present when migration finishes correctly # total downtime in milliseconds for the guest. # (since 1.3) # -# @expected-downtime: #optional only present while migration is active +# @expected-downtime: only present while migration is active # expected downtime in milliseconds for the guest in last walk # of the dirty bitmap. (since 1.3) # -# @setup-time: #optional amount of setup time in milliseconds _before_ the +# @setup-time: amount of setup time in milliseconds _before_ the # iterations begin but _after_ the QMP command is issued. This is designed # to provide an accounting of any activities (such as RDMA pinning) which # may be expensive, but do not actually occur during the iterative # migration rounds themselves. (since 1.6) # -# @cpu-throttle-percentage: #optional percentage of time guest cpus are being +# @cpu-throttle-percentage: percentage of time guest cpus are being # throttled during auto-converge. This is only present when auto-converge # has started throttling guest cpus. (Since 2.7) # -# @error-desc: #optional the human readable error description string, when +# @error-desc: the human readable error description string, when # @status is 'failed'. Clients should not attempt to parse the # error strings. (Since 2.7) # @@ -1038,21 +1038,21 @@ # ('query-migrate-parameters'), with the exception of tls-creds and # tls-hostname. # -# @compress-level: #optional compression level +# @compress-level: compression level # -# @compress-threads: #optional compression thread count +# @compress-threads: compression thread count # -# @decompress-threads: #optional decompression thread count +# @decompress-threads: decompression thread count # -# @cpu-throttle-initial: #optional Initial percentage of time guest cpus are +# @cpu-throttle-initial: Initial percentage of time guest cpus are # throttledwhen migration auto-converge is activated. # The default value is 20. (Since 2.7) # -# @cpu-throttle-increment: #optional throttle percentage increase each time +# @cpu-throttle-increment: throttle percentage increase each time # auto-converge detects that migration is not making # progress. The default value is 10. (Since 2.7) # -# @tls-creds: #optional ID of the 'tls-creds' object that provides credentials +# @tls-creds: ID of the 'tls-creds' object that provides credentials # for establishing a TLS connection over the migration data # channel. On the outgoing side of the migration, the credentials # must be for a 'client' endpoint, while for the incoming side the @@ -1060,7 +1060,7 @@ # will enable TLS for all migrations. The default is unset, # resulting in unsecured migration at the QEMU level. (Since 2.7) # -# @tls-hostname: #optional hostname of the target host for the migration. This +# @tls-hostname: hostname of the target host for the migration. This # is required when using x509 based TLS credentials and the # migration URI does not already include a hostname. For # example if using fd: or exec: based migration, the @@ -1125,9 +1125,9 @@ # # @protocol: must be "spice" # @hostname: migration target hostname -# @port: #optional spice tcp port for plaintext channels -# @tls-port: #optional spice tcp port for tls-secured channels -# @cert-subject: #optional server certificate subject +# @port: spice tcp port for plaintext channels +# @tls-port: spice tcp port for tls-secured channels +# @cert-subject: server certificate subject # # Since: 0.14.0 # @@ -1547,7 +1547,7 @@ # # The network connection information for server # -# @auth: #optional authentication method used for +# @auth: authentication method used for # the plain (non-websocket) VNC server # # Since: 2.1 @@ -1561,10 +1561,10 @@ # # Information about a connected VNC client. # -# @x509_dname: #optional If x509 authentication is in use, the Distinguished +# @x509_dname: If x509 authentication is in use, the Distinguished # Name of the client. # -# @sasl_username: #optional If SASL authentication is in use, the SASL username +# @sasl_username: If SASL authentication is in use, the SASL username # used for authentication. # # Since: 0.14.0 @@ -1580,19 +1580,19 @@ # # @enabled: true if the VNC server is enabled, false otherwise # -# @host: #optional The hostname the VNC server is bound to. This depends on +# @host: The hostname the VNC server is bound to. This depends on # the name resolution on the host and may be an IP address. # -# @family: #optional 'ipv6' if the host is listening for IPv6 connections +# @family: 'ipv6' if the host is listening for IPv6 connections # 'ipv4' if the host is listening for IPv4 connections # 'unix' if the host is listening on a unix domain socket # 'unknown' otherwise # -# @service: #optional The service name of the server's port. This may depends +# @service: The service name of the server's port. This may depends # on the host system's service database so symbolic names should not # be relied on. # -# @auth: #optional the current authentication type used by the server +# @auth: the current authentication type used by the server # 'none' if no authentication is being used # 'vnc' if VNC authentication is being used # 'vencrypt+plain' if VEncrypt is used with plain text authentication @@ -1647,7 +1647,7 @@ # # @auth: The current authentication type used by the servers # -# @vencrypt: #optional The vencrypt sub authentication type used by the +# @vencrypt: The vencrypt sub authentication type used by the # servers, only specified in case auth == vencrypt. # # Since: 2.9 @@ -1675,10 +1675,10 @@ # # @auth: The current authentication type used by the non-websockets servers # -# @vencrypt: #optional The vencrypt authentication type used by the servers, +# @vencrypt: The vencrypt authentication type used by the servers, # only specified in case auth == vencrypt. # -# @display: #optional The display device the vnc server is linked to. +# @display: The display device the vnc server is linked to. # # Since: 2.3 ## @@ -1755,7 +1755,7 @@ # # Information about a SPICE server # -# @auth: #optional authentication method +# @auth: authentication method # # Since: 2.1 ## @@ -1817,16 +1817,16 @@ # @migrated: true if the last guest migration completed and spice # migration had completed as well. false otherwise. (since 1.4) # -# @host: #optional The hostname the SPICE server is bound to. This depends on +# @host: The hostname the SPICE server is bound to. This depends on # the name resolution on the host and may be an IP address. # -# @port: #optional The SPICE server's port number. +# @port: The SPICE server's port number. # -# @compiled-version: #optional SPICE server version. +# @compiled-version: SPICE server version. # -# @tls-port: #optional The SPICE server's TLS port number. +# @tls-port: The SPICE server's TLS port number. # -# @auth: #optional the current authentication type used by the server +# @auth: the current authentication type used by the server # 'none' if no authentication is being used # 'spice' uses SASL or direct TLS authentication, depending on command # line options @@ -1951,9 +1951,9 @@ # # @size: memory size # -# @prefetch: #optional if @type is 'memory', true if the memory is prefetchable +# @prefetch: if @type is 'memory', true if the memory is prefetchable # -# @mem_type_64: #optional if @type is 'memory', true if the BAR is 64-bit +# @mem_type_64: if @type is 'memory', true if the BAR is 64-bit # # Since: 0.14.0 ## @@ -2009,7 +2009,7 @@ # # Information about the Class of a PCI device # -# @desc: #optional a string description of the device's class +# @desc: a string description of the device's class # # @class: the class code of the device # @@ -2047,7 +2047,7 @@ # # @id: the PCI device id # -# @irq: #optional if an IRQ is assigned to the device, the IRQ number +# @irq: if an IRQ is assigned to the device, the IRQ number # # @qdev_id: the device name of the PCI device # @@ -2337,7 +2337,7 @@ # # @filename: the file to save the memory to as binary data # -# @cpu-index: #optional the index of the virtual CPU to use for translating the +# @cpu-index: the index of the virtual CPU to use for translating the # virtual address (defaults to CPU 0) # # Returns: Nothing on success @@ -2566,7 +2566,7 @@ # # Optional arguments to modify the behavior of a Transaction. # -# @completion-mode: #optional Controls how jobs launched asynchronously by +# @completion-mode: Controls how jobs launched asynchronously by # Actions will complete or fail as a group. # See @ActionCompletionMode for details. # @@ -2610,7 +2610,7 @@ # @actions: List of @TransactionAction; # information needed for the respective operations. # -# @properties: #optional structure of additional options to control the +# @properties: structure of additional options to control the # execution of the transaction. See @TransactionProperties # for additional detail. # @@ -2659,7 +2659,7 @@ # # @command-line: the command to execute in the human monitor # -# @cpu-index: #optional The CPU to use for commands that require an implicit CPU +# @cpu-index: The CPU to use for commands that require an implicit CPU # # Returns: the output of the command as a string # @@ -2895,7 +2895,7 @@ # # @password: the new password # -# @connected: #optional how to handle existing clients when changing the +# @connected: how to handle existing clients when changing the # password. If nothing is specified, defaults to `keep' # `fail' to fail the command if clients are connected # `disconnect' to disconnect existing clients @@ -3054,7 +3054,7 @@ # # @name: the name of the property # @type: the typename of the property -# @description: #optional if specified, the description of the property. +# @description: if specified, the description of the property. # (since 2.2) # # Since: 1.2 @@ -3084,9 +3084,9 @@ # # @uri: the Uniform Resource Identifier of the destination VM # -# @blk: #optional do block migration (full disk copy) +# @blk: do block migration (full disk copy) # -# @inc: #optional incremental disk copy migration +# @inc: incremental disk copy migration # # @detach: this argument exists only for compatibility reasons and # is ignored by QEMU @@ -3195,9 +3195,9 @@ # # @driver: the name of the new device's driver # -# @bus: #optional the device's parent bus (device tree path) +# @bus: the device's parent bus (device tree path) # -# @id: #optional the device's ID, must be unique +# @id: the device's ID, must be unique # # Additional arguments depend on the type. # @@ -3310,17 +3310,17 @@ # 2. fd: the protocol starts with "fd:", and the following string # is the fd's name. # -# @detach: #optional if true, QMP will return immediately rather than +# @detach: if true, QMP will return immediately rather than # waiting for the dump to finish. The user can track progress # using "query-dump". (since 2.6). # -# @begin: #optional if specified, the starting physical address. +# @begin: if specified, the starting physical address. # -# @length: #optional if specified, the memory size, in bytes. If you don't +# @length: if specified, the memory size, in bytes. If you don't # want to dump all guest's memory, please specify the start @begin # and @length # -# @format: #optional if specified, the format of guest memory dump. But non-elf +# @format: if specified, the format of guest memory dump. But non-elf # format is conflict with paging and filter, ie. @paging, @begin and # @length is not allowed to be specified with non-elf @format at the # same time (since 2.0) @@ -3512,7 +3512,7 @@ # # @id: the name of the new object # -# @props: #optional a dictionary of properties to be passed to the backend +# @props: a dictionary of properties to be passed to the backend # # Returns: Nothing on success # Error if @qom-type is not a valid class name @@ -3565,15 +3565,15 @@ # # Create a new Network Interface Card. # -# @netdev: #optional id of -netdev to connect to +# @netdev: id of -netdev to connect to # -# @macaddr: #optional MAC address +# @macaddr: MAC address # -# @model: #optional device model (e1000, rtl8139, virtio etc.) +# @model: device model (e1000, rtl8139, virtio etc.) # -# @addr: #optional PCI device address +# @addr: PCI device address # -# @vectors: #optional number of MSI-x vectors, 0 to disable MSI-X +# @vectors: number of MSI-x vectors, 0 to disable MSI-X # # Since: 1.2 ## @@ -3602,57 +3602,57 @@ # Use the user mode network stack which requires no administrator privilege to # run. # -# @hostname: #optional client hostname reported by the builtin DHCP server +# @hostname: client hostname reported by the builtin DHCP server # -# @restrict: #optional isolate the guest from the host +# @restrict: isolate the guest from the host # -# @ipv4: #optional whether to support IPv4, default true for enabled +# @ipv4: whether to support IPv4, default true for enabled # (since 2.6) # -# @ipv6: #optional whether to support IPv6, default true for enabled +# @ipv6: whether to support IPv6, default true for enabled # (since 2.6) # -# @ip: #optional legacy parameter, use net= instead +# @ip: legacy parameter, use net= instead # -# @net: #optional IP network address that the guest will see, in the +# @net: IP network address that the guest will see, in the # form addr[/netmask] The netmask is optional, and can be # either in the form a.b.c.d or as a number of valid top-most # bits. Default is 10.0.2.0/24. # -# @host: #optional guest-visible address of the host +# @host: guest-visible address of the host # -# @tftp: #optional root directory of the built-in TFTP server +# @tftp: root directory of the built-in TFTP server # -# @bootfile: #optional BOOTP filename, for use with tftp= +# @bootfile: BOOTP filename, for use with tftp= # -# @dhcpstart: #optional the first of the 16 IPs the built-in DHCP server can +# @dhcpstart: the first of the 16 IPs the built-in DHCP server can # assign # -# @dns: #optional guest-visible address of the virtual nameserver +# @dns: guest-visible address of the virtual nameserver # -# @dnssearch: #optional list of DNS suffixes to search, passed as DHCP option +# @dnssearch: list of DNS suffixes to search, passed as DHCP option # to the guest # -# @ipv6-prefix: #optional IPv6 network prefix (default is fec0::) (since +# @ipv6-prefix: IPv6 network prefix (default is fec0::) (since # 2.6). The network prefix is given in the usual # hexadecimal IPv6 address notation. # -# @ipv6-prefixlen: #optional IPv6 network prefix length (default is 64) +# @ipv6-prefixlen: IPv6 network prefix length (default is 64) # (since 2.6) # -# @ipv6-host: #optional guest-visible IPv6 address of the host (since 2.6) +# @ipv6-host: guest-visible IPv6 address of the host (since 2.6) # -# @ipv6-dns: #optional guest-visible IPv6 address of the virtual +# @ipv6-dns: guest-visible IPv6 address of the virtual # nameserver (since 2.6) # -# @smb: #optional root directory of the built-in SMB server +# @smb: root directory of the built-in SMB server # -# @smbserver: #optional IP address of the built-in SMB server +# @smbserver: IP address of the built-in SMB server # -# @hostfwd: #optional redirect incoming TCP or UDP host connections to guest +# @hostfwd: redirect incoming TCP or UDP host connections to guest # endpoints # -# @guestfwd: #optional forward guest TCP connections +# @guestfwd: forward guest TCP connections # # Since: 1.2 ## @@ -3684,37 +3684,37 @@ # # Connect the host TAP network interface name to the VLAN. # -# @ifname: #optional interface name +# @ifname: interface name # -# @fd: #optional file descriptor of an already opened tap +# @fd: file descriptor of an already opened tap # -# @fds: #optional multiple file descriptors of already opened multiqueue capable +# @fds: multiple file descriptors of already opened multiqueue capable # tap # -# @script: #optional script to initialize the interface +# @script: script to initialize the interface # -# @downscript: #optional script to shut down the interface +# @downscript: script to shut down the interface # -# @br: #optional bridge name (since 2.8) +# @br: bridge name (since 2.8) # -# @helper: #optional command to execute to configure bridge +# @helper: command to execute to configure bridge # -# @sndbuf: #optional send buffer limit. Understands [TGMKkb] suffixes. +# @sndbuf: send buffer limit. Understands [TGMKkb] suffixes. # -# @vnet_hdr: #optional enable the IFF_VNET_HDR flag on the tap interface +# @vnet_hdr: enable the IFF_VNET_HDR flag on the tap interface # -# @vhost: #optional enable vhost-net network accelerator +# @vhost: enable vhost-net network accelerator # -# @vhostfd: #optional file descriptor of an already opened vhost net device +# @vhostfd: file descriptor of an already opened vhost net device # -# @vhostfds: #optional file descriptors of multiple already opened vhost net +# @vhostfds: file descriptors of multiple already opened vhost net # devices # -# @vhostforce: #optional vhost on for non-MSIX virtio guests +# @vhostforce: vhost on for non-MSIX virtio guests # -# @queues: #optional number of queues to be created for multiqueue capable tap +# @queues: number of queues to be created for multiqueue capable tap # -# @poll-us: #optional maximum number of microseconds that could +# @poll-us: maximum number of microseconds that could # be spent on busy polling for tap (since 2.7) # # Since: 1.2 @@ -3743,17 +3743,17 @@ # Connect the VLAN to a remote VLAN in another QEMU virtual machine using a TCP # socket connection. # -# @fd: #optional file descriptor of an already opened socket +# @fd: file descriptor of an already opened socket # -# @listen: #optional port number, and optional hostname, to listen on +# @listen: port number, and optional hostname, to listen on # -# @connect: #optional port number, and optional hostname, to connect to +# @connect: port number, and optional hostname, to connect to # -# @mcast: #optional UDP multicast address and port number +# @mcast: UDP multicast address and port number # -# @localaddr: #optional source address and port for multicast and udp packets +# @localaddr: source address and port for multicast and udp packets # -# @udp: #optional UDP unicast address and port number +# @udp: UDP unicast address and port number # # Since: 1.2 ## @@ -3775,32 +3775,32 @@ # # @dst: destination address # -# @srcport: #optional source port - mandatory for udp, optional for ip +# @srcport: source port - mandatory for udp, optional for ip # -# @dstport: #optional destination port - mandatory for udp, optional for ip +# @dstport: destination port - mandatory for udp, optional for ip # -# @ipv6: #optional force the use of ipv6 +# @ipv6: force the use of ipv6 # -# @udp: #optional use the udp version of l2tpv3 encapsulation +# @udp: use the udp version of l2tpv3 encapsulation # -# @cookie64: #optional use 64 bit coookies +# @cookie64: use 64 bit coookies # -# @counter: #optional have sequence counter +# @counter: have sequence counter # -# @pincounter: #optional pin sequence counter to zero - +# @pincounter: pin sequence counter to zero - # workaround for buggy implementations or # networks with packet reorder # -# @txcookie: #optional 32 or 64 bit transmit cookie +# @txcookie: 32 or 64 bit transmit cookie # -# @rxcookie: #optional 32 or 64 bit receive cookie +# @rxcookie: 32 or 64 bit receive cookie # # @txsession: 32 bit transmit session # -# @rxsession: #optional 32 bit receive session - if not specified +# @rxsession: 32 bit receive session - if not specified # set to the same value as transmit # -# @offset: #optional additional offset - allows the insertion of +# @offset: additional offset - allows the insertion of # additional application-specific data before the packet payload # # Since: 2.1 @@ -3827,13 +3827,13 @@ # # Connect the VLAN to a vde switch running on the host. # -# @sock: #optional socket path +# @sock: socket path # -# @port: #optional port number +# @port: port number # -# @group: #optional group owner of socket +# @group: group owner of socket # -# @mode: #optional permissions for socket +# @mode: permissions for socket # # Since: 1.2 ## @@ -3849,10 +3849,10 @@ # # Dump VLAN network traffic to a file. # -# @len: #optional per-packet size limit (64k default). Understands [TGMKkb] +# @len: per-packet size limit (64k default). Understands [TGMKkb] # suffixes. # -# @file: #optional dump file path (default is qemu-vlan0.pcap) +# @file: dump file path (default is qemu-vlan0.pcap) # # Since: 1.2 ## @@ -3866,9 +3866,9 @@ # # Connect a host TAP network interface to a host bridge device. # -# @br: #optional bridge name +# @br: bridge name # -# @helper: #optional command to execute to configure bridge +# @helper: command to execute to configure bridge # # Since: 1.2 ## @@ -3902,7 +3902,7 @@ # YYY identifies a port of the switch. VALE ports having the # same XXX are therefore connected to the same switch. # -# @devname: #optional path of the netmap device (default: '/dev/netmap'). +# @devname: path of the netmap device (default: '/dev/netmap'). # # Since: 2.0 ## @@ -3918,9 +3918,9 @@ # # @chardev: name of a unix socket chardev # -# @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false). +# @vhostforce: vhost on for non-MSIX virtio guests (default: false). # -# @queues: #optional number of queues to be created for multiqueue vhost-user +# @queues: number of queues to be created for multiqueue vhost-user # (default: 1) (Since 2.5) # # Since: 2.1 @@ -3977,11 +3977,11 @@ # # Captures the configuration of a network device; legacy. # -# @vlan: #optional vlan number +# @vlan: vlan number # -# @id: #optional identifier for monitor commands +# @id: identifier for monitor commands # -# @name: #optional identifier for monitor commands, ignored if @id is present +# @name: identifier for monitor commands, ignored if @id is present # # @opts: device type specific properties (legacy) # @@ -4055,17 +4055,15 @@ # # @port: port part of the address, or lowest port if @to is present # -# @numeric: #optional true if the host/port are guaranteed to be numeric, +# @numeric: true if the host/port are guaranteed to be numeric, # false if name resolution should be attempted. Defaults to false. # (Since 2.9) # # @to: highest port to try # # @ipv4: whether to accept IPv4 addresses, default try both IPv4 and IPv6 -# #optional # # @ipv6: whether to accept IPv6 addresses, default try both IPv4 and IPv6 -# #optional # # Since: 1.3 ## @@ -4213,9 +4211,9 @@ # # @name: the name of the machine # -# @alias: #optional an alias for the machine name +# @alias: an alias for the machine name # -# @is-default: #optional whether the machine is default +# @is-default: whether the machine is default # # @cpu-max: maximum number of CPUs supported by the machine type # (since 1.5.0) @@ -4247,7 +4245,7 @@ # # @name: the name of the CPU definition # -# @migration-safe: #optional whether a CPU definition can be safely used for +# @migration-safe: whether a CPU definition can be safely used for # migration in combination with a QEMU compatibility machine # when migrating between different QMU versions and between # hosts with different sets of (hardware or software) @@ -4259,7 +4257,7 @@ # QEMU version, machine type, machine options and accelerator options. # A static model is always migration-safe. (since 2.8) # -# @unavailable-features: #optional List of properties that prevent +# @unavailable-features: List of properties that prevent # the CPU model from running in the current # host. (since 2.8) # @typename: Type name that can be used as argument to @device-list-properties, @@ -4310,7 +4308,7 @@ # However, if required, architectures can expose relevant properties. # # @name: the name of the CPU definition the model is based on -# @props: #optional a dictionary of QOM properties to be applied +# @props: a dictionary of QOM properties to be applied # # Since: 2.8.0 ## @@ -4559,9 +4557,9 @@ # # Add a file descriptor, that was passed via SCM rights, to an fd set. # -# @fdset-id: #optional The ID of the fd set to add the file descriptor to. +# @fdset-id: The ID of the fd set to add the file descriptor to. # -# @opaque: #optional A free-form string that can be used to describe the fd. +# @opaque: A free-form string that can be used to describe the fd. # # Returns: @AddfdInfo on success # @@ -4591,7 +4589,7 @@ # # @fdset-id: The ID of the fd set that the file descriptor belongs to. # -# @fd: #optional The file descriptor that is to be removed. +# @fd: The file descriptor that is to be removed. # # Returns: Nothing on success # If @fdset-id or @fd is not found, FdNotFound @@ -4618,7 +4616,7 @@ # # @fd: The file descriptor value. # -# @opaque: #optional A free-form string that can be used to describe the fd. +# @opaque: A free-form string that can be used to describe the fd. # # Since: 1.2.0 ## @@ -4769,7 +4767,7 @@ # directly to the guest, while @KeyValue.qcode must be a valid # @QKeyCode value # -# @hold-time: #optional time to delay key up events, milliseconds. Defaults +# @hold-time: time to delay key up events, milliseconds. Defaults # to 100 # # Returns: Nothing on success @@ -4815,8 +4813,8 @@ # # Configuration shared across all chardev backends # -# @logfile: #optional The name of a logfile to save output -# @logappend: #optional true to append instead of truncate +# @logfile: The name of a logfile to save output +# @logappend: true to append instead of truncate # (default to false to truncate) # # Since: 2.6 @@ -4829,9 +4827,9 @@ # # Configuration info for file chardevs. # -# @in: #optional The name of the input file +# @in: The name of the input file # @out: The name of the output file -# @append: #optional Open the file in append mode (default false to +# @append: Open the file in append mode (default false to # truncate) (Since 2.6) # # Since: 1.4 @@ -4861,14 +4859,14 @@ # # @addr: socket address to listen on (server=true) # or connect to (server=false) -# @tls-creds: #optional the ID of the TLS credentials object (since 2.6) -# @server: #optional create server socket (default: true) -# @wait: #optional wait for incoming connection on server +# @tls-creds: the ID of the TLS credentials object (since 2.6) +# @server: create server socket (default: true) +# @wait: wait for incoming connection on server # sockets (default: false). -# @nodelay: #optional set TCP_NODELAY socket option (default: false) -# @telnet: #optional enable telnet protocol on server +# @nodelay: set TCP_NODELAY socket option (default: false) +# @telnet: enable telnet protocol on server # sockets (default: false) -# @reconnect: #optional For a client socket, if a socket is disconnected, +# @reconnect: For a client socket, if a socket is disconnected, # then attempt a reconnect after the given number of seconds. # Setting this to zero disables this function. (default: 0) # (Since: 2.2) @@ -4890,7 +4888,7 @@ # Configuration info for datagram socket chardevs. # # @remote: remote address -# @local: #optional local address +# @local: local address # # Since: 1.5 ## @@ -4915,7 +4913,7 @@ # # Configuration info for stdio chardevs. # -# @signal: #optional Allow signals (such as SIGINT triggered by ^C) +# @signal: Allow signals (such as SIGINT triggered by ^C) # be delivered to qemu. Default: true in -nographic mode, # false otherwise. # @@ -4972,7 +4970,7 @@ # # Configuration info for ring buffer chardevs. # -# @size: #optional ring buffer size, must be power of two, default is 65536 +# @size: ring buffer size, must be power of two, default is 65536 # # Since: 1.5 ## @@ -5013,7 +5011,7 @@ # # Return info about the chardev backend just created. # -# @pty: #optional name of the slave pseudoterminal device, present if +# @pty: name of the slave pseudoterminal device, present if # and only if a chardev of type 'pty' was created # # Since: 1.4 @@ -5135,9 +5133,9 @@ # # Information about the TPM passthrough type # -# @path: #optional string describing the path used for accessing the TPM device +# @path: string describing the path used for accessing the TPM device # -# @cancel-path: #optional string showing the TPM's sysfs cancel file +# @cancel-path: string showing the TPM's sysfs cancel file # for cancellation of TPM commands while they are executing # # Since: 1.5 @@ -5223,28 +5221,28 @@ # String fields are copied into the matching ACPI member from lowest address # upwards, and silently truncated / NUL-padded to length. # -# @sig: #optional table signature / identifier (4 bytes) +# @sig: table signature / identifier (4 bytes) # -# @rev: #optional table revision number (dependent on signature, 1 byte) +# @rev: table revision number (dependent on signature, 1 byte) # -# @oem_id: #optional OEM identifier (6 bytes) +# @oem_id: OEM identifier (6 bytes) # -# @oem_table_id: #optional OEM table identifier (8 bytes) +# @oem_table_id: OEM table identifier (8 bytes) # -# @oem_rev: #optional OEM-supplied revision number (4 bytes) +# @oem_rev: OEM-supplied revision number (4 bytes) # -# @asl_compiler_id: #optional identifier of the utility that created the table +# @asl_compiler_id: identifier of the utility that created the table # (4 bytes) # -# @asl_compiler_rev: #optional revision number of the utility that created the +# @asl_compiler_rev: revision number of the utility that created the # table (4 bytes) # -# @file: #optional colon (:) separated list of pathnames to load and +# @file: colon (:) separated list of pathnames to load and # concatenate as table data. The resultant binary blob is expected to # have an ACPI table header. At least one file is required. This field # excludes @data. # -# @data: #optional colon (:) separated list of pathnames to load and +# @data: colon (:) separated list of pathnames to load and # concatenate as table data. The resultant binary blob must not have an # ACPI table header. At least one file is required. This field excludes # @file. @@ -5291,9 +5289,9 @@ # # @type: parameter @CommandLineParameterType # -# @help: #optional human readable text string, not suitable for parsing. +# @help: human readable text string, not suitable for parsing. # -# @default: #optional default value string (since 2.1) +# @default: default value string (since 2.1) # # Since: 1.5 ## @@ -5322,7 +5320,7 @@ # # Query command line option schema. # -# @option: #optional option name +# @option: option name # # Returns: list of @CommandLineOptionInfo for all options (or for the given # @option). Returns an error if the given @option doesn't exist. @@ -5371,7 +5369,7 @@ # # @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word # -# @cpuid-input-ecx: #optional Input ECX value for CPUID instruction for that +# @cpuid-input-ecx: Input ECX value for CPUID instruction for that # feature word # # @cpuid-register: Output register containing the feature bits @@ -5463,7 +5461,7 @@ # # Return rx-filter information for all NICs (or for the given NIC). # -# @name: #optional net client name +# @name: net client name # # Returns: list of @RxFilterInfo for all NICs (or for the given NIC). # Returns an error if the given @name doesn't exist, or given @@ -5597,8 +5595,8 @@ # # Send input event(s) to guest. # -# @device: #optional display device to send event(s) to. -# @head: #optional head to send event(s) to, in case the +# @device: display device to send event(s) to. +# @head: head to send event(s) to, in case the # display device supports multiple scanouts. # @events: List of InputEvent union. # @@ -5690,16 +5688,16 @@ # # Create a guest NUMA node. (for OptsVisitor) # -# @nodeid: #optional NUMA node ID (increase by 1 from 0 if omitted) +# @nodeid: NUMA node ID (increase by 1 from 0 if omitted) # -# @cpus: #optional VCPUs belonging to this node (assign VCPUS round-robin +# @cpus: VCPUs belonging to this node (assign VCPUS round-robin # if omitted) # -# @mem: #optional memory size of this node; mutually exclusive with @memdev. +# @mem: memory size of this node; mutually exclusive with @memdev. # Equally divide total memory among nodes if both @mem and @memdev are # omitted. # -# @memdev: #optional memory backend object. If specified for one node, +# @memdev: memory backend object. If specified for one node, # it must be specified for all nodes. # # Since: 2.1 @@ -5736,7 +5734,7 @@ # # Information about memory backend # -# @id: #optional backend's ID if backend has 'id' property (since 2.9) +# @id: backend's ID if backend has 'id' property (since 2.9) # # @size: memory backend size # @@ -5803,7 +5801,7 @@ # # PCDIMMDevice state information # -# @id: #optional device's ID +# @id: device's ID # # @addr: physical address, where device is mapped # @@ -5882,7 +5880,7 @@ # For description of possible values of @source and @status fields # see "_OST (OSPM Status Indication)" chapter of ACPI5.0 spec. # -# @device: #optional device ID associated with slot +# @device: device ID associated with slot # # @slot: slot ID, unique per slot of a given @slot-type # @@ -6080,7 +6078,7 @@ # # @primary: true for primary or false for secondary. # -# @failover: #optional true to do failover, false to stop. but cannot be +# @failover: true to do failover, false to stop. but cannot be # specified if 'enable' is true. default value is false. # # Returns: nothing. @@ -6103,7 +6101,7 @@ # # @error: true if an error happened, false if replication is normal. # -# @desc: #optional the human readable error description string, when +# @desc: the human readable error description string, when # @error is 'true'. # # Since: 2.9 @@ -6194,10 +6192,10 @@ # it should be passed by management with device_add command when # a CPU is being hotplugged. # -# @node-id: #optional NUMA node ID the CPU belongs to -# @socket-id: #optional socket number within node/board the CPU belongs to -# @core-id: #optional core number within socket the CPU belongs to -# @thread-id: #optional thread number within core the CPU belongs to +# @node-id: NUMA node ID the CPU belongs to +# @socket-id: socket number within node/board the CPU belongs to +# @core-id: core number within socket the CPU belongs to +# @thread-id: thread number within core the CPU belongs to # # Note: currently there are 4 properties that could be present # but management should be prepared to pass through other @@ -6221,7 +6219,7 @@ # @type: CPU object type for usage with device_add command # @props: list of properties to be used for hotplugging CPU # @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides -# @qom-path: #optional link to existing CPU object if CPU is present or +# @qom-path: link to existing CPU object if CPU is present or # omitted if CPU is not present. # # Since: 2.7 diff --git a/qapi/block-core.json b/qapi/block-core.json index 786b39e911..1be1ec58ac 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -37,9 +37,9 @@ # # @compat: compatibility level # -# @lazy-refcounts: #optional on or off; only valid for compat >= 1.1 +# @lazy-refcounts: on or off; only valid for compat >= 1.1 # -# @corrupt: #optional true if the image has been marked corrupt; only valid for +# @corrupt: true if the image has been marked corrupt; only valid for # compat >= 1.1 (since 2.2) # # @refcount-bits: width of a refcount entry in bits (since 2.3) @@ -103,27 +103,27 @@ # # @virtual-size: maximum capacity in bytes of the image # -# @actual-size: #optional actual size on disk in bytes of the image +# @actual-size: actual size on disk in bytes of the image # -# @dirty-flag: #optional true if image is not cleanly closed +# @dirty-flag: true if image is not cleanly closed # -# @cluster-size: #optional size of a cluster in bytes +# @cluster-size: size of a cluster in bytes # -# @encrypted: #optional true if the image is encrypted +# @encrypted: true if the image is encrypted # -# @compressed: #optional true if the image is compressed (Since 1.7) +# @compressed: true if the image is compressed (Since 1.7) # -# @backing-filename: #optional name of the backing file +# @backing-filename: name of the backing file # -# @full-backing-filename: #optional full path of the backing file +# @full-backing-filename: full path of the backing file # -# @backing-filename-format: #optional the format of the backing file +# @backing-filename-format: the format of the backing file # -# @snapshots: #optional list of VM snapshots +# @snapshots: list of VM snapshots # -# @backing-image: #optional info of the backing image (since 1.6) +# @backing-image: info of the backing image (since 1.6) # -# @format-specific: #optional structure supplying additional format-specific +# @format-specific: structure supplying additional format-specific # information (since 1.7) # # Since: 1.3 @@ -149,31 +149,31 @@ # # @check-errors: number of unexpected errors occurred during check # -# @image-end-offset: #optional offset (in bytes) where the image ends, this +# @image-end-offset: offset (in bytes) where the image ends, this # field is present if the driver for the image format # supports it # -# @corruptions: #optional number of corruptions found during the check if any +# @corruptions: number of corruptions found during the check if any # -# @leaks: #optional number of leaks found during the check if any +# @leaks: number of leaks found during the check if any # -# @corruptions-fixed: #optional number of corruptions fixed during the check +# @corruptions-fixed: number of corruptions fixed during the check # if any # -# @leaks-fixed: #optional number of leaks fixed during the check if any +# @leaks-fixed: number of leaks fixed during the check if any # -# @total-clusters: #optional total number of clusters, this field is present +# @total-clusters: total number of clusters, this field is present # if the driver for the image format supports it # -# @allocated-clusters: #optional total number of allocated clusters, this +# @allocated-clusters: total number of allocated clusters, this # field is present if the driver for the image format # supports it # -# @fragmented-clusters: #optional total number of fragmented clusters, this +# @fragmented-clusters: total number of fragmented clusters, this # field is present if the driver for the image format # supports it # -# @compressed-clusters: #optional total number of compressed clusters, this +# @compressed-clusters: total number of compressed clusters, this # field is present if the driver for the image format # supports it # @@ -202,9 +202,9 @@ # # @depth: the depth of the mapping # -# @offset: #optional the offset in file that the virtual sectors are mapped to +# @offset: the offset in file that the virtual sectors are mapped to # -# @filename: #optional filename that is referred to by @offset +# @filename: filename that is referred to by @offset # # Since: 2.6 # @@ -237,7 +237,7 @@ # # @file: the filename of the backing device # -# @node-name: #optional the name of the block driver node (Since 2.0) +# @node-name: the name of the block driver node (Since 2.0) # # @ro: true if the backing device was open read-only # @@ -253,7 +253,7 @@ # 2.8: 'replication' added, 'tftp' dropped # 2.9: 'archipelago' dropped # -# @backing_file: #optional the name of the backing file (for copy-on-write) +# @backing_file: the name of the backing file (for copy-on-write) # # @backing_file_depth: number of files in the backing file chain (since: 1.2) # @@ -278,45 +278,45 @@ # # @image: the info of image used (since: 1.6) # -# @bps_max: #optional total throughput limit during bursts, +# @bps_max: total throughput limit during bursts, # in bytes (Since 1.7) # -# @bps_rd_max: #optional read throughput limit during bursts, +# @bps_rd_max: read throughput limit during bursts, # in bytes (Since 1.7) # -# @bps_wr_max: #optional write throughput limit during bursts, +# @bps_wr_max: write throughput limit during bursts, # in bytes (Since 1.7) # -# @iops_max: #optional total I/O operations per second during bursts, +# @iops_max: total I/O operations per second during bursts, # in bytes (Since 1.7) # -# @iops_rd_max: #optional read I/O operations per second during bursts, +# @iops_rd_max: read I/O operations per second during bursts, # in bytes (Since 1.7) # -# @iops_wr_max: #optional write I/O operations per second during bursts, +# @iops_wr_max: write I/O operations per second during bursts, # in bytes (Since 1.7) # -# @bps_max_length: #optional maximum length of the @bps_max burst +# @bps_max_length: maximum length of the @bps_max burst # period, in seconds. (Since 2.6) # -# @bps_rd_max_length: #optional maximum length of the @bps_rd_max +# @bps_rd_max_length: maximum length of the @bps_rd_max # burst period, in seconds. (Since 2.6) # -# @bps_wr_max_length: #optional maximum length of the @bps_wr_max +# @bps_wr_max_length: maximum length of the @bps_wr_max # burst period, in seconds. (Since 2.6) # -# @iops_max_length: #optional maximum length of the @iops burst +# @iops_max_length: maximum length of the @iops burst # period, in seconds. (Since 2.6) # -# @iops_rd_max_length: #optional maximum length of the @iops_rd_max +# @iops_rd_max_length: maximum length of the @iops_rd_max # burst period, in seconds. (Since 2.6) # -# @iops_wr_max_length: #optional maximum length of the @iops_wr_max +# @iops_wr_max_length: maximum length of the @iops_wr_max # burst period, in seconds. (Since 2.6) # -# @iops_size: #optional an I/O size in bytes (Since 1.7) +# @iops_size: an I/O size in bytes (Since 1.7) # -# @group: #optional throttle group name (Since 2.4) +# @group: throttle group name (Since 2.4) # # @cache: the cache mode used for the block device (since: 2.3) # @@ -411,7 +411,7 @@ # # Block dirty bitmap information. # -# @name: #optional the name of the dirty bitmap (Since 2.4) +# @name: the name of the dirty bitmap (Since 2.4) # # @count: number of dirty bytes according to the dirty bitmap # @@ -441,17 +441,17 @@ # @locked: True if the guest has locked this device from having its media # removed # -# @tray_open: #optional True if the device's tray is open +# @tray_open: True if the device's tray is open # (only present if it has a tray) # -# @dirty-bitmaps: #optional dirty bitmaps information (only present if the +# @dirty-bitmaps: dirty bitmaps information (only present if the # driver has one or more dirty bitmaps) (Since 2.0) # -# @io-status: #optional @BlockDeviceIoStatus. Only present if the device +# @io-status: @BlockDeviceIoStatus. Only present if the device # supports it and the VM is configured to stop on errors # (supported device models: virtio-blk, ide, scsi-disk) # -# @inserted: #optional @BlockDeviceInfo describing the device if media is +# @inserted: @BlockDeviceInfo describing the device if media is # present # # Since: 0.14.0 @@ -640,7 +640,7 @@ # @wr_merged: Number of write requests that have been merged into another # request (Since 2.3). # -# @idle_time_ns: #optional Time since the last I/O operation, in +# @idle_time_ns: Time since the last I/O operation, in # nanoseconds. If the field is absent it means that # there haven't been any operations yet (Since 2.5). # @@ -690,19 +690,19 @@ # # Statistics of a virtual block device or a block backing device. # -# @device: #optional If the stats are for a virtual block device, the name +# @device: If the stats are for a virtual block device, the name # corresponding to the virtual block device. # -# @node-name: #optional The node name of the device. (Since 2.3) +# @node-name: The node name of the device. (Since 2.3) # # @stats: A @BlockDeviceStats for the device. # -# @parent: #optional This describes the file block device if it has one. +# @parent: This describes the file block device if it has one. # Contains recursively the statistics of the underlying # protocol (e.g. the host file for a qcow2 image). If there is # no underlying protocol, this field is omitted # -# @backing: #optional This describes the backing block device if it has one. +# @backing: This describes the backing block device if it has one. # (Since 2.0) # # Since: 0.14.0 @@ -718,7 +718,7 @@ # # Query the @BlockStats for all virtual block devices. # -# @query-nodes: #optional If true, the command will query all the block nodes +# @query-nodes: If true, the command will query all the block nodes # that have a node name, in a list which will include "parent" # information, but not "backing". # If false or omitted, the behavior is as before - query all the @@ -957,9 +957,9 @@ # # Either @device or @node-name must be set but not both. # -# @device: #optional the name of the block backend device to set the password on +# @device: the name of the block backend device to set the password on # -# @node-name: #optional graph node name to set the password on (Since 2.0) +# @node-name: graph node name to set the password on (Since 2.0) # # @password: the password to use for the device # @@ -990,9 +990,9 @@ # # Either @device or @node-name must be set but not both. # -# @device: #optional the name of the device to get the image resized +# @device: the name of the device to get the image resized # -# @node-name: #optional graph node name to get the image resized (Since 2.0) +# @node-name: graph node name to get the image resized (Since 2.0) # # @size: new image size in bytes # @@ -1034,19 +1034,19 @@ # # Either @device or @node-name must be set but not both. # -# @device: #optional the name of the device to generate the snapshot from. +# @device: the name of the device to generate the snapshot from. # -# @node-name: #optional graph node name to generate the snapshot from (Since 2.0) +# @node-name: graph node name to generate the snapshot from (Since 2.0) # # @snapshot-file: the target of the new image. If the file exists, or # if it is a device, the snapshot will be created in the existing # file/device. Otherwise, a new file will be created. # -# @snapshot-node-name: #optional the graph node name of the new image (Since 2.0) +# @snapshot-node-name: the graph node name of the new image (Since 2.0) # -# @format: #optional the format of the snapshot image, default is 'qcow2'. +# @format: the format of the snapshot image, default is 'qcow2'. # -# @mode: #optional whether and how QEMU should create a new image, default is +# @mode: whether and how QEMU should create a new image, default is # 'absolute-paths'. ## { 'struct': 'BlockdevSnapshotSync', @@ -1072,7 +1072,7 @@ ## # @DriveBackup: # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: the device name or node-name of a root node which should be copied. @@ -1081,30 +1081,30 @@ # is a device, the existing file/device will be used as the new # destination. If it does not exist, a new file will be created. # -# @format: #optional the format of the new destination, default is to +# @format: the format of the new destination, default is to # probe if @mode is 'existing', else the format of the source # # @sync: what parts of the disk image should be copied to the destination # (all the disk, only the sectors allocated in the topmost image, from a # dirty bitmap, or only new I/O). # -# @mode: #optional whether and how QEMU should create a new image, default is +# @mode: whether and how QEMU should create a new image, default is # 'absolute-paths'. # -# @speed: #optional the maximum speed, in bytes per second +# @speed: the maximum speed, in bytes per second # -# @bitmap: #optional the name of dirty bitmap if sync is "incremental". +# @bitmap: the name of dirty bitmap if sync is "incremental". # Must be present if sync is "incremental", must NOT be present # otherwise. (Since 2.4) # -# @compress: #optional true to compress data, if the target format supports it. +# @compress: true to compress data, if the target format supports it. # (default: false) (since 2.8) # -# @on-source-error: #optional the action to take on an error on the source, +# @on-source-error: the action to take on an error on the source, # default 'report'. 'stop' and 'enospc' can only be used # if the block device supports io-status (see BlockInfo). # -# @on-target-error: #optional the action to take on an error on the target, +# @on-target-error: the action to take on an error on the target, # default 'report' (no limitations, since this applies to # a different block device than @device). # @@ -1124,7 +1124,7 @@ ## # @BlockdevBackup: # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: the device name or node-name of a root node which should be copied. @@ -1135,17 +1135,17 @@ # (all the disk, only the sectors allocated in the topmost image, or # only new I/O). # -# @speed: #optional the maximum speed, in bytes per second. The default is 0, +# @speed: the maximum speed, in bytes per second. The default is 0, # for unlimited. # -# @compress: #optional true to compress data, if the target format supports it. +# @compress: true to compress data, if the target format supports it. # (default: false) (since 2.8) # -# @on-source-error: #optional the action to take on an error on the source, +# @on-source-error: the action to take on an error on the source, # default 'report'. 'stop' and 'enospc' can only be used # if the block device supports io-status (see BlockInfo). # -# @on-target-error: #optional the action to take on an error on the target, +# @on-target-error: the action to take on an error on the target, # default 'report' (no limitations, since this applies to # a different block device than @device). # @@ -1262,19 +1262,19 @@ # Live commit of data from overlay image nodes into backing nodes - i.e., # writes data between 'top' and 'base' into 'base'. # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: the device name or node-name of a root node # -# @base: #optional The file name of the backing image to write data into. +# @base: The file name of the backing image to write data into. # If not specified, this is the deepest backing image. # -# @top: #optional The file name of the backing image within the image chain, +# @top: The file name of the backing image within the image chain, # which contains the topmost data to be committed down. If # not specified, this is the active layer. # -# @backing-file: #optional The backing file string to write into the overlay +# @backing-file: The backing file string to write into the overlay # image of 'top'. If 'top' is the active layer, # specifying a backing file string is an error. This # filename is not validated. @@ -1303,9 +1303,9 @@ # size of the smaller top, you can safely truncate it # yourself once the commit operation successfully completes. # -# @speed: #optional the maximum speed, in bytes per second +# @speed: the maximum speed, in bytes per second # -# @filter-node-name: #optional the node name that should be assigned to the +# @filter-node-name: the node name that should be assigned to the # filter driver that the commit job inserts into the graph # above @top. If this option is not given, a node name is # autogenerated. (Since: 2.9) @@ -1483,7 +1483,7 @@ # # A set of parameters describing drive mirror setup. # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: the device name or node-name of a root node whose writes should be @@ -1493,41 +1493,41 @@ # is a device, the existing file/device will be used as the new # destination. If it does not exist, a new file will be created. # -# @format: #optional the format of the new destination, default is to +# @format: the format of the new destination, default is to # probe if @mode is 'existing', else the format of the source # -# @node-name: #optional the new block driver state node name in the graph +# @node-name: the new block driver state node name in the graph # (Since 2.1) # -# @replaces: #optional with sync=full graph node name to be replaced by the new +# @replaces: with sync=full graph node name to be replaced by the new # image when a whole image copy is done. This can be used to repair # broken Quorum files. (Since 2.1) # -# @mode: #optional whether and how QEMU should create a new image, default is +# @mode: whether and how QEMU should create a new image, default is # 'absolute-paths'. # -# @speed: #optional the maximum speed, in bytes per second +# @speed: the maximum speed, in bytes per second # # @sync: what parts of the disk image should be copied to the destination # (all the disk, only the sectors allocated in the topmost image, or # only new I/O). # -# @granularity: #optional granularity of the dirty bitmap, default is 64K +# @granularity: granularity of the dirty bitmap, default is 64K # if the image format doesn't have clusters, 4K if the clusters # are smaller than that, else the cluster size. Must be a # power of 2 between 512 and 64M (since 1.4). # -# @buf-size: #optional maximum amount of data in flight from source to +# @buf-size: maximum amount of data in flight from source to # target (since 1.4). # -# @on-source-error: #optional the action to take on an error on the source, +# @on-source-error: the action to take on an error on the source, # default 'report'. 'stop' and 'enospc' can only be used # if the block device supports io-status (see BlockInfo). # -# @on-target-error: #optional the action to take on an error on the target, +# @on-target-error: the action to take on an error on the target, # default 'report' (no limitations, since this applies to # a different block device than @device). -# @unmap: #optional Whether to try to unmap target sectors where source has +# @unmap: Whether to try to unmap target sectors where source has # only zero. If true, and target unallocated sectors will read as zero, # target image sectors will be unmapped; otherwise, zeroes will be # written. Both will result in identical contents. @@ -1563,7 +1563,7 @@ # # @name: name of the dirty bitmap # -# @granularity: #optional the bitmap granularity, default is 64k for +# @granularity: the bitmap granularity, default is 64k for # block-dirty-bitmap-add # # Since: 2.4 @@ -1643,7 +1643,7 @@ # # Start mirroring a block device's writes to a new destination. # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: The device name or node-name of a root node whose writes should be @@ -1652,33 +1652,33 @@ # @target: the id or node-name of the block device to mirror to. This mustn't be # attached to guest. # -# @replaces: #optional with sync=full graph node name to be replaced by the new +# @replaces: with sync=full graph node name to be replaced by the new # image when a whole image copy is done. This can be used to repair # broken Quorum files. # -# @speed: #optional the maximum speed, in bytes per second +# @speed: the maximum speed, in bytes per second # # @sync: what parts of the disk image should be copied to the destination # (all the disk, only the sectors allocated in the topmost image, or # only new I/O). # -# @granularity: #optional granularity of the dirty bitmap, default is 64K +# @granularity: granularity of the dirty bitmap, default is 64K # if the image format doesn't have clusters, 4K if the clusters # are smaller than that, else the cluster size. Must be a # power of 2 between 512 and 64M # -# @buf-size: #optional maximum amount of data in flight from source to +# @buf-size: maximum amount of data in flight from source to # target # -# @on-source-error: #optional the action to take on an error on the source, +# @on-source-error: the action to take on an error on the source, # default 'report'. 'stop' and 'enospc' can only be used # if the block device supports io-status (see BlockInfo). # -# @on-target-error: #optional the action to take on an error on the target, +# @on-target-error: the action to take on an error on the target, # default 'report' (no limitations, since this applies to # a different block device than @device). # -# @filter-node-name: #optional the node name that should be assigned to the +# @filter-node-name: the node name that should be assigned to the # filter driver that the mirror job inserts into the graph # above @device. If this option is not given, a node name is # autogenerated. (Since: 2.9) @@ -1766,9 +1766,9 @@ # # A set of parameters describing block throttling. # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # # @bps: total throughput limit in bytes per second # @@ -1782,57 +1782,57 @@ # # @iops_wr: write I/O operations per second # -# @bps_max: #optional total throughput limit during bursts, +# @bps_max: total throughput limit during bursts, # in bytes (Since 1.7) # -# @bps_rd_max: #optional read throughput limit during bursts, +# @bps_rd_max: read throughput limit during bursts, # in bytes (Since 1.7) # -# @bps_wr_max: #optional write throughput limit during bursts, +# @bps_wr_max: write throughput limit during bursts, # in bytes (Since 1.7) # -# @iops_max: #optional total I/O operations per second during bursts, +# @iops_max: total I/O operations per second during bursts, # in bytes (Since 1.7) # -# @iops_rd_max: #optional read I/O operations per second during bursts, +# @iops_rd_max: read I/O operations per second during bursts, # in bytes (Since 1.7) # -# @iops_wr_max: #optional write I/O operations per second during bursts, +# @iops_wr_max: write I/O operations per second during bursts, # in bytes (Since 1.7) # -# @bps_max_length: #optional maximum length of the @bps_max burst +# @bps_max_length: maximum length of the @bps_max burst # period, in seconds. It must only # be set if @bps_max is set as well. # Defaults to 1. (Since 2.6) # -# @bps_rd_max_length: #optional maximum length of the @bps_rd_max +# @bps_rd_max_length: maximum length of the @bps_rd_max # burst period, in seconds. It must only # be set if @bps_rd_max is set as well. # Defaults to 1. (Since 2.6) # -# @bps_wr_max_length: #optional maximum length of the @bps_wr_max +# @bps_wr_max_length: maximum length of the @bps_wr_max # burst period, in seconds. It must only # be set if @bps_wr_max is set as well. # Defaults to 1. (Since 2.6) # -# @iops_max_length: #optional maximum length of the @iops burst +# @iops_max_length: maximum length of the @iops burst # period, in seconds. It must only # be set if @iops_max is set as well. # Defaults to 1. (Since 2.6) # -# @iops_rd_max_length: #optional maximum length of the @iops_rd_max +# @iops_rd_max_length: maximum length of the @iops_rd_max # burst period, in seconds. It must only # be set if @iops_rd_max is set as well. # Defaults to 1. (Since 2.6) # -# @iops_wr_max_length: #optional maximum length of the @iops_wr_max +# @iops_wr_max_length: maximum length of the @iops_wr_max # burst period, in seconds. It must only # be set if @iops_wr_max is set as well. # Defaults to 1. (Since 2.6) # -# @iops_size: #optional an I/O size in bytes (Since 1.7) +# @iops_size: an I/O size in bytes (Since 1.7) # -# @group: #optional throttle group name (Since 2.4) +# @group: throttle group name (Since 2.4) # # Since: 1.1 ## @@ -1873,18 +1873,18 @@ # On successful completion the image file is updated to drop the backing file # and the BLOCK_JOB_COMPLETED event is emitted. # -# @job-id: #optional identifier for the newly-created block job. If +# @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # # @device: the device or node name of the top image # -# @base: #optional the common backing file name. +# @base: the common backing file name. # It cannot be set if @base-node is also set. # -# @base-node: #optional the node name of the backing file. +# @base-node: the node name of the backing file. # It cannot be set if @base is also set. (Since 2.8) # -# @backing-file: #optional The backing file string to write into the top +# @backing-file: The backing file string to write into the top # image. This filename is not validated. # # If a pathname string is such that it cannot be @@ -1899,9 +1899,9 @@ # protocol. # (Since 2.1) # -# @speed: #optional the maximum speed, in bytes per second +# @speed: the maximum speed, in bytes per second # -# @on-error: #optional the action to take on an error (default report). +# @on-error: the action to take on an error (default report). # 'stop' and 'enospc' can only be used if the block device # supports io-status (see BlockInfo). Since 1.3. # @@ -1968,7 +1968,7 @@ # the name of the parameter), but since QEMU 2.7 it can have # other values. # -# @force: #optional whether to allow cancellation of a paused job (default +# @force: whether to allow cancellation of a paused job (default # false). Since 1.3. # # Returns: Nothing on success @@ -2100,9 +2100,9 @@ # # Includes cache-related options for block devices # -# @direct: #optional enables use of O_DIRECT (bypass the host page cache; +# @direct: enables use of O_DIRECT (bypass the host page cache; # default: false) -# @no-flush: #optional ignore any flush requests for the device (default: +# @no-flush: ignore any flush requests for the device (default: # false) # # Since: 1.7 @@ -2143,7 +2143,7 @@ # Driver specific block device options for the file backend. # # @filename: path to the image file -# @aio: #optional AIO backend (default: threads) (since: 2.8) +# @aio: AIO backend (default: threads) (since: 2.8) # # Since: 1.7 ## @@ -2156,8 +2156,8 @@ # # Driver specific block device options for the null backend. # -# @size: #optional size of the device in bytes. -# @latency-ns: #optional emulated latency (in nanoseconds) in processing +# @size: size of the device in bytes. +# @latency-ns: emulated latency (in nanoseconds) in processing # requests. Default to zero which completes requests immediately. # (Since 2.4) # @@ -2172,14 +2172,14 @@ # Driver specific block device options for the vvfat protocol. # # @dir: directory to be exported as FAT image -# @fat-type: #optional FAT type: 12, 16 or 32 -# @floppy: #optional whether to export a floppy image (true) or +# @fat-type: FAT type: 12, 16 or 32 +# @floppy: whether to export a floppy image (true) or # partitioned hard disk (false; default) -# @label: #optional set the volume label, limited to 11 bytes. FAT16 and +# @label: set the volume label, limited to 11 bytes. FAT16 and # FAT32 traditionally have some restrictions on labels, which are # ignored by most operating systems. Defaults to "QEMU VVFAT". # (since 2.4) -# @rw: #optional whether to allow write operations (default: false) +# @rw: whether to allow write operations (default: false) # # Since: 1.7 ## @@ -2205,7 +2205,7 @@ # # Driver specific block device options for LUKS. # -# @key-secret: #optional the ID of a QCryptoSecret object providing +# @key-secret: the ID of a QCryptoSecret object providing # the decryption key (since 2.6). Mandatory except when # doing a metadata-only probe of the image. # @@ -2222,7 +2222,7 @@ # Driver specific block device options for image format that have no option # besides their data source and an optional backing file. # -# @backing: #optional reference to or definition of the backing file block +# @backing: reference to or definition of the backing file block # device (if missing, taken from the image file content). It is # allowed to pass an empty string here in order to disable the # default backing file. @@ -2298,33 +2298,33 @@ # # Driver specific block device options for qcow2. # -# @lazy-refcounts: #optional whether to enable the lazy refcounts +# @lazy-refcounts: whether to enable the lazy refcounts # feature (default is taken from the image file) # -# @pass-discard-request: #optional whether discard requests to the qcow2 +# @pass-discard-request: whether discard requests to the qcow2 # device should be forwarded to the data source # -# @pass-discard-snapshot: #optional whether discard requests for the data source +# @pass-discard-snapshot: whether discard requests for the data source # should be issued when a snapshot operation (e.g. # deleting a snapshot) frees clusters in the qcow2 file # -# @pass-discard-other: #optional whether discard requests for the data source +# @pass-discard-other: whether discard requests for the data source # should be issued on other occasions where a cluster # gets freed # -# @overlap-check: #optional which overlap checks to perform for writes +# @overlap-check: which overlap checks to perform for writes # to the image, defaults to 'cached' (since 2.2) # -# @cache-size: #optional the maximum total size of the L2 table and +# @cache-size: the maximum total size of the L2 table and # refcount block caches in bytes (since 2.2) # -# @l2-cache-size: #optional the maximum size of the L2 table cache in +# @l2-cache-size: the maximum size of the L2 table cache in # bytes (since 2.2) # -# @refcount-cache-size: #optional the maximum size of the refcount block cache +# @refcount-cache-size: the maximum size of the refcount block cache # in bytes (since 2.2) # -# @cache-clean-interval: #optional clean unused entries in the L2 and refcount +# @cache-clean-interval: clean unused entries in the L2 and refcount # caches. The interval is in seconds. The default value # is 0 and it disables this feature (since 2.5) # @@ -2350,7 +2350,7 @@ # # @path: path to the image on the host # -# @user: #optional user as which to connect, defaults to current +# @user: user as which to connect, defaults to current # local user name # # TODO: Expose the host_key_check option in QMP @@ -2393,20 +2393,20 @@ # # @event: trigger event # -# @state: #optional the state identifier blkdebug needs to be in to +# @state: the state identifier blkdebug needs to be in to # actually trigger the event; defaults to "any" # -# @errno: #optional error identifier (errno) to be returned; defaults to +# @errno: error identifier (errno) to be returned; defaults to # EIO # -# @sector: #optional specifies the sector index which has to be affected +# @sector: specifies the sector index which has to be affected # in order to actually trigger the event; defaults to "any # sector" # -# @once: #optional disables further events after this one has been +# @once: disables further events after this one has been # triggered; defaults to false # -# @immediately: #optional fail immediately; defaults to false +# @immediately: fail immediately; defaults to false # # Since: 2.0 ## @@ -2425,7 +2425,7 @@ # # @event: trigger event # -# @state: #optional the current state identifier blkdebug needs to be in; +# @state: the current state identifier blkdebug needs to be in; # defaults to "any" # # @new_state: the state identifier blkdebug is supposed to assume if @@ -2445,14 +2445,14 @@ # # @image: underlying raw block device (or image file) # -# @config: #optional filename of the configuration file +# @config: filename of the configuration file # -# @align: #optional required alignment for requests in bytes, +# @align: required alignment for requests in bytes, # must be power of 2, or 0 for default # -# @inject-error: #optional array of error injection descriptions +# @inject-error: array of error injection descriptions # -# @set-state: #optional array of state-change descriptions +# @set-state: array of state-change descriptions # # Since: 2.0 ## @@ -2496,17 +2496,17 @@ # # Driver specific block device options for Quorum # -# @blkverify: #optional true if the driver must print content mismatch +# @blkverify: true if the driver must print content mismatch # set to false by default # # @children: the children block devices to use # # @vote-threshold: the vote limit under which a read will fail # -# @rewrite-corrupted: #optional rewrite corrupted data when quorum is reached +# @rewrite-corrupted: rewrite corrupted data when quorum is reached # (Since 2.1) # -# @read-pattern: #optional choose read pattern and set to quorum by default +# @read-pattern: choose read pattern and set to quorum by default # (Since 2.2) # # Since: 2.0 @@ -2529,10 +2529,10 @@ # # @server: gluster servers description # -# @debug: #optional libgfapi log level (default '4' which is Error) +# @debug: libgfapi log level (default '4' which is Error) # (Since 2.8) # -# @logfile: #optional libgfapi log file (default /dev/stderr) (Since 2.8) +# @logfile: libgfapi log file (default /dev/stderr) (Since 2.8) # # Since: 2.7 ## @@ -2573,23 +2573,23 @@ # # @target: The target iqn name # -# @lun: #optional LUN to connect to. Defaults to 0. +# @lun: LUN to connect to. Defaults to 0. # -# @user: #optional User name to log in with. If omitted, no CHAP +# @user: User name to log in with. If omitted, no CHAP # authentication is performed. # -# @password-secret: #optional The ID of a QCryptoSecret object providing +# @password-secret: The ID of a QCryptoSecret object providing # the password for the login. This option is required if # @user is specified. # -# @initiator-name: #optional The iqn name we want to identify to the target +# @initiator-name: The iqn name we want to identify to the target # as. If this option is not specified, an initiator name is # generated automatically. # -# @header-digest: #optional The desired header digest. Defaults to +# @header-digest: The desired header digest. Defaults to # none-crc32c. # -# @timeout: #optional Timeout in seconds after which a request will +# @timeout: Timeout in seconds after which a request will # timeout. 0 means no timeout and is the default. # # Driver specific block device options for iscsi @@ -2636,20 +2636,20 @@ # # @image: Image name in the Ceph pool. # -# @conf: #optional path to Ceph configuration file. Values +# @conf: path to Ceph configuration file. Values # in the configuration file will be overridden by # options specified via QAPI. # -# @snapshot: #optional Ceph snapshot name. +# @snapshot: Ceph snapshot name. # -# @user: #optional Ceph id name. +# @user: Ceph id name. # -# @server: #optional Monitor host address and port. This maps +# @server: Monitor host address and port. This maps # to the "mon_host" Ceph option. # -# @auth-supported: #optional Authentication supported. +# @auth-supported: Authentication supported. # -# @password-secret: #optional The ID of a QCryptoSecret object providing +# @password-secret: The ID of a QCryptoSecret object providing # the password for the login. # # Since: 2.9 @@ -2704,7 +2704,7 @@ # # @mode: the replication mode # -# @top-id: #optional In secondary mode, node name or device ID of the root +# @top-id: In secondary mode, node name or device ID of the root # node who owns the replication node chain. Must not be given in # primary mode. # @@ -2751,24 +2751,24 @@ # # @path: path of the image on the host # -# @user: #optional UID value to use when talking to the +# @user: UID value to use when talking to the # server (defaults to 65534 on Windows and getuid() # on unix) # -# @group: #optional GID value to use when talking to the +# @group: GID value to use when talking to the # server (defaults to 65534 on Windows and getgid() # in unix) # -# @tcp-syn-count: #optional number of SYNs during the session +# @tcp-syn-count: number of SYNs during the session # establishment (defaults to libnfs default) # -# @readahead-size: #optional set the readahead size in bytes (defaults +# @readahead-size: set the readahead size in bytes (defaults # to libnfs default) # -# @page-cache-size: #optional set the pagecache size in bytes (defaults +# @page-cache-size: set the pagecache size in bytes (defaults # to libnfs default) # -# @debug: #optional set the NFS debug level (max 2) (defaults +# @debug: set the NFS debug level (max 2) (defaults # to libnfs default) # # Since: 2.8 @@ -2802,9 +2802,9 @@ # # @server: NBD server address # -# @export: #optional export name +# @export: export name # -# @tls-creds: #optional TLS credentials ID +# @tls-creds: TLS credentials ID # # Since: 2.8 ## @@ -2818,8 +2818,8 @@ # # Driver specific block device options for the raw driver. # -# @offset: #optional position where the block device starts -# @size: #optional the assumed size of the device +# @offset: position where the block device starts +# @size: the assumed size of the device # # Since: 2.8 ## @@ -2834,13 +2834,13 @@ # block devices, independent of the block driver: # # @driver: block driver name -# @node-name: #optional the node name of the new node (Since 2.0). +# @node-name: the node name of the new node (Since 2.0). # This option is required on the top level of blockdev-add. -# @discard: #optional discard-related options (default: ignore) -# @cache: #optional cache-related options -# @read-only: #optional whether the block device should be read-only +# @discard: discard-related options (default: ignore) +# @cache: cache-related options +# @read-only: whether the block device should be read-only # (default: false) -# @detect-zeroes: #optional detect and optimize zero writes (Since 2.1) +# @detect-zeroes: detect and optimize zero writes (Since 2.1) # (default: off) # # Remaining options are determined by the block driver. @@ -3021,11 +3021,11 @@ # to it # - if the guest device does not have an actual tray # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # -# @force: #optional if false (the default), an eject request will be sent to +# @force: if false (the default), an eject request will be sent to # the guest if it has locked the tray (and the tray will not be opened # immediately); if true, the tray will be opened regardless of whether # it is locked @@ -3061,9 +3061,9 @@ # # If the tray was already closed before, this will be a no-op. # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # # Since: 2.5 # @@ -3095,9 +3095,9 @@ # # If the tray is open and there is no medium inserted, this will be a no-op. # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # # Note: This command is still a work in progress and is considered experimental. # Stay away from it unless you want to help with its development. @@ -3141,9 +3141,9 @@ # device's tray must currently be open (unless there is no attached guest # device) and there must be no medium inserted already. # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # # @node-name: name of a node in the block driver state graph # @@ -3202,17 +3202,17 @@ # combines blockdev-open-tray, x-blockdev-remove-medium, # x-blockdev-insert-medium and blockdev-close-tray). # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device +# @id: The name or QOM path of the guest device # (since: 2.8) # # @filename: filename of the new image to be loaded # -# @format: #optional format to open the new image with (defaults to +# @format: format to open the new image with (defaults to # the probed format) # -# @read-only-mode: #optional change the read-only mode of the device; defaults +# @read-only-mode: change the read-only mode of the device; defaults # to 'retain' # # Since: 2.5 @@ -3285,16 +3285,16 @@ # reasons, but it can be empty ("") if the image does not # have a device name associated. # -# @node-name: #optional node name (Since: 2.4) +# @node-name: node name (Since: 2.4) # # @msg: informative message for human consumption, such as the kind of # corruption being detected. It should not be parsed by machine as it is # not guaranteed to be stable # -# @offset: #optional if the corruption resulted from an image access, this is +# @offset: if the corruption resulted from an image access, this is # the host's access offset into the image # -# @size: #optional if the corruption resulted from an image access, this is +# @size: if the corruption resulted from an image access, this is # the access size # # @fatal: if set, the image is marked corrupt and therefore unusable after this @@ -3339,7 +3339,7 @@ # # @action: action that has been taken # -# @nospace: #optional true if I/O error was caused due to a no-space +# @nospace: true if I/O error was caused due to a no-space # condition. This key is only present if query-block's # io-status is present, please see query-block documentation # for more information (since: 2.2) @@ -3385,7 +3385,7 @@ # # @speed: rate limit, bytes per second # -# @error: #optional error message. Only present on failure. This field +# @error: error message. Only present on failure. This field # contains a human-readable error message. There are no semantics # other than that streaming has failed and clients should not try to # interpret the error string @@ -3594,9 +3594,9 @@ # # @parent: the id or name of the parent node. # -# @child: #optional the name of a child under the given parent node. +# @child: the name of a child under the given parent node. # -# @node: #optional the name of the node that will be added. +# @node: the name of the node that will be added. # # Note: this command is experimental, and its API is not stable. It # does not support all kinds of operations, all kinds of children, nor diff --git a/qapi/block.json b/qapi/block.json index 22da91441b..46fca0e1f3 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -163,11 +163,11 @@ # # Ejects a device from a removable drive. # -# @device: #optional Block device name (deprecated, use @id instead) +# @device: Block device name (deprecated, use @id instead) # -# @id: #optional The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device (since: 2.8) # -# @force: #optional If true, eject regardless of whether the drive is locked. +# @force: If true, eject regardless of whether the drive is locked. # If not specified, the default value is false. # # Returns: Nothing on success @@ -215,7 +215,7 @@ # @device: The device name or node name of the node to be exported # # @writable: Whether clients should be able to write to the device via the -# NBD connection (default false). #optional +# NBD connection (default false). # # Returns: error if the device is already marked for export. # diff --git a/qapi/crypto.json b/qapi/crypto.json index 93a04743ea..6b6fde367a 100644 --- a/qapi/crypto.json +++ b/qapi/crypto.json @@ -152,7 +152,7 @@ # # The options that apply to QCow/QCow2 AES-CBC encryption format # -# @key-secret: #optional the ID of a QCryptoSecret object providing the +# @key-secret: the ID of a QCryptoSecret object providing the # decryption key. Mandatory except when probing image for # metadata only. # @@ -166,7 +166,7 @@ # # The options that apply to LUKS encryption format # -# @key-secret: #optional the ID of a QCryptoSecret object providing the +# @key-secret: the ID of a QCryptoSecret object providing the # decryption key. Mandatory except when probing image for # metadata only. # Since: 2.6 @@ -180,17 +180,17 @@ # # The options that apply to LUKS encryption format initialization # -# @cipher-alg: #optional the cipher algorithm for data encryption +# @cipher-alg: the cipher algorithm for data encryption # Currently defaults to 'aes'. -# @cipher-mode: #optional the cipher mode for data encryption +# @cipher-mode: the cipher mode for data encryption # Currently defaults to 'cbc' -# @ivgen-alg: #optional the initialization vector generator +# @ivgen-alg: the initialization vector generator # Currently defaults to 'essiv' -# @ivgen-hash-alg: #optional the initialization vector generator hash +# @ivgen-hash-alg: the initialization vector generator hash # Currently defaults to 'sha256' -# @hash-alg: #optional the master key hash algorithm +# @hash-alg: the master key hash algorithm # Currently defaults to 'sha256' -# @iter-time: #optional number of milliseconds to spend in +# @iter-time: number of milliseconds to spend in # PBKDF passphrase processing. Currently defaults # to 2000. (since 2.8) # Since: 2.6 @@ -257,8 +257,8 @@ # # @active: whether the key slot is currently in use # @key-offset: offset to the key material in bytes -# @iters: #optional number of PBKDF2 iterations for key material -# @stripes: #optional number of stripes for splitting key material +# @iters: number of PBKDF2 iterations for key material +# @stripes: number of stripes for splitting key material # # Since: 2.7 ## @@ -277,7 +277,7 @@ # @cipher-alg: the cipher algorithm for data encryption # @cipher-mode: the cipher mode for data encryption # @ivgen-alg: the initialization vector generator -# @ivgen-hash-alg: #optional the initialization vector generator hash +# @ivgen-hash-alg: the initialization vector generator hash # @hash-alg: the master key hash algorithm # @payload-offset: offset to the payload data in bytes # @master-key-iters: number of PBKDF2 iterations for key material diff --git a/qapi/event.json b/qapi/event.json index e02852cd8a..e80f3f4446 100644 --- a/qapi/event.json +++ b/qapi/event.json @@ -186,7 +186,7 @@ # At this point, it's safe to reuse the specified device ID. Device removal can # be initiated by the guest or by HMP/QMP commands. # -# @device: #optional device name +# @device: device name # # @path: device path # @@ -209,7 +209,7 @@ # Emitted once until the 'query-rx-filter' command is executed, the first event # will always be emitted # -# @name: #optional net client name +# @name: net client name # # @path: device path # @@ -488,7 +488,7 @@ # # @action: action that has been taken, currently always "pause" # -# @info: #optional information about a panic (since 2.9) +# @info: information about a panic (since 2.9) # # Since: 1.5 # @@ -533,7 +533,7 @@ # # @type: quorum operation type (Since 2.6) # -# @error: #optional error message. Only present on failure. This field +# @error: error message. Only present on failure. This field # contains a human-readable error message. There are no semantics other # than that the block layer reported an error and clients should not # try to interpret the error string. @@ -620,7 +620,7 @@ # # @result: DumpQueryResult type described in qapi-schema.json. # -# @error: #optional human-readable error string that provides +# @error: human-readable error string that provides # hint on why dump failed. Only presents on failure. The # user should not try to interpret the error string. # diff --git a/qapi/introspect.json b/qapi/introspect.json index f6adc439bb..1dbaef56eb 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -163,10 +163,10 @@ # # @members: the object type's (non-variant) members, in no particular order. # -# @tag: #optional the name of the member serving as type tag. +# @tag: the name of the member serving as type tag. # An element of @members with this name must exist. # -# @variants: #optional variant members, i.e. additional members that +# @variants: variant members, i.e. additional members that # depend on the type tag's value. Present exactly when # @tag is present. The variants are in no particular order, # and may even differ from the order of the values of the @@ -190,7 +190,7 @@ # # @type: the name of the member's type. # -# @default: #optional default when used as command parameter. +# @default: default when used as command parameter. # If absent, the parameter is mandatory. # If present, the value must be null. The parameter is # optional, and behavior when it's missing is not specified diff --git a/qapi/rocker.json b/qapi/rocker.json index f374038c60..3587661161 100644 --- a/qapi/rocker.json +++ b/qapi/rocker.json @@ -121,23 +121,23 @@ # # @tbl-id: flow table ID # -# @in-pport: #optional physical input port +# @in-pport: physical input port # -# @tunnel-id: #optional tunnel ID +# @tunnel-id: tunnel ID # -# @vlan-id: #optional VLAN ID +# @vlan-id: VLAN ID # -# @eth-type: #optional Ethernet header type +# @eth-type: Ethernet header type # -# @eth-src: #optional Ethernet header source MAC address +# @eth-src: Ethernet header source MAC address # -# @eth-dst: #optional Ethernet header destination MAC address +# @eth-dst: Ethernet header destination MAC address # -# @ip-proto: #optional IP Header protocol field +# @ip-proto: IP Header protocol field # -# @ip-tos: #optional IP header TOS field +# @ip-tos: IP header TOS field # -# @ip-dst: #optional IP header destination address +# @ip-dst: IP header destination address # # Note: optional members may or may not appear in the flow key # depending if they're relevant to the flow key. @@ -155,19 +155,19 @@ # # Rocker switch OF-DPA flow mask # -# @in-pport: #optional physical input port +# @in-pport: physical input port # -# @tunnel-id: #optional tunnel ID +# @tunnel-id: tunnel ID # -# @vlan-id: #optional VLAN ID +# @vlan-id: VLAN ID # -# @eth-src: #optional Ethernet header source MAC address +# @eth-src: Ethernet header source MAC address # -# @eth-dst: #optional Ethernet header destination MAC address +# @eth-dst: Ethernet header destination MAC address # -# @ip-proto: #optional IP Header protocol field +# @ip-proto: IP Header protocol field # -# @ip-tos: #optional IP header TOS field +# @ip-tos: IP header TOS field # # Note: optional members may or may not appear in the flow mask # depending if they're relevant to the flow mask. @@ -184,17 +184,17 @@ # # Rocker switch OF-DPA flow action # -# @goto-tbl: #optional next table ID +# @goto-tbl: next table ID # -# @group-id: #optional group ID +# @group-id: group ID # -# @tunnel-lport: #optional tunnel logical port ID +# @tunnel-lport: tunnel logical port ID # -# @vlan-id: #optional VLAN ID +# @vlan-id: VLAN ID # -# @new-vlan-id: #optional new VLAN ID +# @new-vlan-id: new VLAN ID # -# @out-pport: #optional physical output port +# @out-pport: physical output port # # Note: optional members may or may not appear in the flow action # depending if they're relevant to the flow action. @@ -234,7 +234,7 @@ # # @name: switch name # -# @tbl-id: #optional flow table ID. If tbl-id is not specified, returns +# @tbl-id: flow table ID. If tbl-id is not specified, returns # flow information for all tables. # # Returns: rocker OF-DPA flow information @@ -268,27 +268,27 @@ # # @type: group type # -# @vlan-id: #optional VLAN ID +# @vlan-id: VLAN ID # -# @pport: #optional physical port number +# @pport: physical port number # -# @index: #optional group index, unique with group type +# @index: group index, unique with group type # -# @out-pport: #optional output physical port number +# @out-pport: output physical port number # -# @group-id: #optional next group ID +# @group-id: next group ID # -# @set-vlan-id: #optional VLAN ID to set +# @set-vlan-id: VLAN ID to set # -# @pop-vlan: #optional pop VLAN headr from packet +# @pop-vlan: pop VLAN headr from packet # -# @group-ids: #optional list of next group IDs +# @group-ids: list of next group IDs # -# @set-eth-src: #optional set source MAC address in Ethernet header +# @set-eth-src: set source MAC address in Ethernet header # -# @set-eth-dst: #optional set destination MAC address in Ethernet header +# @set-eth-dst: set destination MAC address in Ethernet header # -# @ttl-check: #optional perform TTL check +# @ttl-check: perform TTL check # # Note: optional members may or may not appear in the group depending # if they're relevant to the group type. @@ -310,7 +310,7 @@ # # @name: switch name # -# @type: #optional group type. If type is not specified, returns +# @type: group type. If type is not specified, returns # group information for all group types. # # Returns: rocker OF-DPA group information diff --git a/qapi/trace.json b/qapi/trace.json index 2bfda7ac7c..de6588d9f7 100644 --- a/qapi/trace.json +++ b/qapi/trace.json @@ -48,7 +48,7 @@ # Query the state of events. # # @name: Event name pattern (case-sensitive glob). -# @vcpu: #optional The vCPU to query (any by default; since 2.7). +# @vcpu: The vCPU to query (any by default; since 2.7). # # Returns: a list of @TraceEventInfo for the matching events # @@ -81,8 +81,8 @@ # # @name: Event name pattern (case-sensitive glob). # @enable: Whether to enable tracing. -# @ignore-unavailable: #optional Do not match unavailable events with @name. -# @vcpu: #optional The vCPU to act upon (all by default; since 2.7). +# @ignore-unavailable: Do not match unavailable events with @name. +# @vcpu: The vCPU to act upon (all by default; since 2.7). # # An event's state is modified if: # - its name matches the @name pattern, and diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index a8e4bdabc3..a02dbf2d18 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -144,7 +144,7 @@ # If that's the case users are advised to always pass a # value. # -# @time: #optional time of nanoseconds, relative to the Epoch +# @time: time of nanoseconds, relative to the Epoch # of 1970-01-01 in UTC. # # Returns: Nothing on success. @@ -203,7 +203,7 @@ # Initiate guest-activated shutdown. Note: this is an asynchronous # shutdown request, with no guarantee of successful shutdown. # -# @mode: #optional "halt", "powerdown" (default), or "reboot" +# @mode: "halt", "powerdown" (default), or "reboot" # # This command does NOT return a response on success. Success condition # is indicated by the VM exiting with a zero exit status or, when @@ -222,7 +222,7 @@ # # @path: Full path to the file in the guest to open. # -# @mode: #optional open mode, as per fopen(), "r" is the default. +# @mode: open mode, as per fopen(), "r" is the default. # # Returns: Guest file handle on success. # @@ -270,7 +270,7 @@ # # @handle: filehandle returned by guest-file-open # -# @count: #optional maximum number of bytes to read (default is 4KB) +# @count: maximum number of bytes to read (default is 4KB) # # Returns: @GuestFileRead on success. # @@ -304,7 +304,7 @@ # # @buf-b64: base64-encoded string representing data to be written # -# @count: #optional bytes to write (actual bytes, after base64-decode), +# @count: bytes to write (actual bytes, after base64-decode), # default is all content in buf-b64 buffer after base64 decoding # # Returns: @GuestFileWrite on success. @@ -441,7 +441,7 @@ # # Sync and freeze specified guest filesystems # -# @mountpoints: #optional an array of mountpoints of filesystems to be frozen. +# @mountpoints: an array of mountpoints of filesystems to be frozen. # If omitted, every mounted filesystem is frozen. # # Returns: Number of file systems currently frozen. On error, all filesystems @@ -670,7 +670,7 @@ # # @online: Whether the VCPU is enabled. # -# @can-offline: #optional Whether offlining the VCPU is possible. This member +# @can-offline: Whether offlining the VCPU is possible. This member # is always filled in by the guest agent when the structure is # returned, and always ignored on input (hence it can be omitted # then). @@ -858,7 +858,7 @@ # # @online: Whether the MEMORY BLOCK is enabled in guest. # -# @can-offline: #optional Whether offlining the MEMORY BLOCK is possible. +# @can-offline: Whether offlining the MEMORY BLOCK is possible. # This member is always filled in by the guest agent when the # structure is returned, and always ignored on input (hence it # can be omitted then). @@ -911,7 +911,7 @@ # # @response: the result of memory block operation. # -# @error-code: #optional the error number. +# @error-code: the error number. # When memory block operation fails, we assign the value of # 'errno' to this member, it indicates what goes wrong. # When the operation succeeds, it will be omitted. @@ -979,16 +979,16 @@ # @GuestExecStatus: # # @exited: true if process has already terminated. -# @exitcode: #optional process exit code if it was normally terminated. -# @signal: #optional signal number (linux) or unhandled exception code +# @exitcode: process exit code if it was normally terminated. +# @signal: signal number (linux) or unhandled exception code # (windows) if the process was abnormally terminated. -# @out-data: #optional base64-encoded stdout of the process -# @err-data: #optional base64-encoded stderr of the process +# @out-data: base64-encoded stdout of the process +# @err-data: base64-encoded stderr of the process # Note: @out-data and @err-data are present only # if 'capture-output' was specified for 'guest-exec' -# @out-truncated: #optional true if stdout was not fully captured +# @out-truncated: true if stdout was not fully captured # due to size limitation. -# @err-truncated: #optional true if stderr was not fully captured +# @err-truncated: true if stderr was not fully captured # due to size limitation. # # Since: 2.5 @@ -1028,10 +1028,10 @@ # Execute a command in the guest # # @path: path or executable name to execute -# @arg: #optional argument list to pass to executable -# @env: #optional environment variables to pass to executable -# @input-data: #optional data to be passed to process stdin (base64 encoded) -# @capture-output: #optional bool flag to enable capture of +# @arg: argument list to pass to executable +# @env: environment variables to pass to executable +# @input-data: data to be passed to process stdin (base64 encoded) +# @capture-output: bool flag to enable capture of # stdout/stderr of running process. defaults to false. # # Returns: PID on success. diff --git a/scripts/qapi.py b/scripts/qapi.py index f4c8eac8f6..748d7ad296 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -219,6 +219,10 @@ def _append_freeform(self, line): if (in_arg or not self.section.name or not self.section.name.startswith("Example")): line = line.strip() + # TODO Drop this once the dust has settled + if (isinstance(self.section, QAPIDoc.ArgSection) + and '#optional' in line): + raise QAPISemError(self.info, "Please drop the #optional tag") self.section.append(line) def connect_member(self, member): @@ -985,25 +989,6 @@ def check_definition_doc(doc, expr, info): or (meta == 'union' and not expr.get('discriminator'))): args.append('type') - for arg in args: - if arg[0] == '*': - opt = True - desc = doc.args.get(arg[1:]) - else: - opt = False - desc = doc.args.get(arg) - if not desc: - continue - desc.optional = opt - desc_opt = "#optional" in str(desc) - if desc_opt and not opt: - raise QAPISemError(info, "Description has #optional, " - "but the declaration doesn't") - if not desc_opt and opt: - # TODO either fix the schema and make this an error, - # or drop #optional entirely - pass - doc_args = set(doc.args.keys()) args = set([name.strip('*') for name in args]) if not doc_args.issubset(args): diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 6d4e75713d..45834777fc 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -145,8 +145,7 @@ def texi_members(doc, member_func, show_undocumented): for section in doc.args.itervalues(): if not section.content and not show_undocumented: continue # Undocumented TODO require doc and drop - desc = re.sub(r'^ *#optional *\n?|\n? *#optional *$|#optional', - '', str(section)) + desc = str(section) items += member_func(section.member) + texi_format(desc) + '\n' if not items: return '' diff --git a/tests/Makefile.include b/tests/Makefile.include index 3e640a846c..00b02fd19c 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -385,7 +385,6 @@ qapi-schema += doc-missing.json qapi-schema += doc-missing-colon.json qapi-schema += doc-missing-expr.json qapi-schema += doc-missing-space.json -qapi-schema += doc-optional.json qapi-schema += double-data.json qapi-schema += double-type.json qapi-schema += duplicate-key.json diff --git a/tests/qapi-schema/doc-optional.err b/tests/qapi-schema/doc-optional.err deleted file mode 100644 index 20d405af79..0000000000 --- a/tests/qapi-schema/doc-optional.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/doc-optional.json:3: Description has #optional, but the declaration doesn't diff --git a/tests/qapi-schema/doc-optional.exit b/tests/qapi-schema/doc-optional.exit deleted file mode 100644 index d00491fd7e..0000000000 --- a/tests/qapi-schema/doc-optional.exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/tests/qapi-schema/doc-optional.json b/tests/qapi-schema/doc-optional.json deleted file mode 100644 index 06c855ec94..0000000000 --- a/tests/qapi-schema/doc-optional.json +++ /dev/null @@ -1,7 +0,0 @@ -# Description #optional should match declaration - -## -# @foo: -# @a: a #optional -## -{ 'command': 'foo', 'data': {'a': 'int'} } diff --git a/tests/qapi-schema/doc-optional.out b/tests/qapi-schema/doc-optional.out deleted file mode 100644 index e69de29bb2..0000000000 From 0fe675af77e922f3901552be4ac0c454b7dad43d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:07 +0100 Subject: [PATCH 20/49] qapi: Use raw strings for regular expressions consistently Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-19-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 748d7ad296..8088f603a8 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -554,7 +554,7 @@ def discriminator_find_enum_define(expr): # Names must be letters, numbers, -, and _. They must start with letter, # except for downstream extensions which must start with __RFQDN_. # Dots are only valid in the downstream extension prefix. -valid_name = re.compile('^(__[a-zA-Z0-9.-]+_)?' +valid_name = re.compile(r'^(__[a-zA-Z0-9.-]+_)?' '[a-zA-Z][a-zA-Z0-9_-]*$') @@ -1831,10 +1831,10 @@ def cgen(code, **kwds): if indent_level: indent = genindent(indent_level) # re.subn() lacks flags support before Python 2.7, use re.compile() - raw = re.subn(re.compile("^.", re.MULTILINE), + raw = re.subn(re.compile(r'^.', re.MULTILINE), indent + r'\g<0>', raw) raw = raw[0] - return re.sub(re.escape(eatspace) + ' *', '', raw) + return re.sub(re.escape(eatspace) + r' *', '', raw) def mcgen(code, **kwds): @@ -1968,7 +1968,7 @@ def parse_command_line(extra_options="", extra_long_options=[]): for oa in opts: o, a = oa if o in ("-p", "--prefix"): - match = re.match('([A-Za-z_.-][A-Za-z0-9_.-]*)?', a) + match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', a) if match.end() != len(a): print >>sys.stderr, \ "%s: 'funny character '%s' in argument of --prefix" \ From ef801a9bb1e2cf276a8482c4ad1910f72de223f8 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:08 +0100 Subject: [PATCH 21/49] qapi: Prefer single-quoted strings more consistently PEP 8 advises: In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it. When a string contains single or double quote characters, however, use the other one to avoid backslashes in the string. It improves readability. The QAPI generators succeed at picking a rule, but fail at sticking to it. Convert a bunch of double-quoted strings to single-quoted ones. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-20-git-send-email-armbru@redhat.com> --- scripts/qapi-event.py | 2 +- scripts/qapi-introspect.py | 4 +- scripts/qapi-types.py | 4 +- scripts/qapi-visit.py | 4 +- scripts/qapi.py | 96 +++++++++++++++++++------------------- scripts/qapi2texi.py | 46 +++++++++--------- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py index f4eb7f85b1..0485e39145 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi-event.py @@ -223,7 +223,7 @@ def visit_event(self, name, info, arg_type, boxed): ''', prefix=prefix)) -event_enum_name = c_name(prefix + "QAPIEvent", protect=False) +event_enum_name = c_name(prefix + 'QAPIEvent', protect=False) schema = QAPISchema(input_file) gen = QAPISchemaGenEventVisitor() diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py index fb72c61d02..032bcea491 100644 --- a/scripts/qapi-introspect.py +++ b/scripts/qapi-introspect.py @@ -170,10 +170,10 @@ def visit_event(self, name, info, arg_type, boxed): opt_unmask = False (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line("u", ["unmask-non-abi-names"]) + parse_command_line('u', ['unmask-non-abi-names']) for o, a in opts: - if o in ("-u", "--unmask-non-abi-names"): + if o in ('-u', '--unmask-non-abi-names'): opt_unmask = True c_comment = ''' diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index dabc42e047..b45e7b5634 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -244,10 +244,10 @@ def visit_alternate_type(self, name, info, variants): do_builtins = False (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line("b", ["builtins"]) + parse_command_line('b', ['builtins']) for o, a in opts: - if o in ("-b", "--builtins"): + if o in ('-b', '--builtins'): do_builtins = True c_comment = ''' diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 330b9f321b..3d3936e4d0 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -335,10 +335,10 @@ def visit_alternate_type(self, name, info, variants): do_builtins = False (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line("b", ["builtins"]) + parse_command_line('b', ['builtins']) for o, a in opts: - if o in ("-b", "--builtins"): + if o in ('-b', '--builtins'): do_builtins = True c_comment = ''' diff --git a/scripts/qapi.py b/scripts/qapi.py index 8088f603a8..8b7377e51e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -58,9 +58,9 @@ def error_path(parent): - res = "" + res = '' while parent: - res = ("In file included from %s:%d:\n" % (parent['file'], + res = ('In file included from %s:%d:\n' % (parent['file'], parent['line'])) + res parent = parent['parent'] return res @@ -76,10 +76,10 @@ def __init__(self, fname, line, col, incl_info, msg): self.msg = msg def __str__(self): - loc = "%s:%d" % (self.fname, self.line) + loc = '%s:%d' % (self.fname, self.line) if self.col is not None: - loc += ":%s" % self.col - return error_path(self.info) + "%s: %s" % (loc, self.msg) + loc += ':%s' % self.col + return error_path(self.info) + '%s: %s' % (loc, self.msg) class QAPIParseError(QAPIError): @@ -113,7 +113,7 @@ def append(self, line): self.content.append(line) def __repr__(self): - return "\n".join(self.content).strip() + return '\n'.join(self.content).strip() class ArgSection(Section): def __init__(self, name): @@ -163,8 +163,8 @@ def append(self, line): # recognized, and get silently treated as ordinary text if self.symbol: self._append_symbol_line(line) - elif not self.body.content and line.startswith("@"): - if not line.endswith(":"): + elif not self.body.content and line.startswith('@'): + if not line.endswith(':'): raise QAPIParseError(self.parser, "Line should end with :") self.symbol = line[1:-1] # FIXME invalid names other than the empty string aren't flagged @@ -176,14 +176,14 @@ def append(self, line): def _append_symbol_line(self, line): name = line.split(' ', 1)[0] - if name.startswith("@") and name.endswith(":"): + if name.startswith('@') and name.endswith(':'): line = line[len(name)+1:] self._start_args_section(name[1:-1]) - elif name in ("Returns:", "Since:", + elif name in ('Returns:', 'Since:', # those are often singular or plural - "Note:", "Notes:", - "Example:", "Examples:", - "TODO:"): + 'Note:', 'Notes:', + 'Example:', 'Examples:', + 'TODO:'): line = line[len(name)+1:] self._start_section(name[:-1]) @@ -203,8 +203,8 @@ def _start_args_section(self, name): self.section = QAPIDoc.ArgSection(name) self.args[name] = self.section - def _start_section(self, name=""): - if name in ("Returns", "Since") and self.has_section(name): + def _start_section(self, name=''): + if name in ('Returns', 'Since') and self.has_section(name): raise QAPIParseError(self.parser, "Duplicated '%s' section" % name) self.section = QAPIDoc.Section(name) @@ -217,7 +217,7 @@ def _append_freeform(self, line): and line and not line[0].isspace()): self._start_section() if (in_arg or not self.section.name - or not self.section.name.startswith("Example")): + or not self.section.name.startswith('Example')): line = line.strip() # TODO Drop this once the dust has settled if (isinstance(self.section, QAPIDoc.ArgSection) @@ -262,7 +262,7 @@ def __init__(self, fp, previously_included=[], incl_info=None): if 'include' in expr: if len(expr) != 1: raise QAPISemError(info, "Invalid 'include' directive") - include = expr["include"] + include = expr['include'] if not isinstance(include, str): raise QAPISemError(info, "Value of 'include' must be a string") @@ -347,7 +347,7 @@ def accept(self, skip_comment=True): if not skip_comment: self.val = self.src[self.pos:self.cursor] return - elif self.tok in "{}:,[]": + elif self.tok in '{}:,[]': return elif self.tok == "'": string = '' @@ -373,7 +373,7 @@ def accept(self, skip_comment=True): for _ in range(0, 4): ch = self.src[self.cursor] self.cursor += 1 - if ch not in "0123456789abcdefABCDEF": + if ch not in '0123456789abcdefABCDEF': raise QAPIParseError(self, '\\u escape needs 4 ' 'hex digits') @@ -388,28 +388,28 @@ def accept(self, skip_comment=True): 'only supports non-zero ' 'values up to \\u007f') string += chr(value) - elif ch in "\\/'\"": + elif ch in '\\/\'"': string += ch else: raise QAPIParseError(self, "Unknown escape \\%s" % ch) esc = False - elif ch == "\\": + elif ch == '\\': esc = True elif ch == "'": self.val = string return else: string += ch - elif self.src.startswith("true", self.pos): + elif self.src.startswith('true', self.pos): self.val = True self.cursor += 3 return - elif self.src.startswith("false", self.pos): + elif self.src.startswith('false', self.pos): self.val = False self.cursor += 4 return - elif self.src.startswith("null", self.pos): + elif self.src.startswith('null', self.pos): self.val = None self.cursor += 3 return @@ -523,11 +523,11 @@ def find_alternate_member_qtype(qapi_type): if qapi_type in builtin_types: return builtin_types[qapi_type] elif find_struct(qapi_type): - return "QTYPE_QDICT" + return 'QTYPE_QDICT' elif find_enum(qapi_type): - return "QTYPE_QSTRING" + return 'QTYPE_QSTRING' elif find_union(qapi_type): - return "QTYPE_QDICT" + return 'QTYPE_QDICT' return None @@ -628,7 +628,7 @@ def find_union(name): def add_enum(name, info, enum_values=None, implicit=False): global enum_types add_name(name, info, 'enum', implicit) - enum_types.append({"enum_name": name, "enum_values": enum_values}) + enum_types.append({'enum_name': name, 'enum_values': enum_values}) def find_enum(name): @@ -788,7 +788,7 @@ def check_union(expr, info): raise QAPISemError(info, "Discriminator value '%s' is not found in " "enum '%s'" - % (key, enum_define["enum_name"])) + % (key, enum_define['enum_name'])) # If discriminator is user-defined, ensure all values are covered if enum_define: @@ -993,7 +993,7 @@ def check_definition_doc(doc, expr, info): args = set([name.strip('*') for name in args]) if not doc_args.issubset(args): raise QAPISemError(info, "The following documented members are not in " - "the declaration: %s" % ", ".join(doc_args - args)) + "the declaration: %s" % ', '.join(doc_args - args)) def check_docs(docs): @@ -1487,7 +1487,7 @@ def visit(self, visitor): class QAPISchema(object): def __init__(self, fname): try: - parser = QAPISchemaParser(open(fname, "r")) + parser = QAPISchemaParser(open(fname, 'r')) self.exprs = check_exprs(parser.exprs) self.docs = check_docs(parser.docs) self._entity_dict = {} @@ -1740,8 +1740,8 @@ def camel_to_upper(value): l = len(c_fun_str) for i in range(l): c = c_fun_str[i] - # When c is upper and no "_" appears before, do more checks - if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_": + # When c is upper and no '_' appears before, do more checks + if c.isupper() and (i > 0) and c_fun_str[i - 1] != '_': if i < l - 1 and c_fun_str[i + 1].islower(): new_name += '_' elif c_fun_str[i - 1].isdigit(): @@ -1760,7 +1760,7 @@ def c_enum_const(type_name, const_name, prefix=None): # Map @name to a valid C identifier. # If @protect, avoid returning certain ticklish identifiers (like -# C keywords) by prepending "q_". +# C keywords) by prepending 'q_'. # # Used for converting 'name' from a 'name':'type' qapi definition # into a generated struct member, as well as converting type names @@ -1798,7 +1798,7 @@ def c_name(name, protect=True): name = name.translate(c_name_trans) if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words): - return "q_" + name + return 'q_' + name return name eatspace = '\033EATSPACE.' @@ -1806,9 +1806,9 @@ def c_name(name, protect=True): def genindent(count): - ret = "" + ret = '' for _ in range(count): - ret += " " + ret += ' ' return ret indent_level = 0 @@ -1948,26 +1948,26 @@ def gen_params(arg_type, boxed, extra): # -def parse_command_line(extra_options="", extra_long_options=[]): +def parse_command_line(extra_options='', extra_long_options=[]): try: opts, args = getopt.gnu_getopt(sys.argv[1:], - "chp:o:" + extra_options, - ["source", "header", "prefix=", - "output-dir="] + extra_long_options) + 'chp:o:' + extra_options, + ['source', 'header', 'prefix=', + 'output-dir='] + extra_long_options) except getopt.GetoptError as err: print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err)) sys.exit(1) - output_dir = "" - prefix = "" + output_dir = '' + prefix = '' do_c = False do_h = False extra_opts = [] for oa in opts: o, a = oa - if o in ("-p", "--prefix"): + if o in ('-p', '--prefix'): match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', a) if match.end() != len(a): print >>sys.stderr, \ @@ -1975,11 +1975,11 @@ def parse_command_line(extra_options="", extra_long_options=[]): % (sys.argv[0], a[match.end()]) sys.exit(1) prefix = a - elif o in ("-o", "--output-dir"): - output_dir = a + "/" - elif o in ("-c", "--source"): + elif o in ('-o', '--output-dir'): + output_dir = a + '/' + elif o in ('-c', '--source'): do_c = True - elif o in ("-h", "--header"): + elif o in ('-h', '--header'): do_h = True else: extra_opts.append(oa) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 45834777fc..91cd59391a 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -50,7 +50,7 @@ def subst_vars(doc): def subst_braces(doc): """Replaces {} with @{ @}""" - return doc.replace("{", "@{").replace("}", "@}") + return doc.replace('{', '@{').replace('}', '@}') def texi_example(doc): @@ -79,10 +79,10 @@ def texi_format(doc): doc = subst_vars(doc) doc = subst_emph(doc) doc = subst_strong(doc) - inlist = "" + inlist = '' lastempty = False for line in doc.split('\n'): - empty = line == "" + empty = line == '' # FIXME: Doing this in a single if / elif chain is # problematic. For instance, a line without markup terminates @@ -92,35 +92,35 @@ def texi_format(doc): # # Make sure to update section "Documentation markup" in # docs/qapi-code-gen.txt when fixing this. - if line.startswith("| "): + if line.startswith('| '): line = EXAMPLE_FMT(code=line[2:]) - elif line.startswith("= "): - line = "@section " + line[2:] - elif line.startswith("== "): - line = "@subsection " + line[3:] + elif line.startswith('= '): + line = '@section ' + line[2:] + elif line.startswith('== '): + line = '@subsection ' + line[3:] elif re.match(r'^([0-9]*\.) ', line): if not inlist: - lines.append("@enumerate") - inlist = "enumerate" - line = line[line.find(" ")+1:] - lines.append("@item") + lines.append('@enumerate') + inlist = 'enumerate' + line = line[line.find(' ')+1:] + lines.append('@item') elif re.match(r'^[*-] ', line): if not inlist: - lines.append("@itemize %s" % {'*': "@bullet", - '-': "@minus"}[line[0]]) - inlist = "itemize" - lines.append("@item") + lines.append('@itemize %s' % {'*': '@bullet', + '-': '@minus'}[line[0]]) + inlist = 'itemize' + lines.append('@item') line = line[2:] elif lastempty and inlist: - lines.append("@end %s\n" % inlist) - inlist = "" + lines.append('@end %s\n' % inlist) + inlist = '' lastempty = empty lines.append(line) if inlist: - lines.append("@end %s\n" % inlist) - return "\n".join(lines) + lines.append('@end %s\n' % inlist) + return '\n'.join(lines) def texi_body(doc): @@ -158,12 +158,12 @@ def texi_sections(doc): for section in doc.sections: name, doc = (section.name, str(section)) func = texi_format - if name.startswith("Example"): + if name.startswith('Example'): func = texi_example if name: # prefer @b over @strong, so txt doesn't translate it to *Foo:* - body += "\n\n@b{%s:}\n" % name + body += '\n\n@b{%s:}\n' % name body += func(doc) return body @@ -269,5 +269,5 @@ def main(argv): print texi_schema(schema) -if __name__ == "__main__": +if __name__ == '__main__': main(sys.argv) From 71d918a1b191adaabd009910163f996289666ee7 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:09 +0100 Subject: [PATCH 22/49] qapi2texi: Plainer enum value and member name formatting Use @code{%s} instead of @code{'%s'}. Impact, using @id as example: * Texinfo -@item @code{'id'} +@item @code{id} * HTML -
'id'
+
id
* POD (for manual pages): -=item C<'id'> +=item C * Formatted manual pages: -'id' +"id" * Plain text: - ''id'' + 'id' Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-21-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 91cd59391a..ecfaeda89e 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -130,12 +130,12 @@ def texi_body(doc): def texi_enum_value(value): """Format a table of members item for an enumeration value""" - return "@item @code{'%s'}\n" % value.name + return '@item @code{%s}\n' % value.name def texi_member(member): """Format a table of members item for an object type member""" - return "@item @code{'%s'}%s\n" % ( + return '@item @code{%s}%s\n' % ( member.name, ' (optional)' if member.optional else '') From 2a1183ce9399657a896c51f388e6c7ca58f5d56d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:10 +0100 Subject: [PATCH 23/49] qapi2texi: Present the table of members more clearly The table of members follows the main descriptive text immediately. Makes it hard to see what it is about. Start a new paragraph, and lead with a line "Members:" for object and alternate types, "Values:" for enumeration types, and "Arguments:" for commands and events. Example change (qemu-qmp-ref.txt): -- Command: set_link Sets the link status of a virtual network adapter. + + Arguments: 'name' the device name of the virtual network adapter 'up' true to set the link status to be up Returns: Nothing on success If 'name' is not a valid network device, DeviceNotFound Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-22-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index ecfaeda89e..35e182d543 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -139,7 +139,7 @@ def texi_member(member): member.name, ' (optional)' if member.optional else '') -def texi_members(doc, member_func, show_undocumented): +def texi_members(doc, what, member_func, show_undocumented): """Format the table of members""" items = '' for section in doc.args.itervalues(): @@ -149,7 +149,7 @@ def texi_members(doc, member_func, show_undocumented): items += member_func(section.member) + texi_format(desc) + '\n' if not items: return '' - return '@table @asis\n' + items + '@end table\n' + return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items) def texi_sections(doc): @@ -169,9 +169,10 @@ def texi_sections(doc): return body -def texi_entity(doc, member_func=texi_member, show_undocumented=False): +def texi_entity(doc, what, member_func=texi_member, + show_undocumented=False): return (texi_body(doc) - + texi_members(doc, member_func, show_undocumented) + + texi_members(doc, what, member_func, show_undocumented) + texi_sections(doc)) @@ -189,7 +190,7 @@ def visit_enum_type(self, name, info, values, prefix): self.out += '\n' self.out += TYPE_FMT(type='Enum', name=doc.symbol, - body=texi_entity(doc, + body=texi_entity(doc, 'Values', member_func=texi_enum_value, show_undocumented=True)) @@ -205,7 +206,7 @@ def visit_object_type(self, name, info, base, members, variants): self.out += '\n' self.out += TYPE_FMT(type=typ, name=doc.symbol, - body=texi_entity(doc)) + body=texi_entity(doc, 'Members')) def visit_alternate_type(self, name, info, variants): doc = self.cur_doc @@ -213,7 +214,7 @@ def visit_alternate_type(self, name, info, variants): self.out += '\n' self.out += TYPE_FMT(type='Alternate', name=doc.symbol, - body=texi_entity(doc)) + body=texi_entity(doc, 'Members')) def visit_command(self, name, info, arg_type, ret_type, gen, success_response, boxed): @@ -222,7 +223,7 @@ def visit_command(self, name, info, arg_type, ret_type, self.out += '\n' self.out += MSG_FMT(type='Command', name=doc.symbol, - body=texi_entity(doc)) + body=texi_entity(doc, 'Arguments')) def visit_event(self, name, info, arg_type, boxed): doc = self.cur_doc @@ -230,7 +231,7 @@ def visit_event(self, name, info, arg_type, boxed): self.out += '\n' self.out += MSG_FMT(type='Event', name=doc.symbol, - body=texi_entity(doc)) + body=texi_entity(doc, 'Arguments')) def symbol(self, doc, entity): self.cur_doc = doc From 5da19f14ff3393dc84f0f84c50770affd2c10acf Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:11 +0100 Subject: [PATCH 24/49] qapi2texi: Explain enum value undocumentedness more clearly Instead of not saying anything when we have no documentation, say "Not documented". Example change (qemu-qmp-ref.txt): -- Enum: GuestPanicAction An enumeration of the actions taken when guest OS panic is detected Values: 'pause' system pauses 'poweroff' + Not documented Since: 2.1 (poweroff since 2.8) Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-23-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 35e182d543..1f01817be5 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -145,7 +145,10 @@ def texi_members(doc, what, member_func, show_undocumented): for section in doc.args.itervalues(): if not section.content and not show_undocumented: continue # Undocumented TODO require doc and drop - desc = str(section) + if section.content: + desc = str(section) + else: + desc = 'Not documented' items += member_func(section.member) + texi_format(desc) + '\n' if not items: return '' From 2c99f5fdc8a1e3decbb2c3bd99090ecb816a3d95 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:12 +0100 Subject: [PATCH 25/49] qapi2texi: Don't hide undocumented members and arguments Show undocumented object, alternate type members and command, event arguments exactly like undocumented enumeration type values. Example change (qemu-qmp-ref.txt): -- Command: query-rocker Return rocker switch information. + Arguments: + 'name' + Not documented + Returns: 'Rocker' information Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-24-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 1f01817be5..df874415e3 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -139,12 +139,10 @@ def texi_member(member): member.name, ' (optional)' if member.optional else '') -def texi_members(doc, what, member_func, show_undocumented): +def texi_members(doc, what, member_func): """Format the table of members""" items = '' for section in doc.args.itervalues(): - if not section.content and not show_undocumented: - continue # Undocumented TODO require doc and drop if section.content: desc = str(section) else: @@ -172,10 +170,9 @@ def texi_sections(doc): return body -def texi_entity(doc, what, member_func=texi_member, - show_undocumented=False): +def texi_entity(doc, what, member_func=texi_member): return (texi_body(doc) - + texi_members(doc, what, member_func, show_undocumented) + + texi_members(doc, what, member_func) + texi_sections(doc)) @@ -194,8 +191,7 @@ def visit_enum_type(self, name, info, values, prefix): self.out += TYPE_FMT(type='Enum', name=doc.symbol, body=texi_entity(doc, 'Values', - member_func=texi_enum_value, - show_undocumented=True)) + member_func=texi_enum_value)) def visit_object_type(self, name, info, base, members, variants): doc = self.cur_doc From c2dd311cb72b0ef59287aad3c0c7ee968c7289e2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:13 +0100 Subject: [PATCH 26/49] qapi2texi: Implement boxed argument documentation This replaces manual references like "For the arguments, see the documentation of ..." by a generated reference "Arguments: the members of ...". Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-25-git-send-email-armbru@redhat.com> --- qapi-schema.json | 2 +- qapi/block-core.json | 10 ---------- scripts/qapi2texi.py | 8 +++++++- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index d693033556..1d7b1cd1c7 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1017,7 +1017,7 @@ ## # @migrate-set-parameters: # -# Set various migration parameters. See MigrationParameters for details. +# Set various migration parameters. # # Since: 2.4 # diff --git a/qapi/block-core.json b/qapi/block-core.json index 1be1ec58ac..0f132fc995 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1341,8 +1341,6 @@ # The operation can be stopped before it has completed using the # block-job-cancel command. # -# For the arguments, see the documentation of DriveBackup. -# # Returns: nothing on success # If @device is not a valid block device, GenericError # @@ -1369,8 +1367,6 @@ # The operation can be stopped before it has completed using the # block-job-cancel command. # -# For the arguments, see the documentation of BlockdevBackup. -# # Returns: nothing on success # If @device is not a valid block device, DeviceNotFound # @@ -1458,8 +1454,6 @@ # format of the mirror image, default is to probe if mode='existing', # else the format of the source. # -# See DriveMirror for parameter descriptions -# # Returns: nothing on success # If @device is not a valid block device, GenericError # @@ -1731,8 +1725,6 @@ # the device will be removed from its group and the rest of its # members will not be affected. The 'group' parameter is ignored. # -# See BlockIOThrottle for parameter descriptions. -# # Returns: Nothing on success # If @device is not a valid block device, DeviceNotFound # @@ -2915,8 +2907,6 @@ # BlockBackend will be created; otherwise, @node-name is mandatory at the top # level and no BlockBackend will be created. # -# For the arguments, see the documentation of BlockdevOptions. -# # Note: This command is still a work in progress. It doesn't support all # block drivers among other things. Stay away from it unless you want # to help with its development. diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index df874415e3..3dd0146ba0 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -220,9 +220,15 @@ def visit_command(self, name, info, arg_type, ret_type, doc = self.cur_doc if self.out: self.out += '\n' + if boxed: + body = texi_body(doc) + body += '\n@b{Arguments:} the members of @code{%s}' % arg_type.name + body += texi_sections(doc) + else: + body = texi_entity(doc, 'Arguments') self.out += MSG_FMT(type='Command', name=doc.symbol, - body=texi_entity(doc, 'Arguments')) + body=body) def visit_event(self, name, info, arg_type, boxed): doc = self.cur_doc From 691e03133e79fd1f70ea4b524cdd10cbc23fd72a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:14 +0100 Subject: [PATCH 27/49] qapi2texi: Include member type in generated documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent merge of docs/qmp-commands.txt and docs/qmp-events.txt into the schema lost type information. Fix this documentation regression. Example change (qemu-qmp-ref.txt): -- Struct: InputKeyEvent Keyboard input event. Members: - 'button' + 'button: InputButton' Which button this event is for. - 'down' + 'down: boolean' True for key-down and false for key-up events. Since: 2.0 Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Reviewed-by: Eric Blake Message-Id: <1489582656-31133-26-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 14 ++++++++++++++ scripts/qapi2texi.py | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 8b7377e51e..21a15918dc 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1105,6 +1105,11 @@ def alternate_qtype(self): } return json2qtype.get(self.json_type()) + def doc_type(self): + if self.is_implicit(): + return None + return self.name + class QAPISchemaBuiltinType(QAPISchemaType): def __init__(self, name, json_type, c_type): @@ -1129,6 +1134,9 @@ def c_param_type(self): def json_type(self): return self._json_type_name + def doc_type(self): + return self.json_type() + def visit(self, visitor): visitor.visit_builtin_type(self.name, self.info, self.json_type()) @@ -1188,6 +1196,12 @@ def c_type(self): def json_type(self): return 'array' + def doc_type(self): + elt_doc_type = self.element_type.doc_type() + if not elt_doc_type: + return None + return 'array of ' + elt_doc_type + def visit(self, visitor): visitor.visit_array_type(self.name, self.info, self.element_type) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 3dd0146ba0..993b65264f 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -135,8 +135,12 @@ def texi_enum_value(value): def texi_member(member): """Format a table of members item for an object type member""" - return '@item @code{%s}%s\n' % ( - member.name, ' (optional)' if member.optional else '') + typ = member.type.doc_type() + return '@item @code{%s%s%s}%s\n' % ( + member.name, + ': ' if typ else '', + typ if typ else '', + ' (optional)' if member.optional else '') def texi_members(doc, what, member_func): From 88f63467c5753ec49ea8e7134c6b4b59c03d73b2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:15 +0100 Subject: [PATCH 28/49] qapi2texi: Generate reference to base type members The generated documentation doesn't mention object type members inherited from a base type. Fix that. Example change (qemu-qmp-ref.txt): -- Struct: VncServerInfo The network connection information for server Members: 'auth' (optional) authentication method used for the plain (non-websocket) VNC server + The members of 'VncBasicInfo' Since: 2.1 Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-27-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 993b65264f..7083d0c0d0 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -143,7 +143,7 @@ def texi_member(member): ' (optional)' if member.optional else '') -def texi_members(doc, what, member_func): +def texi_members(doc, what, base, member_func): """Format the table of members""" items = '' for section in doc.args.itervalues(): @@ -152,6 +152,8 @@ def texi_members(doc, what, member_func): else: desc = 'Not documented' items += member_func(section.member) + texi_format(desc) + '\n' + if base: + items += '@item The members of @code{%s}\n' % base.doc_type() if not items: return '' return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items) @@ -174,9 +176,9 @@ def texi_sections(doc): return body -def texi_entity(doc, what, member_func=texi_member): +def texi_entity(doc, what, base=None, member_func=texi_member): return (texi_body(doc) - + texi_members(doc, what, member_func) + + texi_members(doc, what, base, member_func) + texi_sections(doc)) @@ -205,11 +207,13 @@ def visit_object_type(self, name, info, base, members, variants): typ = 'Flat Union' else: typ = 'Simple Union' + if base and base.is_implicit(): + base = None if self.out: self.out += '\n' self.out += TYPE_FMT(type=typ, name=doc.symbol, - body=texi_entity(doc, 'Members')) + body=texi_entity(doc, 'Members', base)) def visit_alternate_type(self, name, info, variants): doc = self.cur_doc From 5169cd87673b99be8c017b1969583f0c729917d9 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:16 +0100 Subject: [PATCH 29/49] qapi2texi: Generate documentation for variant members A flat union's branch brings in the members of another type. Generate a suitable reference to that type. Example change (qemu-qmp-ref.txt): -- Flat Union: QCryptoBlockOpenOptions The options that are available for all encryption formats when opening an existing volume Members: The members of 'QCryptoBlockOptionsBase' + The members of 'QCryptoBlockOptionsQCow' when 'format' is "qcow" + The members of 'QCryptoBlockOptionsLUKS' when 'format' is "luks" Since: 2.6 A simple union's branch adds a member 'data' of some other type. Generate documentation for that member. Example change (qemu-qmp-ref.txt): -- Simple Union: SocketAddress Captures the address of a socket, which could also be a named file descriptor Members: 'type' Not documented + 'data: InetSocketAddress' when 'type' is "inet" + 'data: UnixSocketAddress' when 'type' is "unix" + 'data: VsockSocketAddress' when 'type' is "vsock" + 'data: String' when 'type' is "fd" Since: 1.3 Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-28-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 7083d0c0d0..ab6b6cda25 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -133,17 +133,18 @@ def texi_enum_value(value): return '@item @code{%s}\n' % value.name -def texi_member(member): +def texi_member(member, suffix=''): """Format a table of members item for an object type member""" typ = member.type.doc_type() - return '@item @code{%s%s%s}%s\n' % ( + return '@item @code{%s%s%s}%s%s\n' % ( member.name, ': ' if typ else '', typ if typ else '', - ' (optional)' if member.optional else '') + ' (optional)' if member.optional else '', + suffix) -def texi_members(doc, what, base, member_func): +def texi_members(doc, what, base, variants, member_func): """Format the table of members""" items = '' for section in doc.args.itervalues(): @@ -154,6 +155,17 @@ def texi_members(doc, what, base, member_func): items += member_func(section.member) + texi_format(desc) + '\n' if base: items += '@item The members of @code{%s}\n' % base.doc_type() + if variants: + for v in variants.variants: + when = ' when @code{%s} is @t{"%s"}' % ( + variants.tag_member.name, v.name) + if v.type.is_implicit(): + assert not v.type.base and not v.type.variants + for m in v.type.local_members: + items += member_func(m, when) + else: + items += '@item The members of @code{%s}%s\n' % ( + v.type.doc_type(), when) if not items: return '' return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items) @@ -176,9 +188,10 @@ def texi_sections(doc): return body -def texi_entity(doc, what, base=None, member_func=texi_member): +def texi_entity(doc, what, base=None, variants=None, + member_func=texi_member): return (texi_body(doc) - + texi_members(doc, what, base, member_func) + + texi_members(doc, what, base, variants, member_func) + texi_sections(doc)) @@ -213,7 +226,7 @@ def visit_object_type(self, name, info, base, members, variants): self.out += '\n' self.out += TYPE_FMT(type=typ, name=doc.symbol, - body=texi_entity(doc, 'Members', base)) + body=texi_entity(doc, 'Members', base, variants)) def visit_alternate_type(self, name, info, variants): doc = self.cur_doc From c19eaa64df7be01f060e04c0f13bba5de549c3f3 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:17 +0100 Subject: [PATCH 30/49] qapi2texi: Generate descriptions for simple union tags Simple union tags carry no type information, because their type is implicit. Their description should make up for it, but many have none. Generate one automatically then. Example change (qemu-qmp-ref.txt): -- Simple Union: ImageInfoSpecific A discriminated record of image format specific information structures. Members: 'type' - Not documented + One of "qcow2", "vmdk", "luks" 'data: ImageInfoSpecificQCow2' when 'type' is "qcow2" 'data: ImageInfoSpecificVmdk' when 'type' is "vmdk" 'data: QCryptoBlockInfoLUKS' when 'type' is "luks" Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-29-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index ab6b6cda25..282adf46dc 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -148,11 +148,16 @@ def texi_members(doc, what, base, variants, member_func): """Format the table of members""" items = '' for section in doc.args.itervalues(): + # TODO Drop fallbacks when undocumented members are outlawed if section.content: - desc = str(section) + desc = texi_format(str(section)) + elif (variants and variants.tag_member == section.member + and not section.member.type.doc_type()): + values = section.member.type.member_names() + desc = 'One of ' + ', '.join(['@t{"%s"}' % v for v in values]) else: desc = 'Not documented' - items += member_func(section.member) + texi_format(desc) + '\n' + items += member_func(section.member) + desc + '\n' if base: items += '@item The members of @code{%s}\n' % base.doc_type() if variants: From 75b50196d9eee43f0b7d006455b9735ea5c3c333 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:18 +0100 Subject: [PATCH 31/49] qapi2texi: Use category "Object" for all object types At the protocol level, the distinction between struct, flat union and simple union is meaningless, they are all JSON objects. Document them that way. Example change (qemu-qmp-ref.txt): - -- Simple Union: InputEvent + -- Object: InputEvent Input event union. This also fixes the completely broken headings for flat and simple unions in qemu-qmp-ref.7 and qemu-ga-ref.7, by sidestepping a bug in texi2pod.pl. For instance, it mistranslates "@deftp {Simple Union} InputEvent" to "B (Simple)", but translates "@deftp Object InputEvent" to "B (Object)". Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-30-git-send-email-armbru@redhat.com> --- scripts/qapi2texi.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py index 282adf46dc..8eed11a60c 100755 --- a/scripts/qapi2texi.py +++ b/scripts/qapi2texi.py @@ -219,17 +219,11 @@ def visit_enum_type(self, name, info, values, prefix): def visit_object_type(self, name, info, base, members, variants): doc = self.cur_doc - if not variants: - typ = 'Struct' - elif variants._tag_name: # TODO unclean member access - typ = 'Flat Union' - else: - typ = 'Simple Union' if base and base.is_implicit(): base = None if self.out: self.out += '\n' - self.out += TYPE_FMT(type=typ, + self.out += TYPE_FMT(type='Object', name=doc.symbol, body=texi_entity(doc, 'Members', base, variants)) From 2028be8eeaa5334ce63fbf625942c6d52c6dac28 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:19 +0100 Subject: [PATCH 32/49] tests/qapi-schema: Improve doc / expression mismatch coverage New tests doc-before-include.json and doc-before-pragma.json show we fail to reject a misplaced expression comment. New test doc-no-symbol.json shows a bad error message. Signed-off-by: Markus Armbruster Message-Id: <1489582656-31133-31-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake --- tests/Makefile.include | 3 +++ tests/qapi-schema/doc-before-include.err | 0 tests/qapi-schema/doc-before-include.exit | 1 + tests/qapi-schema/doc-before-include.json | 8 ++++++++ tests/qapi-schema/doc-before-include.out | 4 ++++ tests/qapi-schema/doc-before-pragma.err | 0 tests/qapi-schema/doc-before-pragma.exit | 1 + tests/qapi-schema/doc-before-pragma.json | 8 ++++++++ tests/qapi-schema/doc-before-pragma.out | 4 ++++ tests/qapi-schema/doc-no-symbol.err | 1 + tests/qapi-schema/doc-no-symbol.exit | 1 + tests/qapi-schema/doc-no-symbol.json | 7 +++++++ tests/qapi-schema/doc-no-symbol.out | 0 13 files changed, 38 insertions(+) create mode 100644 tests/qapi-schema/doc-before-include.err create mode 100644 tests/qapi-schema/doc-before-include.exit create mode 100644 tests/qapi-schema/doc-before-include.json create mode 100644 tests/qapi-schema/doc-before-include.out create mode 100644 tests/qapi-schema/doc-before-pragma.err create mode 100644 tests/qapi-schema/doc-before-pragma.exit create mode 100644 tests/qapi-schema/doc-before-pragma.json create mode 100644 tests/qapi-schema/doc-before-pragma.out create mode 100644 tests/qapi-schema/doc-no-symbol.err create mode 100644 tests/qapi-schema/doc-no-symbol.exit create mode 100644 tests/qapi-schema/doc-no-symbol.json create mode 100644 tests/qapi-schema/doc-no-symbol.out diff --git a/tests/Makefile.include b/tests/Makefile.include index 00b02fd19c..505f918404 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -369,6 +369,8 @@ qapi-schema += command-int.json qapi-schema += comments.json qapi-schema += doc-bad-args.json qapi-schema += doc-bad-symbol.json +qapi-schema += doc-before-include.json +qapi-schema += doc-before-pragma.json qapi-schema += doc-duplicated-arg.json qapi-schema += doc-duplicated-return.json qapi-schema += doc-duplicated-since.json @@ -385,6 +387,7 @@ qapi-schema += doc-missing.json qapi-schema += doc-missing-colon.json qapi-schema += doc-missing-expr.json qapi-schema += doc-missing-space.json +qapi-schema += doc-no-symbol.json qapi-schema += double-data.json qapi-schema += double-type.json qapi-schema += duplicate-key.json diff --git a/tests/qapi-schema/doc-before-include.err b/tests/qapi-schema/doc-before-include.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/doc-before-include.exit b/tests/qapi-schema/doc-before-include.exit new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/tests/qapi-schema/doc-before-include.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/doc-before-include.json b/tests/qapi-schema/doc-before-include.json new file mode 100644 index 0000000000..ec1fbf275f --- /dev/null +++ b/tests/qapi-schema/doc-before-include.json @@ -0,0 +1,8 @@ +# Doc comment separated from defining expression by non-defining expression +# BUG: not rejected + +## +# @foo: +## +{ 'include': 'empty.json' } +{ 'struct': 'foo', 'data': {} } diff --git a/tests/qapi-schema/doc-before-include.out b/tests/qapi-schema/doc-before-include.out new file mode 100644 index 0000000000..236a849d48 --- /dev/null +++ b/tests/qapi-schema/doc-before-include.out @@ -0,0 +1,4 @@ +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE +object foo +object q_empty diff --git a/tests/qapi-schema/doc-before-pragma.err b/tests/qapi-schema/doc-before-pragma.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/doc-before-pragma.exit b/tests/qapi-schema/doc-before-pragma.exit new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/tests/qapi-schema/doc-before-pragma.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/doc-before-pragma.json b/tests/qapi-schema/doc-before-pragma.json new file mode 100644 index 0000000000..fb2ec8e3fb --- /dev/null +++ b/tests/qapi-schema/doc-before-pragma.json @@ -0,0 +1,8 @@ +# Doc comment separated from defining expression by non-defining expression +# BUG: not rejected + +## +# @foo: +## +{ 'pragma': {} } +{ 'struct': 'foo', 'data': {} } diff --git a/tests/qapi-schema/doc-before-pragma.out b/tests/qapi-schema/doc-before-pragma.out new file mode 100644 index 0000000000..236a849d48 --- /dev/null +++ b/tests/qapi-schema/doc-before-pragma.out @@ -0,0 +1,4 @@ +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE +object foo +object q_empty diff --git a/tests/qapi-schema/doc-no-symbol.err b/tests/qapi-schema/doc-no-symbol.err new file mode 100644 index 0000000000..727966cc0c --- /dev/null +++ b/tests/qapi-schema/doc-no-symbol.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-no-symbol.json:4: Definition of 'foo' follows documentation for 'None' diff --git a/tests/qapi-schema/doc-no-symbol.exit b/tests/qapi-schema/doc-no-symbol.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/doc-no-symbol.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/doc-no-symbol.json b/tests/qapi-schema/doc-no-symbol.json new file mode 100644 index 0000000000..ee86ca184b --- /dev/null +++ b/tests/qapi-schema/doc-no-symbol.json @@ -0,0 +1,7 @@ +# Documentation for expression lacks symbol +# BUG: Error message claims it has symbol 'None' + +## +# foo: +## +{ 'command': 'foo', 'data': {'a': 'int'} } diff --git a/tests/qapi-schema/doc-no-symbol.out b/tests/qapi-schema/doc-no-symbol.out new file mode 100644 index 0000000000..e69de29bb2 From e7823a2adf7222d0513b8e7cfd8af85d407d4918 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:20 +0100 Subject: [PATCH 33/49] qapi: Fix detection of doc / expression mismatch This fixes the errors uncovered by the previous commit. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-32-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 35 ++++++++++++++--------- tests/qapi-schema/doc-before-include.err | 1 + tests/qapi-schema/doc-before-include.exit | 2 +- tests/qapi-schema/doc-before-include.json | 1 - tests/qapi-schema/doc-before-include.out | 4 --- tests/qapi-schema/doc-before-pragma.err | 1 + tests/qapi-schema/doc-before-pragma.exit | 2 +- tests/qapi-schema/doc-before-pragma.json | 1 - tests/qapi-schema/doc-before-pragma.out | 4 --- tests/qapi-schema/doc-missing-expr.err | 2 +- tests/qapi-schema/doc-no-symbol.err | 2 +- tests/qapi-schema/doc-no-symbol.json | 1 - 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 21a15918dc..37f28146eb 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -248,18 +248,21 @@ def __init__(self, fp, previously_included=[], incl_info=None): self.line_pos = 0 self.exprs = [] self.docs = [] + self.cur_doc = None self.accept() while self.tok is not None: info = {'file': fname, 'line': self.line, 'parent': self.incl_info} if self.tok == '#': - doc = self.get_doc(info) - self.docs.append(doc) + self.reject_expr_doc() + self.cur_doc = self.get_doc(info) + self.docs.append(self.cur_doc) continue expr = self.get_expr(False) if 'include' in expr: + self.reject_expr_doc() if len(expr) != 1: raise QAPISemError(info, "Invalid 'include' directive") include = expr['include'] @@ -269,6 +272,7 @@ def __init__(self, fp, previously_included=[], incl_info=None): self._include(include, info, os.path.dirname(abs_fname), previously_included) elif "pragma" in expr: + self.reject_expr_doc() if len(expr) != 1: raise QAPISemError(info, "Invalid 'pragma' directive") pragma = expr['pragma'] @@ -280,13 +284,23 @@ def __init__(self, fp, previously_included=[], incl_info=None): else: expr_elem = {'expr': expr, 'info': info} - if (self.docs - and self.docs[-1].info['file'] == fname - and not self.docs[-1].expr): - self.docs[-1].expr = expr - expr_elem['doc'] = self.docs[-1] - + if self.cur_doc: + if not self.cur_doc.symbol: + raise QAPISemError( + self.cur_doc.info, + "Expression documentation required") + self.cur_doc.expr = expr + expr_elem['doc'] = self.cur_doc self.exprs.append(expr_elem) + self.cur_doc = None + self.reject_expr_doc() + + def reject_expr_doc(self): + if self.cur_doc and self.cur_doc.symbol: + raise QAPISemError( + self.cur_doc.info, + "Documentation for '%s' is not followed by the definition" + % self.cur_doc.symbol) def _include(self, include, info, base_dir, previously_included): incl_abs_fname = os.path.join(base_dir, include) @@ -950,11 +964,6 @@ def check_exprs(exprs): def check_freeform_doc(doc): - if doc.symbol: - raise QAPISemError(doc.info, - "Documention for '%s' is not followed" - " by the definition" % doc.symbol) - body = str(doc.body) if re.search(r'@\S+:', body, re.MULTILINE): raise QAPISemError(doc.info, diff --git a/tests/qapi-schema/doc-before-include.err b/tests/qapi-schema/doc-before-include.err index e69de29bb2..a649d38a63 100644 --- a/tests/qapi-schema/doc-before-include.err +++ b/tests/qapi-schema/doc-before-include.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-before-include.json:3: Documentation for 'foo' is not followed by the definition diff --git a/tests/qapi-schema/doc-before-include.exit b/tests/qapi-schema/doc-before-include.exit index 573541ac97..d00491fd7e 100644 --- a/tests/qapi-schema/doc-before-include.exit +++ b/tests/qapi-schema/doc-before-include.exit @@ -1 +1 @@ -0 +1 diff --git a/tests/qapi-schema/doc-before-include.json b/tests/qapi-schema/doc-before-include.json index ec1fbf275f..0caa0ae079 100644 --- a/tests/qapi-schema/doc-before-include.json +++ b/tests/qapi-schema/doc-before-include.json @@ -1,5 +1,4 @@ # Doc comment separated from defining expression by non-defining expression -# BUG: not rejected ## # @foo: diff --git a/tests/qapi-schema/doc-before-include.out b/tests/qapi-schema/doc-before-include.out index 236a849d48..e69de29bb2 100644 --- a/tests/qapi-schema/doc-before-include.out +++ b/tests/qapi-schema/doc-before-include.out @@ -1,4 +0,0 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] - prefix QTYPE -object foo -object q_empty diff --git a/tests/qapi-schema/doc-before-pragma.err b/tests/qapi-schema/doc-before-pragma.err index e69de29bb2..c0fb0660d1 100644 --- a/tests/qapi-schema/doc-before-pragma.err +++ b/tests/qapi-schema/doc-before-pragma.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-before-pragma.json:3: Documentation for 'foo' is not followed by the definition diff --git a/tests/qapi-schema/doc-before-pragma.exit b/tests/qapi-schema/doc-before-pragma.exit index 573541ac97..d00491fd7e 100644 --- a/tests/qapi-schema/doc-before-pragma.exit +++ b/tests/qapi-schema/doc-before-pragma.exit @@ -1 +1 @@ -0 +1 diff --git a/tests/qapi-schema/doc-before-pragma.json b/tests/qapi-schema/doc-before-pragma.json index fb2ec8e3fb..a6e090e44a 100644 --- a/tests/qapi-schema/doc-before-pragma.json +++ b/tests/qapi-schema/doc-before-pragma.json @@ -1,5 +1,4 @@ # Doc comment separated from defining expression by non-defining expression -# BUG: not rejected ## # @foo: diff --git a/tests/qapi-schema/doc-before-pragma.out b/tests/qapi-schema/doc-before-pragma.out index 236a849d48..e69de29bb2 100644 --- a/tests/qapi-schema/doc-before-pragma.out +++ b/tests/qapi-schema/doc-before-pragma.out @@ -1,4 +0,0 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] - prefix QTYPE -object foo -object q_empty diff --git a/tests/qapi-schema/doc-missing-expr.err b/tests/qapi-schema/doc-missing-expr.err index c0e687cadd..c909e26eca 100644 --- a/tests/qapi-schema/doc-missing-expr.err +++ b/tests/qapi-schema/doc-missing-expr.err @@ -1 +1 @@ -tests/qapi-schema/doc-missing-expr.json:3: Documention for 'bar' is not followed by the definition +tests/qapi-schema/doc-missing-expr.json:3: Documentation for 'bar' is not followed by the definition diff --git a/tests/qapi-schema/doc-no-symbol.err b/tests/qapi-schema/doc-no-symbol.err index 727966cc0c..75f032a942 100644 --- a/tests/qapi-schema/doc-no-symbol.err +++ b/tests/qapi-schema/doc-no-symbol.err @@ -1 +1 @@ -tests/qapi-schema/doc-no-symbol.json:4: Definition of 'foo' follows documentation for 'None' +tests/qapi-schema/doc-no-symbol.json:3: Expression documentation required diff --git a/tests/qapi-schema/doc-no-symbol.json b/tests/qapi-schema/doc-no-symbol.json index ee86ca184b..98605bab96 100644 --- a/tests/qapi-schema/doc-no-symbol.json +++ b/tests/qapi-schema/doc-no-symbol.json @@ -1,5 +1,4 @@ # Documentation for expression lacks symbol -# BUG: Error message claims it has symbol 'None' ## # foo: From 7947016d1ceb08584f0d0a3f62b8049ab27219ba Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:21 +0100 Subject: [PATCH 34/49] qapi: Move detection of doc / expression name mismatch Move the check whether the doc matches the expression name from check_definition_doc() to check_exprs(). This changes the error location from the comment to the expression. Makes sense as the message talks about the expression: "Definition of '%s' follows documentation for '%s'". It's also a step towards getting rid of check_docs(). Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-33-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 28 ++++++++++++++++++---------- tests/qapi-schema/doc-bad-symbol.err | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 37f28146eb..9a1d830f2f 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -894,40 +894,52 @@ def check_keys(expr_elem, meta, required, optional=[]): def check_exprs(exprs): global all_names - # Learn the types and check for valid expression keys + # Populate name table with names of built-in types for builtin in builtin_types.keys(): all_names[builtin] = 'built-in' + + # Learn the types and check for valid expression keys for expr_elem in exprs: expr = expr_elem['expr'] info = expr_elem['info'] + doc = expr_elem.get('doc') - if 'doc' not in expr_elem and doc_required: + if not doc and doc_required: raise QAPISemError(info, "Expression missing documentation comment") if 'enum' in expr: + name = expr['enum'] check_keys(expr_elem, 'enum', ['data'], ['prefix']) - add_enum(expr['enum'], info, expr['data']) + add_enum(name, info, expr['data']) elif 'union' in expr: + name = expr['union'] check_keys(expr_elem, 'union', ['data'], ['base', 'discriminator']) add_union(expr, info) elif 'alternate' in expr: + name = expr['alternate'] check_keys(expr_elem, 'alternate', ['data']) - add_name(expr['alternate'], info, 'alternate') + add_name(name, info, 'alternate') elif 'struct' in expr: + name = expr['struct'] check_keys(expr_elem, 'struct', ['data'], ['base']) add_struct(expr, info) elif 'command' in expr: + name = expr['command'] check_keys(expr_elem, 'command', [], ['data', 'returns', 'gen', 'success-response', 'boxed']) - add_name(expr['command'], info, 'command') + add_name(name, info, 'command') elif 'event' in expr: + name = expr['event'] check_keys(expr_elem, 'event', [], ['data', 'boxed']) - add_name(expr['event'], info, 'event') + add_name(name, info, 'event') else: raise QAPISemError(expr_elem['info'], "Expression is missing metatype") + if doc and doc.symbol != name: + raise QAPISemError(info, "Definition of '%s' follows documentation" + " for '%s'" % (name, doc.symbol)) # Try again for hidden UnionKind enum for expr_elem in exprs: @@ -977,10 +989,6 @@ def check_definition_doc(doc, expr, info): meta = i break - name = expr[meta] - if doc.symbol != name: - raise QAPISemError(info, "Definition of '%s' follows documentation" - " for '%s'" % (name, doc.symbol)) if doc.has_section('Returns') and 'command' not in expr: raise QAPISemError(info, "'Returns:' is only valid for commands") diff --git a/tests/qapi-schema/doc-bad-symbol.err b/tests/qapi-schema/doc-bad-symbol.err index ac4e5667cb..8472030c79 100644 --- a/tests/qapi-schema/doc-bad-symbol.err +++ b/tests/qapi-schema/doc-bad-symbol.err @@ -1 +1 @@ -tests/qapi-schema/doc-bad-symbol.json:3: Definition of 'foo' follows documentation for 'food' +tests/qapi-schema/doc-bad-symbol.json:6: Definition of 'foo' follows documentation for 'food' From 2d433236df5ab15d61a117c3d8e47a4abc651ce0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:22 +0100 Subject: [PATCH 35/49] qapi: Improve error message on @NAME: in free-form doc Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-34-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 17 ++++++----------- tests/qapi-schema/doc-invalid-section.err | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 9a1d830f2f..4edcea1883 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -219,6 +219,11 @@ def _append_freeform(self, line): if (in_arg or not self.section.name or not self.section.name.startswith('Example')): line = line.strip() + match = re.match(r'(@\S+:)', line) + if match: + raise QAPIParseError(self.parser, + "'%s' not allowed in free-form documentation" + % match.group(1)) # TODO Drop this once the dust has settled if (isinstance(self.section, QAPIDoc.ArgSection) and '#optional' in line): @@ -975,14 +980,6 @@ def check_exprs(exprs): return exprs -def check_freeform_doc(doc): - body = str(doc.body) - if re.search(r'@\S+:', body, re.MULTILINE): - raise QAPISemError(doc.info, - "Free-form documentation block must not contain" - " @NAME: sections") - - def check_definition_doc(doc, expr, info): for i in ('enum', 'union', 'alternate', 'struct', 'command', 'event'): if i in expr: @@ -1021,9 +1018,7 @@ def check_docs(docs): raise QAPISemError(doc.info, "Empty doc section '%s'" % section.name) - if not doc.expr: - check_freeform_doc(doc) - else: + if doc.expr: check_definition_doc(doc, doc.expr, doc.info) return docs diff --git a/tests/qapi-schema/doc-invalid-section.err b/tests/qapi-schema/doc-invalid-section.err index 85bb67b829..bda93b44fd 100644 --- a/tests/qapi-schema/doc-invalid-section.err +++ b/tests/qapi-schema/doc-invalid-section.err @@ -1 +1 @@ -tests/qapi-schema/doc-invalid-section.json:3: Free-form documentation block must not contain @NAME: sections +tests/qapi-schema/doc-invalid-section.json:5:1: '@note:' not allowed in free-form documentation From 4ea7148e89deda8795b3233bc5ba8c4bf037230e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:23 +0100 Subject: [PATCH 36/49] qapi: Move empty doc section checking to doc parser Results in a more precise error location, but the real reason is emptying out check_docs() step by step. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-35-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 20 ++++++++++++++------ tests/qapi-schema/doc-empty-section.err | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 4edcea1883..648355ed0e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -173,6 +173,9 @@ def append(self, line): else: self._append_freeform(line) + def end_comment(self): + self._end_section() + def _append_symbol_line(self, line): name = line.split(' ', 1)[0] @@ -200,6 +203,7 @@ def _start_args_section(self, name): raise QAPIParseError(self.parser, "'@%s:' can't follow '%s' section" % (name, self.sections[0].name)) + self._end_section() self.section = QAPIDoc.ArgSection(name) self.args[name] = self.section @@ -207,9 +211,18 @@ def _start_section(self, name=''): if name in ('Returns', 'Since') and self.has_section(name): raise QAPIParseError(self.parser, "Duplicated '%s' section" % name) + self._end_section() self.section = QAPIDoc.Section(name) self.sections.append(self.section) + def _end_section(self): + if self.section: + contents = str(self.section) + if self.section.name and (not contents or contents.isspace()): + raise QAPIParseError(self.parser, "Empty doc section '%s'" + % self.section.name) + self.section = None + def _append_freeform(self, line): in_arg = isinstance(self.section, QAPIDoc.ArgSection) if (in_arg and self.section.content @@ -512,6 +525,7 @@ def get_doc(self, info): if self.val != '##': raise QAPIParseError(self, "Junk after '##' at end of " "documentation comment") + doc.end_comment() self.accept() return doc else: @@ -1012,12 +1026,6 @@ def check_definition_doc(doc, expr, info): def check_docs(docs): for doc in docs: - for section in doc.args.values() + doc.sections: - content = str(section) - if not content or content.isspace(): - raise QAPISemError(doc.info, - "Empty doc section '%s'" % section.name) - if doc.expr: check_definition_doc(doc, doc.expr, doc.info) diff --git a/tests/qapi-schema/doc-empty-section.err b/tests/qapi-schema/doc-empty-section.err index 00ad625e17..b61e4a7886 100644 --- a/tests/qapi-schema/doc-empty-section.err +++ b/tests/qapi-schema/doc-empty-section.err @@ -1 +1 @@ -tests/qapi-schema/doc-empty-section.json:3: Empty doc section 'Note' +tests/qapi-schema/doc-empty-section.json:7:1: Empty doc section 'Note' From bdc001caaa60dd71af8cddf73688f28ac5a32bc2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:24 +0100 Subject: [PATCH 37/49] tests/qapi-schema: Rename doc-bad-args to doc-bad-command-arg Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-36-git-send-email-armbru@redhat.com> --- tests/Makefile.include | 2 +- tests/qapi-schema/doc-bad-args.err | 1 - tests/qapi-schema/doc-bad-command-arg.err | 1 + .../qapi-schema/{doc-bad-args.exit => doc-bad-command-arg.exit} | 0 .../qapi-schema/{doc-bad-args.json => doc-bad-command-arg.json} | 0 tests/qapi-schema/{doc-bad-args.out => doc-bad-command-arg.out} | 0 6 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 tests/qapi-schema/doc-bad-args.err create mode 100644 tests/qapi-schema/doc-bad-command-arg.err rename tests/qapi-schema/{doc-bad-args.exit => doc-bad-command-arg.exit} (100%) rename tests/qapi-schema/{doc-bad-args.json => doc-bad-command-arg.json} (100%) rename tests/qapi-schema/{doc-bad-args.out => doc-bad-command-arg.out} (100%) diff --git a/tests/Makefile.include b/tests/Makefile.include index 505f918404..734c7ff6da 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -367,7 +367,7 @@ qapi-schema += base-cycle-direct.json qapi-schema += base-cycle-indirect.json qapi-schema += command-int.json qapi-schema += comments.json -qapi-schema += doc-bad-args.json +qapi-schema += doc-bad-command-arg.json qapi-schema += doc-bad-symbol.json qapi-schema += doc-before-include.json qapi-schema += doc-before-pragma.json diff --git a/tests/qapi-schema/doc-bad-args.err b/tests/qapi-schema/doc-bad-args.err deleted file mode 100644 index 5d44d9b668..0000000000 --- a/tests/qapi-schema/doc-bad-args.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/doc-bad-args.json:3: The following documented members are not in the declaration: b diff --git a/tests/qapi-schema/doc-bad-command-arg.err b/tests/qapi-schema/doc-bad-command-arg.err new file mode 100644 index 0000000000..8075b146ae --- /dev/null +++ b/tests/qapi-schema/doc-bad-command-arg.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-bad-command-arg.json:3: The following documented members are not in the declaration: b diff --git a/tests/qapi-schema/doc-bad-args.exit b/tests/qapi-schema/doc-bad-command-arg.exit similarity index 100% rename from tests/qapi-schema/doc-bad-args.exit rename to tests/qapi-schema/doc-bad-command-arg.exit diff --git a/tests/qapi-schema/doc-bad-args.json b/tests/qapi-schema/doc-bad-command-arg.json similarity index 100% rename from tests/qapi-schema/doc-bad-args.json rename to tests/qapi-schema/doc-bad-command-arg.json diff --git a/tests/qapi-schema/doc-bad-args.out b/tests/qapi-schema/doc-bad-command-arg.out similarity index 100% rename from tests/qapi-schema/doc-bad-args.out rename to tests/qapi-schema/doc-bad-command-arg.out From f641d06ad63773ae524fb073b2f8639e1db1462c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:25 +0100 Subject: [PATCH 38/49] tests/qapi-schema: Improve coverage of bogus member docs New test doc-bad-union-member.json shows we can fail to reject documentation for nonexistent members. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-37-git-send-email-armbru@redhat.com> --- tests/Makefile.include | 2 ++ .../qapi-schema/doc-bad-alternate-member.err | 1 + .../qapi-schema/doc-bad-alternate-member.exit | 1 + .../qapi-schema/doc-bad-alternate-member.json | 9 +++++++++ .../qapi-schema/doc-bad-alternate-member.out | 0 tests/qapi-schema/doc-bad-union-member.err | 0 tests/qapi-schema/doc-bad-union-member.exit | 1 + tests/qapi-schema/doc-bad-union-member.json | 19 +++++++++++++++++++ tests/qapi-schema/doc-bad-union-member.out | 11 +++++++++++ 9 files changed, 44 insertions(+) create mode 100644 tests/qapi-schema/doc-bad-alternate-member.err create mode 100644 tests/qapi-schema/doc-bad-alternate-member.exit create mode 100644 tests/qapi-schema/doc-bad-alternate-member.json create mode 100644 tests/qapi-schema/doc-bad-alternate-member.out create mode 100644 tests/qapi-schema/doc-bad-union-member.err create mode 100644 tests/qapi-schema/doc-bad-union-member.exit create mode 100644 tests/qapi-schema/doc-bad-union-member.json create mode 100644 tests/qapi-schema/doc-bad-union-member.out diff --git a/tests/Makefile.include b/tests/Makefile.include index 734c7ff6da..e6e00b40e6 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -367,8 +367,10 @@ qapi-schema += base-cycle-direct.json qapi-schema += base-cycle-indirect.json qapi-schema += command-int.json qapi-schema += comments.json +qapi-schema += doc-bad-alternate-member.json qapi-schema += doc-bad-command-arg.json qapi-schema += doc-bad-symbol.json +qapi-schema += doc-bad-union-member.json qapi-schema += doc-before-include.json qapi-schema += doc-before-pragma.json qapi-schema += doc-duplicated-arg.json diff --git a/tests/qapi-schema/doc-bad-alternate-member.err b/tests/qapi-schema/doc-bad-alternate-member.err new file mode 100644 index 0000000000..387f7824da --- /dev/null +++ b/tests/qapi-schema/doc-bad-alternate-member.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-bad-alternate-member.json:3: The following documented members are not in the declaration: aa, bb diff --git a/tests/qapi-schema/doc-bad-alternate-member.exit b/tests/qapi-schema/doc-bad-alternate-member.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/doc-bad-alternate-member.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/doc-bad-alternate-member.json b/tests/qapi-schema/doc-bad-alternate-member.json new file mode 100644 index 0000000000..738635ca8f --- /dev/null +++ b/tests/qapi-schema/doc-bad-alternate-member.json @@ -0,0 +1,9 @@ +# Arguments listed in the doc comment must exist in the actual schema + +## +# @AorB: +# @aa: a +# @bb: b +## +{ 'alternate': 'AorB', + 'data': { 'a': 'str', 'b': 'int' } } diff --git a/tests/qapi-schema/doc-bad-alternate-member.out b/tests/qapi-schema/doc-bad-alternate-member.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/doc-bad-union-member.err b/tests/qapi-schema/doc-bad-union-member.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/doc-bad-union-member.exit b/tests/qapi-schema/doc-bad-union-member.exit new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/tests/qapi-schema/doc-bad-union-member.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/doc-bad-union-member.json b/tests/qapi-schema/doc-bad-union-member.json new file mode 100644 index 0000000000..d611435f6a --- /dev/null +++ b/tests/qapi-schema/doc-bad-union-member.json @@ -0,0 +1,19 @@ +# Arguments listed in the doc comment must exist in the actual schema + +## +# @Frob: +# @a: a +# @b: b +## +{ 'union': 'Frob', + 'base': 'Base', + 'discriminator': 'type', + 'data': { 'nothing': 'Empty' } } + +{ 'struct': 'Base', + 'data': { 'type': 'T' } } + +{ 'struct': 'Empty', + 'data': { } } + +{ 'enum': 'T', 'data': ['nothing'] } diff --git a/tests/qapi-schema/doc-bad-union-member.out b/tests/qapi-schema/doc-bad-union-member.out new file mode 100644 index 0000000000..2576ecd037 --- /dev/null +++ b/tests/qapi-schema/doc-bad-union-member.out @@ -0,0 +1,11 @@ +object Base + member type: T optional=False +object Empty +object Frob + base Base + tag type + case nothing: Empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE +enum T ['nothing'] +object q_empty From 816a57cd6ebb6fe820766ac12478a56a5fa33d52 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:26 +0100 Subject: [PATCH 39/49] qapi: Fix detection of bogus member documentation check_definition_doc() checks for member documentation without a matching member. It laboriously second-guesses what members QAPISchema._def_exprs() will create. That's a stupid game. Move the check into QAPISchema.check(), where the members are known. Delegate the actual checking to new QAPIDoc.check(). Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-38-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 38 +++++++-------------- tests/qapi-schema/doc-bad-union-member.err | 1 + tests/qapi-schema/doc-bad-union-member.exit | 2 +- tests/qapi-schema/doc-bad-union-member.out | 11 ------ 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 648355ed0e..ca9926b796 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -249,6 +249,15 @@ def connect_member(self, member): self.args[member.name] = QAPIDoc.ArgSection(member.name) self.args[member.name].connect(member) + def check(self): + bogus = [name for name, section in self.args.iteritems() + if not section.member] + if bogus: + raise QAPISemError( + self.info, + "The following documented members are not in " + "the declaration: %s" % ", ".join(bogus)) + class QAPISchemaParser(object): @@ -995,34 +1004,9 @@ def check_exprs(exprs): def check_definition_doc(doc, expr, info): - for i in ('enum', 'union', 'alternate', 'struct', 'command', 'event'): - if i in expr: - meta = i - break - if doc.has_section('Returns') and 'command' not in expr: raise QAPISemError(info, "'Returns:' is only valid for commands") - if meta == 'union': - args = expr.get('base', []) - else: - args = expr.get('data', []) - if isinstance(args, str): - return - if isinstance(args, dict): - args = args.keys() - assert isinstance(args, list) - - if (meta == 'alternate' - or (meta == 'union' and not expr.get('discriminator'))): - args.append('type') - - doc_args = set(doc.args.keys()) - args = set([name.strip('*') for name in args]) - if not doc_args.issubset(args): - raise QAPISemError(info, "The following documented members are not in " - "the declaration: %s" % ', '.join(doc_args - args)) - def check_docs(docs): for doc in docs: @@ -1268,6 +1252,8 @@ def check(self, schema): self.variants.check(schema, seen) assert self.variants.tag_member in self.members self.variants.check_clash(schema, self.info, seen) + if self.doc: + self.doc.check() # Check that the members of this type do not cause duplicate JSON members, # and update seen to track the members seen so far. Report any errors @@ -1437,6 +1423,8 @@ def check(self, schema): v.check_clash(self.info, seen) if self.doc: self.doc.connect_member(v) + if self.doc: + self.doc.check() def c_type(self): return c_name(self.name) + pointer_suffix diff --git a/tests/qapi-schema/doc-bad-union-member.err b/tests/qapi-schema/doc-bad-union-member.err index e69de29bb2..4b016df7ff 100644 --- a/tests/qapi-schema/doc-bad-union-member.err +++ b/tests/qapi-schema/doc-bad-union-member.err @@ -0,0 +1 @@ +tests/qapi-schema/doc-bad-union-member.json:3: The following documented members are not in the declaration: a, b diff --git a/tests/qapi-schema/doc-bad-union-member.exit b/tests/qapi-schema/doc-bad-union-member.exit index 573541ac97..d00491fd7e 100644 --- a/tests/qapi-schema/doc-bad-union-member.exit +++ b/tests/qapi-schema/doc-bad-union-member.exit @@ -1 +1 @@ -0 +1 diff --git a/tests/qapi-schema/doc-bad-union-member.out b/tests/qapi-schema/doc-bad-union-member.out index 2576ecd037..e69de29bb2 100644 --- a/tests/qapi-schema/doc-bad-union-member.out +++ b/tests/qapi-schema/doc-bad-union-member.out @@ -1,11 +0,0 @@ -object Base - member type: T optional=False -object Empty -object Frob - base Base - tag type - case nothing: Empty -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] - prefix QTYPE -enum T ['nothing'] -object q_empty From a9f396b028bc304fd1c27b2d52b22966cfc98a61 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:27 +0100 Subject: [PATCH 40/49] qapi: Eliminate check_docs() and drop QAPIDoc.expr Move what's left in check_docs() to check_expr(). Delegate the actual checking to new QAPIDoc.check_expr(). QAPIDoc.expr is now unused; drop it. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-39-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index ca9926b796..1aaae8e2f6 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -138,8 +138,6 @@ def __init__(self, parser, info): self.sections = [] # the current section self.section = self.body - # associated expression (to be set by expression parser) - self.expr = None def has_section(self, name): """Return True if we have a section with this name.""" @@ -249,6 +247,11 @@ def connect_member(self, member): self.args[member.name] = QAPIDoc.ArgSection(member.name) self.args[member.name].connect(member) + def check_expr(self, expr): + if self.has_section('Returns') and 'command' not in expr: + raise QAPISemError(self.info, + "'Returns:' is only valid for commands") + def check(self): bogus = [name for name, section in self.args.iteritems() if not section.member] @@ -316,7 +319,6 @@ def __init__(self, fp, previously_included=[], incl_info=None): raise QAPISemError( self.cur_doc.info, "Expression documentation required") - self.cur_doc.expr = expr expr_elem['doc'] = self.cur_doc self.exprs.append(expr_elem) self.cur_doc = None @@ -984,6 +986,7 @@ def check_exprs(exprs): for expr_elem in exprs: expr = expr_elem['expr'] info = expr_elem['info'] + doc = expr_elem.get('doc') if 'enum' in expr: check_enum(expr, info) @@ -1000,22 +1003,12 @@ def check_exprs(exprs): else: assert False, 'unexpected meta type' + if doc: + doc.check_expr(expr) + return exprs -def check_definition_doc(doc, expr, info): - if doc.has_section('Returns') and 'command' not in expr: - raise QAPISemError(info, "'Returns:' is only valid for commands") - - -def check_docs(docs): - for doc in docs: - if doc.expr: - check_definition_doc(doc, doc.expr, doc.info) - - return docs - - # # Schema compiler frontend # @@ -1511,7 +1504,7 @@ def __init__(self, fname): try: parser = QAPISchemaParser(open(fname, 'r')) self.exprs = check_exprs(parser.exprs) - self.docs = check_docs(parser.docs) + self.docs = parser.docs self._entity_dict = {} self._predefining = True self._def_predefineds() From 062e856b155a8b7724b8eba449fc3aa8a181d46b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:28 +0100 Subject: [PATCH 41/49] qapi: Drop unused variable events Missed in commit e98859a Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-40-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 1aaae8e2f6..d5a113c7d6 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -49,7 +49,6 @@ enum_types = [] struct_types = [] union_types = [] -events = [] all_names = {} # @@ -756,14 +755,12 @@ def check_command(expr, info): def check_event(expr, info): - global events name = expr['event'] boxed = expr.get('boxed', False) meta = ['struct'] if boxed: meta += ['union', 'alternate'] - events.append(name) check_type(info, "'data' for event '%s'" % name, expr.get('data'), allow_dict=not boxed, allow_optional=True, allow_metas=meta) From eda43c68440e32062c32cc99a79edbb52cf87a74 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:29 +0100 Subject: [PATCH 42/49] qapi: Simplify what gets stored in enum_types Don't invent a new dictionary structure just for enum_types, simply store the defining expression, like we do for struct_types and union_types. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-41-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index d5a113c7d6..3c6e137847 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -668,16 +668,17 @@ def find_union(name): return None -def add_enum(name, info, enum_values=None, implicit=False): +def add_enum(definition, info): global enum_types - add_name(name, info, 'enum', implicit) - enum_types.append({'enum_name': name, 'enum_values': enum_values}) + name = definition['enum'] + add_name(name, info, 'enum', 'data' not in definition) + enum_types.append(definition) def find_enum(name): global enum_types for enum in enum_types: - if enum['enum_name'] == name: + if enum['enum'] == name: return enum return None @@ -825,15 +826,15 @@ def check_union(expr, info): # If the discriminator names an enum type, then all members # of 'data' must also be members of the enum type. if enum_define: - if key not in enum_define['enum_values']: + if key not in enum_define['data']: raise QAPISemError(info, "Discriminator value '%s' is not found in " "enum '%s'" - % (key, enum_define['enum_name'])) + % (key, enum_define['enum'])) # If discriminator is user-defined, ensure all values are covered if enum_define: - for value in enum_define['enum_values']: + for value in enum_define['data']: if value not in members.keys(): raise QAPISemError(info, "Union '%s' data missing '%s' branch" % (name, value)) @@ -938,7 +939,7 @@ def check_exprs(exprs): if 'enum' in expr: name = expr['enum'] check_keys(expr_elem, 'enum', ['data'], ['prefix']) - add_enum(name, info, expr['data']) + add_enum(expr, info) elif 'union' in expr: name = expr['union'] check_keys(expr_elem, 'union', ['data'], @@ -971,13 +972,13 @@ def check_exprs(exprs): # Try again for hidden UnionKind enum for expr_elem in exprs: expr = expr_elem['expr'] - if 'union' in expr: - if not discriminator_find_enum_define(expr): - add_enum('%sKind' % expr['union'], expr_elem['info'], - implicit=True) + if 'union' in expr and not discriminator_find_enum_define(expr): + name = '%sKind' % expr['union'] elif 'alternate' in expr: - add_enum('%sKind' % expr['alternate'], expr_elem['info'], - implicit=True) + name = '%sKind' % expr['alternate'] + else: + continue + add_enum({ 'enum': name }, expr_elem['info']) # Validate that exprs make sense for expr_elem in exprs: From 6f05345f8f8eac137e0ba22a7389cdeaff60c9b2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:30 +0100 Subject: [PATCH 43/49] qapi: Factor add_name() calls out of the meta conditional Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-42-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 3c6e137847..1f79eb4d17 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -640,8 +640,6 @@ def add_name(name, info, meta, implicit=False): def add_struct(definition, info): global struct_types - name = definition['struct'] - add_name(name, info, 'struct') struct_types.append(definition) @@ -655,8 +653,6 @@ def find_struct(name): def add_union(definition, info): global union_types - name = definition['union'] - add_name(name, info, 'union') union_types.append(definition) @@ -670,8 +666,6 @@ def find_union(name): def add_enum(definition, info): global enum_types - name = definition['enum'] - add_name(name, info, 'enum', 'data' not in definition) enum_types.append(definition) @@ -937,34 +931,33 @@ def check_exprs(exprs): "Expression missing documentation comment") if 'enum' in expr: - name = expr['enum'] + meta = 'enum' check_keys(expr_elem, 'enum', ['data'], ['prefix']) add_enum(expr, info) elif 'union' in expr: - name = expr['union'] + meta = 'union' check_keys(expr_elem, 'union', ['data'], ['base', 'discriminator']) add_union(expr, info) elif 'alternate' in expr: - name = expr['alternate'] + meta = 'alternate' check_keys(expr_elem, 'alternate', ['data']) - add_name(name, info, 'alternate') elif 'struct' in expr: - name = expr['struct'] + meta = 'struct' check_keys(expr_elem, 'struct', ['data'], ['base']) add_struct(expr, info) elif 'command' in expr: - name = expr['command'] + meta = 'command' check_keys(expr_elem, 'command', [], ['data', 'returns', 'gen', 'success-response', 'boxed']) - add_name(name, info, 'command') elif 'event' in expr: - name = expr['event'] + meta = 'event' check_keys(expr_elem, 'event', [], ['data', 'boxed']) - add_name(name, info, 'event') else: raise QAPISemError(expr_elem['info'], "Expression is missing metatype") + name = expr[meta] + add_name(name, info, meta) if doc and doc.symbol != name: raise QAPISemError(info, "Definition of '%s' follows documentation" " for '%s'" % (name, doc.symbol)) @@ -979,6 +972,7 @@ def check_exprs(exprs): else: continue add_enum({ 'enum': name }, expr_elem['info']) + add_name(name, info, 'enum', implicit=True) # Validate that exprs make sense for expr_elem in exprs: From 5f018446fe69ec85711db364e8d1f4c4de372bf5 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:31 +0100 Subject: [PATCH 44/49] qapi: enum_types is a list used like a dict, make it one Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-43-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 1f79eb4d17..735ddaa605 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -46,7 +46,7 @@ # Whitelist of entities allowed to violate case conventions name_case_whitelist = [] -enum_types = [] +enum_types = {} struct_types = [] union_types = [] all_names = {} @@ -567,7 +567,7 @@ def find_alternate_member_qtype(qapi_type): return builtin_types[qapi_type] elif find_struct(qapi_type): return 'QTYPE_QDICT' - elif find_enum(qapi_type): + elif qapi_type in enum_types: return 'QTYPE_QSTRING' elif find_union(qapi_type): return 'QTYPE_QDICT' @@ -591,7 +591,7 @@ def discriminator_find_enum_define(expr): if not discriminator_type: return None - return find_enum(discriminator_type) + return enum_types.get(discriminator_type) # Names must be letters, numbers, -, and _. They must start with letter, @@ -664,23 +664,6 @@ def find_union(name): return None -def add_enum(definition, info): - global enum_types - enum_types.append(definition) - - -def find_enum(name): - global enum_types - for enum in enum_types: - if enum['enum'] == name: - return enum - return None - - -def is_enum(name): - return find_enum(name) is not None - - def check_type(info, source, value, allow_array=False, allow_dict=False, allow_optional=False, allow_metas=[]): @@ -799,7 +782,7 @@ def check_union(expr, info): "Discriminator '%s' is not a member of base " "struct '%s'" % (discriminator, base)) - enum_define = find_enum(discriminator_type) + enum_define = enum_types.get(discriminator_type) allow_metas = ['struct'] # Do not allow string discriminator if not enum_define: @@ -933,7 +916,7 @@ def check_exprs(exprs): if 'enum' in expr: meta = 'enum' check_keys(expr_elem, 'enum', ['data'], ['prefix']) - add_enum(expr, info) + enum_types[expr[meta]] = expr elif 'union' in expr: meta = 'union' check_keys(expr_elem, 'union', ['data'], @@ -971,7 +954,7 @@ def check_exprs(exprs): name = '%sKind' % expr['alternate'] else: continue - add_enum({ 'enum': name }, expr_elem['info']) + enum_types[name] = {'enum': name} add_name(name, info, 'enum', implicit=True) # Validate that exprs make sense From ed285bf821eeb5d82bb2777707cc02b11194b7b1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:32 +0100 Subject: [PATCH 45/49] qapi: struct_types is a list used like a dict, make it one Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-44-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 735ddaa605..f4d1a483e5 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -47,7 +47,7 @@ name_case_whitelist = [] enum_types = {} -struct_types = [] +struct_types = {} union_types = [] all_names = {} @@ -555,7 +555,7 @@ def get_doc(self, info): def find_base_members(base): if isinstance(base, dict): return base - base_struct_define = find_struct(base) + base_struct_define = struct_types.get(base) if not base_struct_define: return None return base_struct_define['data'] @@ -565,7 +565,7 @@ def find_base_members(base): def find_alternate_member_qtype(qapi_type): if qapi_type in builtin_types: return builtin_types[qapi_type] - elif find_struct(qapi_type): + elif qapi_type in struct_types: return 'QTYPE_QDICT' elif qapi_type in enum_types: return 'QTYPE_QSTRING' @@ -638,19 +638,6 @@ def add_name(name, info, meta, implicit=False): all_names[name] = meta -def add_struct(definition, info): - global struct_types - struct_types.append(definition) - - -def find_struct(name): - global struct_types - for struct in struct_types: - if struct['struct'] == name: - return struct - return None - - def add_union(definition, info): global union_types union_types.append(definition) @@ -928,7 +915,7 @@ def check_exprs(exprs): elif 'struct' in expr: meta = 'struct' check_keys(expr_elem, 'struct', ['data'], ['base']) - add_struct(expr, info) + struct_types[expr[meta]] = expr elif 'command' in expr: meta = 'command' check_keys(expr_elem, 'command', [], From 768562ded0354f6834b48c99626b6fadf19b757b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:33 +0100 Subject: [PATCH 46/49] qapi: union_types is a list used like a dict, make it one Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-45-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index f4d1a483e5..82c25a113e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -48,7 +48,7 @@ enum_types = {} struct_types = {} -union_types = [] +union_types = {} all_names = {} # @@ -569,7 +569,7 @@ def find_alternate_member_qtype(qapi_type): return 'QTYPE_QDICT' elif qapi_type in enum_types: return 'QTYPE_QSTRING' - elif find_union(qapi_type): + elif qapi_type in union_types: return 'QTYPE_QDICT' return None @@ -638,19 +638,6 @@ def add_name(name, info, meta, implicit=False): all_names[name] = meta -def add_union(definition, info): - global union_types - union_types.append(definition) - - -def find_union(name): - global union_types - for union in union_types: - if union['union'] == name: - return union - return None - - def check_type(info, source, value, allow_array=False, allow_dict=False, allow_optional=False, allow_metas=[]): @@ -908,7 +895,7 @@ def check_exprs(exprs): meta = 'union' check_keys(expr_elem, 'union', ['data'], ['base', 'discriminator']) - add_union(expr, info) + union_types[expr[meta]] = expr elif 'alternate' in expr: meta = 'alternate' check_keys(expr_elem, 'alternate', ['data']) From 6bbfb12de6541794c10baf007ad327262f94f10a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:34 +0100 Subject: [PATCH 47/49] qapi: Drop unused .check_clash() parameter schema Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-46-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 82c25a113e..b798ae47b2 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1183,7 +1183,7 @@ def check(self, schema): self.base = schema.lookup_type(self._base_name) assert isinstance(self.base, QAPISchemaObjectType) self.base.check(schema) - self.base.check_clash(schema, self.info, seen) + self.base.check_clash(self.info, seen) for m in self.local_members: m.check(schema) m.check_clash(self.info, seen) @@ -1193,14 +1193,14 @@ def check(self, schema): if self.variants: self.variants.check(schema, seen) assert self.variants.tag_member in self.members - self.variants.check_clash(schema, self.info, seen) + self.variants.check_clash(self.info, seen) if self.doc: self.doc.check() # Check that the members of this type do not cause duplicate JSON members, # and update seen to track the members seen so far. Report any errors # on behalf of info, which is not necessarily self.info - def check_clash(self, schema, info, seen): + def check_clash(self, info, seen): assert not self.variants # not implemented for m in self.members: m.check_clash(info, seen) @@ -1329,12 +1329,12 @@ def check(self, schema, seen): assert isinstance(v.type, QAPISchemaObjectType) v.type.check(schema) - def check_clash(self, schema, info, seen): + def check_clash(self, info, seen): for v in self.variants: # Reset seen map for each variant, since qapi names from one # branch do not affect another branch assert isinstance(v.type, QAPISchemaObjectType) - v.type.check_clash(schema, info, dict(seen)) + v.type.check_clash(info, dict(seen)) class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember): From c261394978d000000a095d7b4986226d0a4a551c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:35 +0100 Subject: [PATCH 48/49] qapi: Make pylint a bit happier Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-47-git-send-email-armbru@redhat.com> --- scripts/qapi-commands.py | 6 +++--- scripts/qapi-visit.py | 1 - scripts/qapi.py | 8 ++++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 0c05449cb6..1943de4852 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -13,7 +13,6 @@ # See the COPYING file in the top-level directory. from qapi import * -import re def gen_command_decl(name, arg_type, boxed, ret_type): @@ -84,7 +83,8 @@ def gen_marshal_output(ret_type): def gen_marshal_proto(name): - return 'void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name) + return ('void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' + % c_name(name)) def gen_marshal_decl(name): @@ -198,7 +198,7 @@ def gen_register_command(name, success_response): options = 'QCO_NO_SUCCESS_RESP' ret = mcgen(''' - qmp_register_command(cmds, "%(name)s", + qmp_register_command(cmds, "%(name)s", qmp_marshal_%(c_name)s, %(opts)s); ''', name=name, c_name=c_name(name), diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 3d3936e4d0..5737aefa05 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -13,7 +13,6 @@ # See the COPYING file in the top-level directory. from qapi import * -import re def gen_visit_decl(name, scalar=False): diff --git a/scripts/qapi.py b/scripts/qapi.py index b798ae47b2..d19300d657 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -11,13 +11,13 @@ # This work is licensed under the terms of the GNU GPL, version 2. # See the COPYING file in the top-level directory. -import re -from ordereddict import OrderedDict import errno import getopt import os -import sys +import re import string +import sys +from ordereddict import OrderedDict builtin_types = { 'str': 'QTYPE_QSTRING', @@ -1587,7 +1587,7 @@ def _def_union_type(self, expr, info, doc): tag_member = None if isinstance(base, dict): base = (self._make_implicit_object_type( - name, info, doc, 'base', self._make_members(base, info))) + name, info, doc, 'base', self._make_members(base, info))) if tag_name: variants = [self._make_variant(key, value) for (key, value) in data.iteritems()] From 012b126de2ded4e93b5ed069be5544ad8a2e6c15 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 15 Mar 2017 13:57:36 +0100 Subject: [PATCH 49/49] qapi: Fix a misleading parser error message When choking on a token where an expression is expected, we report 'Expected "{", "[" or string'. Close, but no cigar. Fix it to Expected '"{", "[", string, boolean or "null"'. Missed in commit e53188a. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1489582656-31133-48-git-send-email-armbru@redhat.com> --- scripts/qapi.py | 3 ++- tests/qapi-schema/trailing-comma-list.err | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index d19300d657..e88c047c2e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -519,7 +519,8 @@ def get_expr(self, nested): expr = self.val self.accept() else: - raise QAPIParseError(self, 'Expected "{", "[" or string') + raise QAPIParseError(self, 'Expected "{", "[", string, ' + 'boolean or "null"') return expr def get_doc(self, info): diff --git a/tests/qapi-schema/trailing-comma-list.err b/tests/qapi-schema/trailing-comma-list.err index 24c24b0108..212e14ae28 100644 --- a/tests/qapi-schema/trailing-comma-list.err +++ b/tests/qapi-schema/trailing-comma-list.err @@ -1 +1 @@ -tests/qapi-schema/trailing-comma-list.json:2:36: Expected "{", "[" or string +tests/qapi-schema/trailing-comma-list.json:2:36: Expected "{", "[", string, boolean or "null"