All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: mdroth@linux.vnet.ibm.com, marcandre.lureau@redhat.com,
	eblake@redhat.com
Subject: [Qemu-devel] [RFC PATCH 21/32] qapi: Define QAPIOptionKind and QAPIOption automatically
Date: Mon,  2 Oct 2017 17:25:41 +0200	[thread overview]
Message-ID: <20171002152552.27999-22-armbru@redhat.com> (raw)
In-Reply-To: <20171002152552.27999-1-armbru@redhat.com>

Enumeration type QAPIOptionKind enumerates the command line options.

Flat union QAPIOption captures a single command line option.  Its tag
is QAPIOptionKind, and the variants are the option argument types.

FIXME implement missing clash checking in QAPISchemaObjectType.check_clash()
FIXME potential clash in QAPISchema._def_autos()
FIXME made up info in QAPISchema._def_autos()
TODO can we avoid the wrappers around non-object option argument types?

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi-commands.py               |  2 +-
 scripts/qapi-event.py                  |  2 +-
 scripts/qapi-introspect.py             |  2 +-
 scripts/qapi-types.py                  |  2 +-
 scripts/qapi-visit.py                  |  2 +-
 scripts/qapi.py                        | 42 ++++++++++++++++++++++++++++++++--
 scripts/qapi2texi.py                   |  2 +-
 tests/qapi-schema/qapi-schema-test.out | 14 ++++++++++++
 tests/qapi-schema/test-qapi.py         |  2 +-
 9 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 76cc9cc8a4..fdd3492f87 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -315,7 +315,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
                   prefix=args.prefix,
                   c_prefix=c_name(args.prefix, protect=False)))
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, args.prefix)
 gen = QAPISchemaGenCommandVisitor()
 schema.visit(gen)
 fdef.write(gen.defn)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 1c61751bc0..64a4a02757 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -226,7 +226,7 @@ fdecl.write(mcgen('''
 
 event_enum_name = c_name(args.prefix + 'QAPIEvent', protect=False)
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, args.prefix)
 gen = QAPISchemaGenEventVisitor()
 schema.visit(gen)
 fdef.write(gen.defn)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index cc4ff01cd4..89365449b0 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -206,7 +206,7 @@ fdef.write(mcgen('''
 ''',
                  prefix=args.prefix))
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, args.prefix)
 gen = QAPISchemaGenIntrospectVisitor(args.unmask_non_abi_names)
 schema.visit(gen, builtins=True)
 fdef.write(gen.defn)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index c058540e4d..5c53c56e45 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -276,7 +276,7 @@ else:
 #include "qapi/util.h"
 '''))
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, args.prefix)
 gen = QAPISchemaGenTypeVisitor()
 schema.visit(gen, builtins=not args.schema)
 fdef.write(gen.defn)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index e756ef98ee..3182b860af 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -359,7 +359,7 @@ else:
 
 '''))
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, args.prefix)
 gen = QAPISchemaGenVisitVisitor()
 schema.visit(gen, builtins=not args.schema)
 fdef.write(gen.defn)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 1e03b62943..efc128eee0 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1235,7 +1235,12 @@ class QAPISchemaObjectType(QAPISchemaType):
     # 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, info, seen):
-        assert not self.variants       # not implemented
+        # check_union() ensures the following assertion holds, but
+        # QAPIUnion violates it.  Disable it for now, so we can play
+        # with QAPIUnion without having to implement the missing clash
+        # checking first.
+        # FIXME implement missing clash checking
+        # assert not self.variants       # not implemented
         for m in self.members:
             m.check_clash(info, seen)
 
@@ -1535,8 +1540,9 @@ class QAPISchemaOption(QAPISchemaEntity):
 
 
 class QAPISchema(object):
-    def __init__(self, file):
+    def __init__(self, file, prefix):
         try:
+            self.prefix = prefix
             if file:
                 parser = QAPISchemaParser(file)
                 self.exprs = check_exprs(parser.exprs)
@@ -1545,10 +1551,14 @@ class QAPISchema(object):
                 self.exprs = []
                 self.docs = []
             self._entity_dict = {}
+            self._option_arg = {}
             self._predefining = True
             self._def_predefineds()
             self._predefining = False
             self._def_exprs()
+            self._predefining = True
+            self._def_autos()
+            self._predefining = False
             self.check()
         except QAPIError as err:
             print >>sys.stderr, err
@@ -1751,6 +1761,7 @@ class QAPISchema(object):
                 name[2:], info, doc, 'optarg', self._make_members(data, info))
         self._def_entity(QAPISchemaOption(name, info, doc, data,
                                           short, implied_key, boxed, help_))
+        self._option_arg[name[2:]] = data
 
     def _def_exprs(self):
         for expr_elem in self.exprs:
@@ -1774,6 +1785,33 @@ class QAPISchema(object):
             else:
                 assert False
 
+    def _def_autos(self):
+        info = {'file': None, 'line': 0, 'parent': None}  # FIXME
+        if self._option_arg:
+            name = self.prefix + 'QAPIOption'
+            self._make_implicit_enum_type(name, info,
+                                          sorted(self._option_arg.keys()))
+            # FIXME what if these members clash with variant members?
+            members = [
+                QAPISchemaObjectTypeMember('type', name + 'Kind', False),
+                QAPISchemaObjectTypeMember('idx', 'int32', False),
+                QAPISchemaObjectTypeMember('cnt', 'int32', False)]
+            variants = []
+            for (key, value) in sorted(self._option_arg.items()):
+                if not value:
+                    continue
+                typ = self.lookup_type(value)
+                if isinstance(typ, QAPISchemaObjectType):
+                    v = self._make_variant(key, value)
+                else:
+                    # TODO can we avoid the wrapper?
+                    v = self._make_simple_variant(key, value, typ.info)
+                variants.append(v)
+            self._def_entity(QAPISchemaObjectType(
+                name, info, None, None, members,
+                QAPISchemaObjectTypeVariants('type', None, variants)
+                if variants else None))
+
     def check(self):
         for ent in self._entity_dict.values():
             ent.check(self)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 071abc9d5d..0e099ebaa2 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -286,7 +286,7 @@ def main(argv):
                         help='QAPI schema source file')
     args = parser.parse_args()
 
-    schema = qapi.QAPISchema(args.schema)
+    schema = qapi.QAPISchema(args.schema, '')
     if not qapi.doc_required:
         print >>sys.stderr, ("%s: need pragma 'doc-required' "
                              "to generate documentation" % argv[0])
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9ee06539ac..16dc30dd99 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -79,6 +79,18 @@ object NestedEnumsOne
     member enum2: EnumOne optional=True
     member enum3: EnumOne optional=False
     member enum4: EnumOne optional=True
+object QAPIOption
+    member type: QAPIOptionKind optional=False
+    member idx: int32 optional=False
+    member cnt: int32 optional=False
+    tag type
+    case opt-any: q_obj_any-wrapper
+    case opt-boxed: UserDefZero
+    case opt-enum: q_obj_EnumOne-wrapper
+    case opt-int: q_obj_int-wrapper
+    case opt-str: q_obj_str-wrapper
+    case opt-struct: q_obj_opt-struct-optarg
+enum QAPIOptionKind ['help', 'opt-any', 'opt-boxed', 'opt-enum', 'opt-int', 'opt-str', 'opt-struct']
 enum QEnumTwo ['value1', 'value2']
     prefix QENUM_TWO
 object TestStruct
@@ -207,6 +219,8 @@ object q_obj_EVENT_D-arg
     member b: str optional=False
     member c: str optional=True
     member enum3: EnumOne optional=True
+object q_obj_EnumOne-wrapper
+    member data: EnumOne optional=False
 object q_obj_UserDefA-wrapper
     member data: UserDefA optional=False
 object q_obj_UserDefB-wrapper
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 2e5e7bfeb1..7de7d6dc53 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -67,7 +67,7 @@ parser.add_argument('schema', type=argparse.FileType('r'), nargs='?',
                     help='QAPI schema source file')
 args = parser.parse_args()
 
-schema = QAPISchema(args.schema)
+schema = QAPISchema(args.schema, '')
 schema.visit(QAPISchemaTestVisitor(), builtins=not args.schema)
 
 for doc in schema.docs:
-- 
2.13.6

  parent reply	other threads:[~2017-10-02 15:26 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-02 15:25 [Qemu-devel] [RFC PATCH 00/32] Command line QAPIfication Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 01/32] tests/qapi-schema: Improve coverage of '@' Markus Armbruster
2017-10-04 10:37   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 02/32] texi2pod: Support @verbatim environment Markus Armbruster
2017-10-05 14:58   ` Eric Blake
2017-10-06  5:24     ` Markus Armbruster
2017-10-06 13:40       ` Eric Blake
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 03/32] qapi2texi: Fix for examples containing '@' Markus Armbruster
2017-10-04 10:45   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 04/32] qapi2texi: Fix for '@' not followed by \w character Markus Armbruster
2017-10-04 10:47   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 05/32] qapi2texi: Provide access to Texinfo markup Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 06/32] qapi2texi: Drop | example markup Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 07/32] qapi: Drop superfluous allow_optional=True Markus Armbruster
2017-10-04 10:52   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 08/32] qapi: Simplify check_name() parameters Markus Armbruster
2017-10-04 10:54   ` Marc-André Lureau
2017-10-04 10:54   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 09/32] qapi: check_type() parameter allow_optional is now unused, drop Markus Armbruster
2017-10-04 10:55   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 10/32] qapi: Don't run generators twice Markus Armbruster
2017-10-04 11:04   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 11/32] qapi: Drop the options to generate only .c or .h Markus Armbruster
2017-10-04 11:07   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 12/32] qapi: Use argparse to parse command line arguments Markus Armbruster
2017-10-04 11:13   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 13/32] qapi: Use argparse to open schema file Markus Armbruster
2017-10-04 11:18   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 14/32] qapi: Rework generated code for built-in types Markus Armbruster
2017-10-04 11:52   ` Marc-André Lureau
2017-10-05  4:24     ` Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 15/32] tests/qapi-schema: Improve simple union coverage Markus Armbruster
2017-10-04 12:02   ` Marc-André Lureau
2017-10-05  4:29     ` Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 16/32] qapi: Factor out _make_implicit_wrapper_type() Markus Armbruster
2017-10-04 12:00   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 17/32] qapi: Fix simple union lowering with multiple schemas Markus Armbruster
2017-10-04 12:04   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 18/32] docs/devel/qapi-code-gen.txt: Rewrite section on schema syntax Markus Armbruster
2017-10-04 11:59   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 19/32] qapi: Accept double-quoted strings Markus Armbruster
2017-10-04 11:58   ` Marc-André Lureau
2017-10-05  4:41     ` Markus Armbruster
2017-10-05 14:13       ` Marc-André Lureau
2017-10-06  5:29         ` Markus Armbruster
2017-10-05 15:16       ` Eric Blake
2017-10-06  5:27         ` Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 20/32] qapi: Frontend for defining command line options Markus Armbruster
2017-10-02 15:25 ` Markus Armbruster [this message]
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 22/32] qapi: New helper c_string() Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 23/32] qapi-options: Command line option backend Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 24/32] qapi-options: Generate help string Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 25/32] qapi-introspect: Include command line options information Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 26/32] qapi2texi: " Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 27/32] os-posix: Drop misleading comment Markus Armbruster
2017-10-04 12:10   ` Marc-André Lureau
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 28/32] vl: QAPIfy command line option definition Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 29/32] qapi/options: QAPIfy --echr argument type Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 30/32] qapi/options: QAPIfy --watchdog-action " Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 31/32] qapi/options: QAPIfy --blockdev " Markus Armbruster
2017-10-02 15:25 ` [Qemu-devel] [RFC PATCH 32/32] qapi/options: QAPIfy --add-fd " Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171002152552.27999-22-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.