All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: QEMU <qemu-devel@nongnu.org>, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [RFC PATCH 14/32] qapi: Rework generated code for built-in types
Date: Wed, 4 Oct 2017 13:52:43 +0200	[thread overview]
Message-ID: <CAJ+F1C+gsgG+Nbmj56DACRCAdWk==Ud=CCtfppc-jy4L41QoMw@mail.gmail.com> (raw)
In-Reply-To: <20171002152552.27999-15-armbru@redhat.com>

Hi

On Mon, Oct 2, 2017 at 5:25 PM, Markus Armbruster <armbru@redhat.com> wrote:
> qapi-types.py and qapi-visit.py generate some C code for built-in
> types.  To make this work with multiple schemas, we generate code for
> built-ins into .c files only when the user asks for it with -b.  The
> user is responsible for linking exactly one set of files generated
> with -b per program.  We generate code for built-ins into .h
> regardless of -b, but guard it with a preprocessor symbol.
>
> This is cumbersome and inflexible.  Move the code generated for
> built-in types into separate files builtin-qapi-{types,visit}.{c,h}.
> Run qapi-types.py and qapi-visit.py without a schema argument to
> generate them.  Drop their option -b.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>


Good idea!
I think I would still prefer to see a seperate argument to generate
builtin files (rather than absence of schema), but this is minor
detail.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>


> ---
>  .gitignore                               |  2 ++
>  Makefile                                 | 18 ++++++++--
>  Makefile.objs                            |  1 +
>  docs/devel/qapi-code-gen.txt             | 24 +++++++++++--
>  qga/Makefile.objs                        |  1 +
>  scripts/qapi-introspect.py               |  4 +--
>  scripts/qapi-types.py                    | 54 ++++++++++------------------
>  scripts/qapi-visit.py                    | 62 ++++++++++++--------------------
>  scripts/qapi.py                          | 57 ++++++++++++++++-------------
>  scripts/qapi2texi.py                     |  2 +-
>  tests/Makefile.include                   |  4 ++-
>  tests/qapi-schema/builtins.err           |  0
>  tests/qapi-schema/builtins.exit          |  1 +
>  tests/qapi-schema/builtins.json          |  1 +
>  tests/qapi-schema/builtins.out           |  3 ++
>  tests/qapi-schema/comments.out           |  3 --
>  tests/qapi-schema/doc-bad-section.out    |  3 --
>  tests/qapi-schema/doc-good.out           |  3 --
>  tests/qapi-schema/empty.out              |  3 --
>  tests/qapi-schema/event-case.out         |  3 --
>  tests/qapi-schema/ident-with-escape.out  |  3 --
>  tests/qapi-schema/include-relpath.out    |  3 --
>  tests/qapi-schema/include-repetition.out |  3 --
>  tests/qapi-schema/include-simple.out     |  3 --
>  tests/qapi-schema/indented-expr.out      |  3 --
>  tests/qapi-schema/qapi-schema-test.out   |  3 --
>  tests/qapi-schema/test-qapi.py           |  4 +--
>  27 files changed, 127 insertions(+), 144 deletions(-)
>  create mode 100644 tests/qapi-schema/builtins.err
>  create mode 100644 tests/qapi-schema/builtins.exit
>  create mode 100644 tests/qapi-schema/builtins.json
>  create mode 100644 tests/qapi-schema/builtins.out
>
> diff --git a/.gitignore b/.gitignore
> index 40acfcb9e2..84a57060ad 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -1,3 +1,5 @@
> +/builtin-qapi-types.[ch]
> +/builtin-qapi-visit.[ch]
>  /config-devices.*
>  /config-all-devices.*
>  /config-all-disas.*
> diff --git a/Makefile b/Makefile
> index 784b601247..421e65d833 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -52,6 +52,8 @@ endif
>  include $(SRC_PATH)/rules.mak
>
>  GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
> +GENERATED_FILES += builtin-qapi-types.h builtin-qapi-types.c
> +GENERATED_FILES += builtin-qapi-visit.h builtin-qapi-visit.c
>  GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
>  GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
>  GENERATED_FILES += qmp-introspect.h
> @@ -428,18 +430,30 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
>                 $(SRC_PATH)/qapi/transaction.json \
>                 $(SRC_PATH)/qapi/ui.json
>
> +.INTERMEDIATE: builtin-qapi-types-gen
> +builtin-qapi-types.c builtin-qapi-types.h: builtin-qapi-types-gen ;
> +builtin-qapi-types-gen: $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
> +       $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py, \
> +               "GEN","$@")
> +
> +.INTERMEDIATE: builtin-qapi-visit-gen
> +builtin-qapi-visit.c builtin-qapi-visit.h: builtin-qapi-visit-gen ;
> +builtin-qapi-visit-gen: $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
> +       $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py, \
> +               "GEN","$@")
> +
>  .INTERMEDIATE: qapi-types-gen
>  qapi-types.c qapi-types.h: qapi-types-gen ;
>  qapi-types-gen: $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
>         $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
> -               -b $<, \
> +               $<, \
>                 "GEN","$@")
>
>  .INTERMEDIATE: qapi-visit-gen
>  qapi-visit.c qapi-visit.h: qapi-visit-gen ;
>  qapi-visit-gen: $(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
>         $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
> -               -b $<, \
> +               $<, \
>                 "GEN","$@")
>
>  .INTERMEDIATE: qapi-event-gen
> diff --git a/Makefile.objs b/Makefile.objs
> index cc4f94d77a..c2c62cb462 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -2,6 +2,7 @@
>  # Common libraries for tools and emulators
>  stub-obj-y = stubs/ crypto/
>  util-obj-y = util/ qobject/ qapi/
> +util-obj-y += builtin-qapi-types.o builtin-qapi-visit.o
>  util-obj-y += qapi-types.o qapi-visit.o qapi-event.o
>
>  chardev-obj-y = chardev/
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index 579807f6a5..f5b7659caf 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -937,7 +937,7 @@ supporting code. The following files are created:
>
>  $(prefix)qapi-types.h - C types corresponding to types defined in
>                          the schema you pass in
> -$(prefix)qapi-types.c - Cleanup functions for the above C types
> +$(prefix)qapi-types.c - Support code for the above C types
>
>  The $(prefix) is an optional parameter used as a namespace to keep the
>  generated code from one schema/code-generation separated from others so code
> @@ -954,7 +954,7 @@ Example:
>      #ifndef EXAMPLE_QAPI_TYPES_H
>      #define EXAMPLE_QAPI_TYPES_H
>
> -[Built-in types omitted...]
> +    #include "builtin-qapi-types.h"
>
>      typedef struct UserDefOne UserDefOne;
>
> @@ -1011,6 +1011,14 @@ Example:
>          visit_free(v);
>      }
>
> +Type definitions for the built-in types are generated separately, into
> +builtin-qapi-types.h and builtin-qapi-types.c.  These are independent
> +of the schema.
> +
> +Example:
> +
> +    $ python scripts/qapi-types.py --output-dir="qapi-generated"
> +
>  === scripts/qapi-visit.py ===
>
>  Used to generate the visitor functions used to walk through and
> @@ -1039,7 +1047,9 @@ Example:
>      #ifndef EXAMPLE_QAPI_VISIT_H
>      #define EXAMPLE_QAPI_VISIT_H
>
> -[Visitors for built-in types omitted...]
> +    #include "builtin-qapi-visit.h"
> +    #include "example-qapi-types.h"
> +
>
>      void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp);
>      void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp);
> @@ -1140,6 +1150,14 @@ Example:
>          error_propagate(errp, err);
>      }
>
> +Visitor functions for the built-in types are generated separately,
> +into builtin-qapi-visit.h and builtin-qapi-visit.c.  These are
> +independent of the schema.
> +
> +Example:
> +
> +    $ python scripts/qapi-visit.py --output-dir="qapi-generated"
> +
>  === scripts/qapi-commands.py ===
>
>  Used to generate the marshaling/dispatch functions for the commands
> diff --git a/qga/Makefile.objs b/qga/Makefile.objs
> index 1c5986c0bb..1430655fbe 100644
> --- a/qga/Makefile.objs
> +++ b/qga/Makefile.objs
> @@ -2,6 +2,7 @@ qga-obj-y = commands.o guest-agent-command-state.o main.o
>  qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
>  qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
>  qga-obj-$(CONFIG_WIN32) += vss-win32.o
> +qga-obj-y += ../builtin-qapi-types.o ../builtin-qapi-visit.o
>  qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
>  qga-obj-y += qapi-generated/qga-qmp-marshal.o
>
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index ad87fc57e3..cc4ff01cd4 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -60,7 +60,7 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
>          jsons = self._jsons
>          self._jsons = []
>          for typ in self._used_types:
> -            typ.visit(self)
> +            typ.visit(self, builtins=True)
>          # generate C
>          # TODO can generate awfully long lines
>          jsons.extend(self._jsons)
> @@ -208,7 +208,7 @@ fdef.write(mcgen('''
>
>  schema = QAPISchema(args.schema)
>  gen = QAPISchemaGenIntrospectVisitor(args.unmask_non_abi_names)
> -schema.visit(gen)
> +schema.visit(gen, builtins=True)
>  fdef.write(gen.defn)
>  fdecl.write(gen.decl)
>
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index ed05d828bf..18fd2a98c0 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -170,7 +170,6 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>          self.decl = None
>          self.defn = None
>          self._fwdecl = None
> -        self._btin = None
>
>      def visit_begin(self, schema):
>          # gen_object() is recursive, ensure it doesn't visit the empty type
> @@ -178,45 +177,23 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>          self.decl = ''
>          self.defn = ''
>          self._fwdecl = ''
> -        self._btin = guardstart('QAPI_TYPES_BUILTIN')
>
>      def visit_end(self):
>          self.decl = self._fwdecl + self.decl
>          self._fwdecl = None
> -        # To avoid header dependency hell, we always generate
> -        # declarations for built-in types in our header files and
> -        # simply guard them.  See also args.builtins (command line
> -        # option -b).
> -        self._btin += guardend('QAPI_TYPES_BUILTIN')
> -        self.decl = self._btin + self.decl
> -        self._btin = None
>
>      def _gen_type_cleanup(self, name):
>          self.decl += gen_type_cleanup_decl(name)
>          self.defn += gen_type_cleanup(name)
>
>      def visit_enum_type(self, name, info, values, prefix):
> -        # Special case for our lone builtin enum type
> -        # TODO use something cleaner than existence of info
> -        if not info:
> -            self._btin += gen_enum(name, values, prefix)
> -            if args.builtins:
> -                self.defn += gen_enum_lookup(name, values, prefix)
> -        else:
> -            self._fwdecl += gen_enum(name, values, prefix)
> -            self.defn += gen_enum_lookup(name, values, prefix)
> +        self._fwdecl += gen_enum(name, values, prefix)
> +        self.defn += gen_enum_lookup(name, values, prefix)
>
>      def visit_array_type(self, name, info, element_type):
> -        if isinstance(element_type, QAPISchemaBuiltinType):
> -            self._btin += gen_fwd_object_or_array(name)
> -            self._btin += gen_array(name, element_type)
> -            self._btin += gen_type_cleanup_decl(name)
> -            if args.builtins:
> -                self.defn += gen_type_cleanup(name)
> -        else:
> -            self._fwdecl += gen_fwd_object_or_array(name)
> -            self.decl += gen_array(name, element_type)
> -            self._gen_type_cleanup(name)
> +        self._fwdecl += gen_fwd_object_or_array(name)
> +        self.decl += gen_array(name, element_type)
> +        self._gen_type_cleanup(name)
>
>      def visit_object_type(self, name, info, base, members, variants):
>          # Nothing to do for the special empty builtin
> @@ -237,12 +214,12 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>          self.decl += gen_object(name, None, [variants.tag_member], variants)
>          self._gen_type_cleanup(name)
>
> -# If you link code generated from multiple schemata, you want only one
> -# instance of the code for built-in types.  Generate it only when
> -# args.builtins, enabled by command line option -b.  See also
> -# QAPISchemaGenTypeVisitor.visit_end().
> -
> -args = common_argument_parser(builtins=True).parse_args()
> +argparser = common_argument_parser(builtins=True)
> +args = argparser.parse_args()
> +if not args.schema:
> +    if args.prefix:
> +        argparser.error('schema required with -p')
> +    args.prefix = 'builtin-'
>
>  c_comment = '''
>  /*
> @@ -286,13 +263,18 @@ fdef.write(mcgen('''
>  ''',
>                   prefix=args.prefix))
>
> -fdecl.write(mcgen('''
> +if args.schema:
> +    fdecl.write(mcgen('''
> +#include "builtin-qapi-types.h"
> +'''))
> +else:
> +    fdecl.write(mcgen('''
>  #include "qapi/util.h"
>  '''))
>
>  schema = QAPISchema(args.schema)
>  gen = QAPISchemaGenTypeVisitor()
> -schema.visit(gen)
> +schema.visit(gen, builtins=not args.schema)
>  fdef.write(gen.defn)
>  fdecl.write(gen.decl)
>
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 010d68434f..e756ef98ee 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -266,43 +266,18 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
>      def __init__(self):
>          self.decl = None
>          self.defn = None
> -        self._btin = None
>
>      def visit_begin(self, schema):
>          self.decl = ''
>          self.defn = ''
> -        self._btin = guardstart('QAPI_VISIT_BUILTIN')
> -
> -    def visit_end(self):
> -        # To avoid header dependency hell, we always generate
> -        # declarations for built-in types in our header files and
> -        # simply guard them.  See also args.builtins (command line
> -        # option -b).
> -        self._btin += guardend('QAPI_VISIT_BUILTIN')
> -        self.decl = self._btin + self.decl
> -        self._btin = None
>
>      def visit_enum_type(self, name, info, values, prefix):
> -        # Special case for our lone builtin enum type
> -        # TODO use something cleaner than existence of info
> -        if not info:
> -            self._btin += gen_visit_decl(name, scalar=True)
> -            if args.builtins:
> -                self.defn += gen_visit_enum(name)
> -        else:
> -            self.decl += gen_visit_decl(name, scalar=True)
> -            self.defn += gen_visit_enum(name)
> +        self.decl += gen_visit_decl(name, scalar=True)
> +        self.defn += gen_visit_enum(name)
>
>      def visit_array_type(self, name, info, element_type):
> -        decl = gen_visit_decl(name)
> -        defn = gen_visit_list(name, element_type)
> -        if isinstance(element_type, QAPISchemaBuiltinType):
> -            self._btin += decl
> -            if args.builtins:
> -                self.defn += defn
> -        else:
> -            self.decl += decl
> -            self.defn += defn
> +        self.decl += gen_visit_decl(name)
> +        self.defn += gen_visit_list(name, element_type)
>
>      def visit_object_type(self, name, info, base, members, variants):
>          # Nothing to do for the special empty builtin
> @@ -321,12 +296,12 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
>          self.decl += gen_visit_decl(name)
>          self.defn += gen_visit_alternate(name, variants)
>
> -# If you link code generated from multiple schemata, you want only one
> -# instance of the code for built-in types.  Generate it only when
> -# args.builtins, enabled by command line option -b.  See also
> -# QAPISchemaGenVisitVisitor.visit_end().
> -
> -args = common_argument_parser(builtins=True).parse_args()
> +argparser = common_argument_parser(builtins=True)
> +args = argparser.parse_args()
> +if not args.schema:
> +    if args.prefix:
> +        argparser.error('schema required with -p')
> +    args.prefix = 'builtin-'
>
>  c_comment = '''
>  /*
> @@ -369,17 +344,24 @@ fdef.write(mcgen('''
>  ''',
>                   prefix=args.prefix))
>
> -fdecl.write(mcgen('''
> +if args.schema:
> +    fdecl.write(mcgen('''
> +#include "builtin-qapi-visit.h"
> +#include "%(prefix)sqapi-types.h"
> +
> +''',
> +                      prefix=args.prefix))
> +else:
> +    fdecl.write(mcgen('''
>  #include "qapi/visitor.h"
>  #include "qapi/qmp/qerror.h"
> -#include "%(prefix)sqapi-types.h"
> +#include "builtin-qapi-types.h"
>
> -''',
> -                  prefix=args.prefix))
> +'''))
>
>  schema = QAPISchema(args.schema)
>  gen = QAPISchemaGenVisitVisitor()
> -schema.visit(gen)
> +schema.visit(gen, builtins=not args.schema)
>  fdef.write(gen.defn)
>  fdecl.write(gen.decl)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index a33203e82d..248d650858 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -983,7 +983,7 @@ class QAPISchemaEntity(object):
>      def is_implicit(self):
>          return not self.info
>
> -    def visit(self, visitor):
> +    def visit(self, visitor, builtins):
>          pass
>
>
> @@ -1084,8 +1084,9 @@ class QAPISchemaBuiltinType(QAPISchemaType):
>      def doc_type(self):
>          return self.json_type()
>
> -    def visit(self, visitor):
> -        visitor.visit_builtin_type(self.name, self.info, self.json_type())
> +    def visit(self, visitor, builtins):
> +        if builtins:
> +            visitor.visit_builtin_type(self.name, self.info, self.json_type())
>
>
>  class QAPISchemaEnumType(QAPISchemaType):
> @@ -1118,9 +1119,11 @@ class QAPISchemaEnumType(QAPISchemaType):
>      def json_type(self):
>          return 'string'
>
> -    def visit(self, visitor):
> -        visitor.visit_enum_type(self.name, self.info,
> -                                self.member_names(), self.prefix)
> +    def visit(self, visitor, builtins):
> +        # TODO use something cleaner than existence of info
> +        if builtins or self.info:
> +            visitor.visit_enum_type(self.name, self.info,
> +                                    self.member_names(), self.prefix)
>
>
>  class QAPISchemaArrayType(QAPISchemaType):
> @@ -1149,8 +1152,10 @@ class QAPISchemaArrayType(QAPISchemaType):
>              return None
>          return 'array of ' + elt_doc_type
>
> -    def visit(self, visitor):
> -        visitor.visit_array_type(self.name, self.info, self.element_type)
> +    def visit(self, visitor, builtins):
> +        if builtins or not isinstance(self.element_type,
> +                                      QAPISchemaBuiltinType):
> +            visitor.visit_array_type(self.name, self.info, self.element_type)
>
>
>  class QAPISchemaObjectType(QAPISchemaType):
> @@ -1229,11 +1234,13 @@ class QAPISchemaObjectType(QAPISchemaType):
>      def json_type(self):
>          return 'object'
>
> -    def visit(self, visitor):
> -        visitor.visit_object_type(self.name, self.info,
> -                                  self.base, self.local_members, self.variants)
> -        visitor.visit_object_type_flat(self.name, self.info,
> -                                       self.members, self.variants)
> +    def visit(self, visitor, builtins):
> +        # TODO use something cleaner than existence of info
> +        if builtins or self.info:
> +            visitor.visit_object_type(self.name, self.info, self.base,
> +                                      self.local_members, self.variants)
> +            visitor.visit_object_type_flat(self.name, self.info,
> +                                           self.members, self.variants)
>
>
>  class QAPISchemaMember(object):
> @@ -1375,7 +1382,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
>      def json_type(self):
>          return 'value'
>
> -    def visit(self, visitor):
> +    def visit(self, visitor, builtins):
>          visitor.visit_alternate_type(self.name, self.info, self.variants)
>
>      def is_empty(self):
> @@ -1415,7 +1422,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
>              self.ret_type = schema.lookup_type(self._ret_type_name)
>              assert isinstance(self.ret_type, QAPISchemaType)
>
> -    def visit(self, visitor):
> +    def visit(self, visitor, builtins):
>          visitor.visit_command(self.name, self.info,
>                                self.arg_type, self.ret_type,
>                                self.gen, self.success_response, self.boxed)
> @@ -1445,16 +1452,20 @@ class QAPISchemaEvent(QAPISchemaEntity):
>          elif self.boxed:
>              raise QAPISemError(self.info, "Use of 'boxed' requires 'data'")
>
> -    def visit(self, visitor):
> +    def visit(self, visitor, builtins):
>          visitor.visit_event(self.name, self.info, self.arg_type, self.boxed)
>
>
>  class QAPISchema(object):
>      def __init__(self, file):
>          try:
> -            parser = QAPISchemaParser(file)
> -            self.exprs = check_exprs(parser.exprs)
> -            self.docs = parser.docs
> +            if file:
> +                parser = QAPISchemaParser(file)
> +                self.exprs = check_exprs(parser.exprs)
> +                self.docs = parser.docs
> +            else:
> +                self.exprs = []
> +                self.docs = []
>              self._entity_dict = {}
>              self._predefining = True
>              self._def_predefineds()
> @@ -1668,11 +1679,11 @@ class QAPISchema(object):
>          for ent in self._entity_dict.values():
>              ent.check(self)
>
> -    def visit(self, visitor):
> +    def visit(self, visitor, builtins=False):
>          visitor.visit_begin(self)
>          for (name, entity) in sorted(self._entity_dict.items()):
>              if visitor.visit_needed(entity):
> -                entity.visit(visitor)
> +                entity.visit(visitor, builtins)
>          visitor.visit_end()
>
>
> @@ -1927,14 +1938,12 @@ def common_argument_parser(builtins=False):
>          return string
>
>      parser = argparse.ArgumentParser(conflict_handler='resolve')
> -    if builtins:
> -        parser.add_argument('-b', '--builtins', action='store_true',
> -                            help='generate builtins')
>      parser.add_argument('-o', '--output-dir', default='',
>                          help='output directory')
>      parser.add_argument('-p', '--prefix', default='', type=prefix,
>                          help='prefix to add to output files')
>      parser.add_argument('schema', type=argparse.FileType('r'),
> +                        nargs='?' if builtins else None,
>                          help='QAPI schema source file')
>      return parser
>
> diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
> index d95d7541a3..071abc9d5d 100755
> --- a/scripts/qapi2texi.py
> +++ b/scripts/qapi2texi.py
> @@ -257,7 +257,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
>          if self.out:
>              self.out += '\n'
>          self.cur_doc = doc
> -        entity.visit(self)
> +        entity.visit(self, builtins=False)
>          self.cur_doc = None
>
>      def freeform(self, doc):
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 5d53c58506..2ef5dc51f1 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -371,6 +371,7 @@ check-qtest-s390x-y += tests/drive_del-test$(EXESUF)
>  check-qtest-generic-y += tests/qom-test$(EXESUF)
>  check-qtest-generic-y += tests/test-hmp$(EXESUF)
>
> +qapi-schema += builtins.json
>  qapi-schema += alternate-any.json
>  qapi-schema += alternate-array.json
>  qapi-schema += alternate-base.json
> @@ -910,7 +911,8 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
>  $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
>         $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
>                 $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
> -               $^ >$*.test.out 2>$*.test.err; \
> +               `echo "$^" | sed '/builtins/d'` \
> +               >$*.test.out 2>$*.test.err; \
>                 echo $$? >$*.test.exit, \
>                 "TEST","$*.out")
>         @diff -q $(SRC_PATH)/$*.out $*.test.out
> diff --git a/tests/qapi-schema/builtins.err b/tests/qapi-schema/builtins.err
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/builtins.exit b/tests/qapi-schema/builtins.exit
> new file mode 100644
> index 0000000000..573541ac97
> --- /dev/null
> +++ b/tests/qapi-schema/builtins.exit
> @@ -0,0 +1 @@
> +0
> diff --git a/tests/qapi-schema/builtins.json b/tests/qapi-schema/builtins.json
> new file mode 100644
> index 0000000000..c4088f6792
> --- /dev/null
> +++ b/tests/qapi-schema/builtins.json
> @@ -0,0 +1 @@
> +# This file exists to simplify make's job, it's not actually read
> diff --git a/tests/qapi-schema/builtins.out b/tests/qapi-schema/builtins.out
> new file mode 100644
> index 0000000000..40b886ddae
> --- /dev/null
> +++ b/tests/qapi-schema/builtins.out
> @@ -0,0 +1,3 @@
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +    prefix QTYPE
> +object q_empty
> diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
> index 17e652535c..6161b90e91 100644
> --- a/tests/qapi-schema/comments.out
> +++ b/tests/qapi-schema/comments.out
> @@ -1,4 +1 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
> -object q_empty
> diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/qapi-schema/doc-bad-section.out
> index 089bde1381..a2f0842130 100644
> --- a/tests/qapi-schema/doc-bad-section.out
> +++ b/tests/qapi-schema/doc-bad-section.out
> @@ -1,7 +1,4 @@
>  enum Enum ['one', 'two']
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
> -object q_empty
>  doc symbol=Enum
>      body=
>  == Produces *invalid* texinfo
> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
> index f0ba51db4b..f609c5d5f5 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -6,8 +6,6 @@ object Object
>      tag base1
>      case one: Variant1
>      case two: Variant2
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  object SugaredUnion
>      member type: SugaredUnionKind optional=False
>      tag type
> @@ -21,7 +19,6 @@ command cmd q_obj_cmd-arg -> Object
>     gen=True success_response=True boxed=False
>  command cmd-boxed Object -> None
>     gen=True success_response=True boxed=True
> -object q_empty
>  object q_obj_Variant1-wrapper
>      member data: Variant1 optional=False
>  object q_obj_Variant2-wrapper
> diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
> index 40b886ddae..e69de29bb2 100644
> --- a/tests/qapi-schema/empty.out
> +++ b/tests/qapi-schema/empty.out
> @@ -1,3 +0,0 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
> -object q_empty
> diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
> index 313c0fe7be..0c3a3b5ba2 100644
> --- a/tests/qapi-schema/event-case.out
> +++ b/tests/qapi-schema/event-case.out
> @@ -1,5 +1,2 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  event oops None
>     boxed=False
> -object q_empty
> diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
> index b5637cb2e0..89fe61f9e9 100644
> --- a/tests/qapi-schema/ident-with-escape.out
> +++ b/tests/qapi-schema/ident-with-escape.out
> @@ -1,7 +1,4 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  command fooA q_obj_fooA-arg -> None
>     gen=True success_response=True boxed=False
> -object q_empty
>  object q_obj_fooA-arg
>      member bar1: str optional=False
> diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
> index 17e652535c..6161b90e91 100644
> --- a/tests/qapi-schema/include-relpath.out
> +++ b/tests/qapi-schema/include-relpath.out
> @@ -1,4 +1 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
> -object q_empty
> diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
> index 17e652535c..6161b90e91 100644
> --- a/tests/qapi-schema/include-repetition.out
> +++ b/tests/qapi-schema/include-repetition.out
> @@ -1,4 +1 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
> -object q_empty
> diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
> index 17e652535c..6161b90e91 100644
> --- a/tests/qapi-schema/include-simple.out
> +++ b/tests/qapi-schema/include-simple.out
> @@ -1,4 +1 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
> -object q_empty
> diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
> index 586795f44d..bfdc976854 100644
> --- a/tests/qapi-schema/indented-expr.out
> +++ b/tests/qapi-schema/indented-expr.out
> @@ -1,7 +1,4 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  command eins None -> None
>     gen=True success_response=True boxed=False
> -object q_empty
>  command zwei None -> None
>     gen=True success_response=True boxed=False
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index 3b1e9082d3..4b42db23b2 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -50,8 +50,6 @@ object NestedEnumsOne
>      member enum4: EnumOne optional=True
>  enum QEnumTwo ['value1', 'value2']
>      prefix QENUM_TWO
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> -    prefix QTYPE
>  object TestStruct
>      member integer: int optional=False
>      member boolean: bool optional=False
> @@ -162,7 +160,6 @@ command guest-get-time q_obj_guest-get-time-arg -> int
>     gen=True success_response=True boxed=False
>  command guest-sync q_obj_guest-sync-arg -> any
>     gen=True success_response=True boxed=False
> -object q_empty
>  object q_obj_EVENT_C-arg
>      member a: int optional=True
>      member b: UserDefOne optional=True
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 225417d861..0294a66619 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -53,12 +53,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
>                  print '    case %s: %s' % (v.name, v.type.name)
>
>  parser = argparse.ArgumentParser()
> -parser.add_argument('schema', type=argparse.FileType('r'),
> +parser.add_argument('schema', type=argparse.FileType('r'), nargs='?',
>                      help='QAPI schema source file')
>  args = parser.parse_args()
>
>  schema = QAPISchema(args.schema)
> -schema.visit(QAPISchemaTestVisitor())
> +schema.visit(QAPISchemaTestVisitor(), builtins=not args.schema)
>
>  for doc in schema.docs:
>      if doc.symbol:
> --
> 2.13.6
>
>



-- 
Marc-André Lureau

  reply	other threads:[~2017-10-04 11:52 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 [this message]
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 ` [Qemu-devel] [RFC PATCH 21/32] qapi: Define QAPIOptionKind and QAPIOption automatically Markus Armbruster
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='CAJ+F1C+gsgG+Nbmj56DACRCAdWk==Ud=CCtfppc-jy4L41QoMw@mail.gmail.com' \
    --to=marcandre.lureau@gmail.com \
    --cc=armbru@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.