diff mbox

[v2,07/29] qapi: Turn generators into modules

Message ID 20180211093607.27351-8-armbru@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Markus Armbruster Feb. 11, 2018, 9:35 a.m. UTC
The next commit will introduce a common driver program for all
generators.  The generators need to be modules for that.  qapi2texi.py
already is.  Make the other generators follow suit.

The changes are actually trivial.  Obvious in the diffs once you view
them with whitespace changes ignored.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi-commands.py   | 43 ++++++++++++++++++--------------
 scripts/qapi-event.py      | 43 ++++++++++++++++++--------------
 scripts/qapi-introspect.py | 54 ++++++++++++++++++++++------------------
 scripts/qapi-types.py      | 56 ++++++++++++++++++++++-------------------
 scripts/qapi-visit.py      | 62 +++++++++++++++++++++++++---------------------
 5 files changed, 143 insertions(+), 115 deletions(-)

Comments

Michael Roth Feb. 17, 2018, 1:29 a.m. UTC | #1
Quoting Markus Armbruster (2018-02-11 03:35:45)
> The next commit will introduce a common driver program for all
> generators.  The generators need to be modules for that.  qapi2texi.py
> already is.  Make the other generators follow suit.
> 
> The changes are actually trivial.  Obvious in the diffs once you view
> them with whitespace changes ignored.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>

> ---
>  scripts/qapi-commands.py   | 43 ++++++++++++++++++--------------
>  scripts/qapi-event.py      | 43 ++++++++++++++++++--------------
>  scripts/qapi-introspect.py | 54 ++++++++++++++++++++++------------------
>  scripts/qapi-types.py      | 56 ++++++++++++++++++++++-------------------
>  scripts/qapi-visit.py      | 62 +++++++++++++++++++++++++---------------------
>  5 files changed, 143 insertions(+), 115 deletions(-)
> 
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index e97e16e828..8584cb5873 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -255,16 +255,17 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
>          self._regy += gen_register_command(name, success_response)
> 
> 
> -(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
> +def main(argv):
> +    (input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
> 
> -blurb = '''
> +    blurb = '''
>   * Schema-defined QAPI/QMP commands
>  '''
> 
> -genc = QAPIGenC(blurb, __doc__)
> -genh = QAPIGenH(blurb, __doc__)
> +    genc = QAPIGenC(blurb, __doc__)
> +    genh = QAPIGenH(blurb, __doc__)
> 
> -genc.add(mcgen('''
> +    genc.add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "qemu-common.h"
>  #include "qemu/module.h"
> @@ -279,23 +280,27 @@ genc.add(mcgen('''
>  #include "%(prefix)sqmp-commands.h"
> 
>  ''',
> -               prefix=prefix))
> +                   prefix=prefix))
> 
> -genh.add(mcgen('''
> +    genh.add(mcgen('''
>  #include "%(prefix)sqapi-types.h"
>  #include "qapi/qmp/dispatch.h"
> 
>  void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
>  ''',
> -               prefix=prefix, c_prefix=c_name(prefix, protect=False)))
> -
> -schema = QAPISchema(input_file)
> -vis = QAPISchemaGenCommandVisitor(prefix)
> -schema.visit(vis)
> -genc.add(vis.defn)
> -genh.add(vis.decl)
> -
> -if do_c:
> -    genc.write(output_dir, prefix + 'qmp-marshal.c')
> -if do_h:
> -    genh.write(output_dir, prefix + 'qmp-commands.h')
> +                   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
> +
> +    schema = QAPISchema(input_file)
> +    vis = QAPISchemaGenCommandVisitor(prefix)
> +    schema.visit(vis)
> +    genc.add(vis.defn)
> +    genh.add(vis.decl)
> +
> +    if do_c:
> +        genc.write(output_dir, prefix + 'qmp-marshal.c')
> +    if do_h:
> +        genh.write(output_dir, prefix + 'qmp-commands.h')
> +
> +
> +if __name__ == '__main__':
> +    main(sys.argv)
> diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
> index 3f98e2491a..e7e07f0055 100644
> --- a/scripts/qapi-event.py
> +++ b/scripts/qapi-event.py
> @@ -171,16 +171,17 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
>          self._event_names.append(name)
> 
> 
> -(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
> +def main(argv):
> +    (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
> 
> -blurb = '''
> +    blurb = '''
>   * Schema-defined QAPI/QMP events
>  '''
> 
> -genc = QAPIGenC(blurb, __doc__)
> -genh = QAPIGenH(blurb, __doc__)
> +    genc = QAPIGenC(blurb, __doc__)
> +    genh = QAPIGenH(blurb, __doc__)
> 
> -genc.add(mcgen('''
> +    genc.add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "qemu-common.h"
>  #include "%(prefix)sqapi-event.h"
> @@ -191,22 +192,26 @@ genc.add(mcgen('''
>  #include "qapi/qmp-event.h"
> 
>  ''',
> -               prefix=prefix))
> +                   prefix=prefix))
> 
> -genh.add(mcgen('''
> +    genh.add(mcgen('''
>  #include "qapi/util.h"
>  #include "%(prefix)sqapi-types.h"
> 
>  ''',
> -               prefix=prefix))
> -
> -schema = QAPISchema(input_file)
> -vis = QAPISchemaGenEventVisitor(prefix)
> -schema.visit(vis)
> -genc.add(vis.defn)
> -genh.add(vis.decl)
> -
> -if do_c:
> -    genc.write(output_dir, prefix + 'qapi-event.c')
> -if do_h:
> -    genh.write(output_dir, prefix + 'qapi-event.h')
> +                   prefix=prefix))
> +
> +    schema = QAPISchema(input_file)
> +    vis = QAPISchemaGenEventVisitor(prefix)
> +    schema.visit(vis)
> +    genc.add(vis.defn)
> +    genh.add(vis.decl)
> +
> +    if do_c:
> +        genc.write(output_dir, prefix + 'qapi-event.c')
> +    if do_h:
> +        genh.write(output_dir, prefix + 'qapi-event.h')
> +
> +
> +if __name__ == '__main__':
> +    main(sys.argv)
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index 2418b80a82..b098b95053 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -167,38 +167,44 @@ const char %(c_name)s[] = %(c_string)s;
>          arg_type = arg_type or self._schema.the_empty_object_type
>          self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
> 
> -# Debugging aid: unmask QAPI schema's type names
> -# We normally mask them, because they're not QMP wire ABI
> -opt_unmask = False
> 
> -(input_file, output_dir, do_c, do_h, prefix, opts) = \
> -    parse_command_line('u', ['unmask-non-abi-names'])
> +def main(argv):
> +    # Debugging aid: unmask QAPI schema's type names
> +    # We normally mask them, because they're not QMP wire ABI
> +    opt_unmask = False
> 
> -for o, a in opts:
> -    if o in ('-u', '--unmask-non-abi-names'):
> -        opt_unmask = True
> +    (input_file, output_dir, do_c, do_h, prefix, opts) = \
> +        parse_command_line('u', ['unmask-non-abi-names'])
> 
> -blurb = '''
> +    for o, a in opts:
> +        if o in ('-u', '--unmask-non-abi-names'):
> +            opt_unmask = True
> +
> +    blurb = '''
>   * QAPI/QMP schema introspection
>  '''
> 
> -genc = QAPIGenC(blurb, __doc__)
> -genh = QAPIGenH(blurb, __doc__)
> +    genc = QAPIGenC(blurb, __doc__)
> +    genh = QAPIGenH(blurb, __doc__)
> 
> -genc.add(mcgen('''
> +    genc.add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "%(prefix)sqmp-introspect.h"
> 
>  ''',
> -               prefix=prefix))
> -
> -schema = QAPISchema(input_file)
> -vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
> -schema.visit(vis)
> -genc.add(vis.defn)
> -genh.add(vis.decl)
> -
> -if do_c:
> -    genc.write(output_dir, prefix + 'qmp-introspect.c')
> -if do_h:
> -    genh.write(output_dir, prefix + 'qmp-introspect.h')
> +                   prefix=prefix))
> +
> +    schema = QAPISchema(input_file)
> +    vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
> +    schema.visit(vis)
> +    genc.add(vis.defn)
> +    genh.add(vis.decl)
> +
> +    if do_c:
> +        genc.write(output_dir, prefix + 'qmp-introspect.c')
> +    if do_h:
> +        genh.write(output_dir, prefix + 'qmp-introspect.h')
> +
> +
> +if __name__ == '__main__':
> +    main(sys.argv)
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 5ff2bfcf41..10955d1c01 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -240,45 +240,51 @@ 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
> -# opt_builtins, enabled by command line option -b.  See also
> -# QAPISchemaGenTypeVisitor.visit_end().
> -opt_builtins = False
> 
> -(input_file, output_dir, do_c, do_h, prefix, opts) = \
> -    parse_command_line('b', ['builtins'])
> +def main(argv):
> +    # If you link code generated from multiple schemata, you want only one
> +    # instance of the code for built-in types.  Generate it only when
> +    # opt_builtins, enabled by command line option -b.  See also
> +    # QAPISchemaGenTypeVisitor.visit_end().
> +    opt_builtins = False
> 
> -for o, a in opts:
> -    if o in ('-b', '--builtins'):
> -        opt_builtins = True
> +    (input_file, output_dir, do_c, do_h, prefix, opts) = \
> +        parse_command_line('b', ['builtins'])
> 
> -blurb = '''
> +    for o, a in opts:
> +        if o in ('-b', '--builtins'):
> +            opt_builtins = True
> +
> +    blurb = '''
>   * Schema-defined QAPI types
>  '''
> 
> -genc = QAPIGenC(blurb, __doc__)
> -genh = QAPIGenH(blurb, __doc__)
> +    genc = QAPIGenC(blurb, __doc__)
> +    genh = QAPIGenH(blurb, __doc__)
> 
> -genc.add(mcgen('''
> +    genc.add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "qapi/dealloc-visitor.h"
>  #include "%(prefix)sqapi-types.h"
>  #include "%(prefix)sqapi-visit.h"
>  ''',
> -               prefix=prefix))
> +                   prefix=prefix))
> 
> -genh.add(mcgen('''
> +    genh.add(mcgen('''
>  #include "qapi/util.h"
>  '''))
> 
> -schema = QAPISchema(input_file)
> -vis = QAPISchemaGenTypeVisitor(opt_builtins)
> -schema.visit(vis)
> -genc.add(vis.defn)
> -genh.add(vis.decl)
> +    schema = QAPISchema(input_file)
> +    vis = QAPISchemaGenTypeVisitor(opt_builtins)
> +    schema.visit(vis)
> +    genc.add(vis.defn)
> +    genh.add(vis.decl)
> 
> -if do_c:
> -    genc.write(output_dir, prefix + 'qapi-types.c')
> -if do_h:
> -    genh.write(output_dir, prefix + 'qapi-types.h')
> +    if do_c:
> +        genc.write(output_dir, prefix + 'qapi-types.c')
> +    if do_h:
> +        genh.write(output_dir, prefix + 'qapi-types.h')
> +
> +
> +if __name__ == '__main__':
> +    main(sys.argv)
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 0a1eff7736..6d829c4d1d 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -323,49 +323,55 @@ 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
> -# opt_builtins, enabled by command line option -b.  See also
> -# QAPISchemaGenVisitVisitor.visit_end().
> -opt_builtins = False
> 
> -(input_file, output_dir, do_c, do_h, prefix, opts) = \
> -    parse_command_line('b', ['builtins'])
> +def main(argv):
> +    # If you link code generated from multiple schemata, you want only one
> +    # instance of the code for built-in types.  Generate it only when
> +    # opt_builtins, enabled by command line option -b.  See also
> +    # QAPISchemaGenVisitVisitor.visit_end().
> +    opt_builtins = False
> 
> -for o, a in opts:
> -    if o in ('-b', '--builtins'):
> -        opt_builtins = True
> +    (input_file, output_dir, do_c, do_h, prefix, opts) = \
> +        parse_command_line('b', ['builtins'])
> 
> -blurb = '''
> +    for o, a in opts:
> +        if o in ('-b', '--builtins'):
> +            opt_builtins = True
> +
> +    blurb = '''
>   * Schema-defined QAPI visitors
>  '''
> 
> -genc = QAPIGenC(blurb, __doc__)
> -genh = QAPIGenH(blurb, __doc__)
> +    genc = QAPIGenC(blurb, __doc__)
> +    genh = QAPIGenH(blurb, __doc__)
> 
> -genc.add(mcgen('''
> +    genc.add(mcgen('''
>  #include "qemu/osdep.h"
>  #include "qemu-common.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qerror.h"
>  #include "%(prefix)sqapi-visit.h"
>  ''',
> -               prefix=prefix))
> +                   prefix=prefix))
> 
> -genh.add(mcgen('''
> +    genh.add(mcgen('''
>  #include "qapi/visitor.h"
>  #include "%(prefix)sqapi-types.h"
> 
>  ''',
> -               prefix=prefix))
> -
> -schema = QAPISchema(input_file)
> -vis = QAPISchemaGenVisitVisitor(opt_builtins)
> -schema.visit(vis)
> -genc.add(vis.defn)
> -genh.add(vis.decl)
> -
> -if do_c:
> -    genc.write(output_dir, prefix + 'qapi-visit.c')
> -if do_h:
> -    genh.write(output_dir, prefix + 'qapi-visit.h')
> +                   prefix=prefix))
> +
> +    schema = QAPISchema(input_file)
> +    vis = QAPISchemaGenVisitVisitor(opt_builtins)
> +    schema.visit(vis)
> +    genc.add(vis.defn)
> +    genh.add(vis.decl)
> +
> +    if do_c:
> +        genc.write(output_dir, prefix + 'qapi-visit.c')
> +    if do_h:
> +        genh.write(output_dir, prefix + 'qapi-visit.h')
> +
> +
> +if __name__ == '__main__':
> +    main(sys.argv)
> -- 
> 2.13.6
>
Eric Blake Feb. 27, 2018, 3:53 p.m. UTC | #2
On 02/11/2018 03:35 AM, Markus Armbruster wrote:
> The next commit will introduce a common driver program for all
> generators.  The generators need to be modules for that.  qapi2texi.py
> already is.  Make the other generators follow suit.
> 
> The changes are actually trivial.  Obvious in the diffs once you view
> them with whitespace changes ignored.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   scripts/qapi-commands.py   | 43 ++++++++++++++++++--------------
>   scripts/qapi-event.py      | 43 ++++++++++++++++++--------------
>   scripts/qapi-introspect.py | 54 ++++++++++++++++++++++------------------
>   scripts/qapi-types.py      | 56 ++++++++++++++++++++++-------------------
>   scripts/qapi-visit.py      | 62 +++++++++++++++++++++++++---------------------
>   5 files changed, 143 insertions(+), 115 deletions(-)

Urgh. One annoyance of this patch is that if you switch to another 
branch without the patch, leftover .pyc files in the source tree can 
cause weird errors until you 'rm -f scripts/qapi/*.pyc':

$ make -j3
   GEN     config-host.h
   GEN     qmp-commands.h
   GEN     qapi-types.h
Traceback (most recent call last):
   File "/home/eblake/qemu/scripts/qapi-commands.py", line 225, in <module>
     class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
NameError: name 'QAPISchemaVisitor' is not defined
Traceback (most recent call last):
   File "/home/eblake/qemu/scripts/qapi-types.py", line 168, in <module>
     class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
NameError: name 'QAPISchemaVisitor' is not defined
make: *** [Makefile:522: qapi-types.h] Error 1
make: *** Waiting for unfinished jobs....
make: *** [Makefile:537: qmp-commands.h] Error 1

Not a show-stopper, but annoying when toggling between branches.
Daniel P. Berrangé Feb. 27, 2018, 4:01 p.m. UTC | #3
On Tue, Feb 27, 2018 at 09:53:22AM -0600, Eric Blake wrote:
> On 02/11/2018 03:35 AM, Markus Armbruster wrote:
> > The next commit will introduce a common driver program for all
> > generators.  The generators need to be modules for that.  qapi2texi.py
> > already is.  Make the other generators follow suit.
> > 
> > The changes are actually trivial.  Obvious in the diffs once you view
> > them with whitespace changes ignored.
> > 
> > Signed-off-by: Markus Armbruster <armbru@redhat.com>
> > Reviewed-by: Eric Blake <eblake@redhat.com>
> > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   scripts/qapi-commands.py   | 43 ++++++++++++++++++--------------
> >   scripts/qapi-event.py      | 43 ++++++++++++++++++--------------
> >   scripts/qapi-introspect.py | 54 ++++++++++++++++++++++------------------
> >   scripts/qapi-types.py      | 56 ++++++++++++++++++++++-------------------
> >   scripts/qapi-visit.py      | 62 +++++++++++++++++++++++++---------------------
> >   5 files changed, 143 insertions(+), 115 deletions(-)
> 
> Urgh. One annoyance of this patch is that if you switch to another branch
> without the patch, leftover .pyc files in the source tree can cause weird
> errors until you 'rm -f scripts/qapi/*.pyc':

Pehaps make our build system set  PYTHONDONTWRITEBYTECODE=1  env variable

  https://docs.python.org/3/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE

Regards,
Daniel
Markus Armbruster April 13, 2018, 12:49 p.m. UTC | #4
Daniel P. Berrangé <berrange@redhat.com> writes:

> On Tue, Feb 27, 2018 at 09:53:22AM -0600, Eric Blake wrote:
>> On 02/11/2018 03:35 AM, Markus Armbruster wrote:
>> > The next commit will introduce a common driver program for all
>> > generators.  The generators need to be modules for that.  qapi2texi.py
>> > already is.  Make the other generators follow suit.
>> > 
>> > The changes are actually trivial.  Obvious in the diffs once you view
>> > them with whitespace changes ignored.
>> > 
>> > Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> > Reviewed-by: Eric Blake <eblake@redhat.com>
>> > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > ---
>> >   scripts/qapi-commands.py   | 43 ++++++++++++++++++--------------
>> >   scripts/qapi-event.py      | 43 ++++++++++++++++++--------------
>> >   scripts/qapi-introspect.py | 54 ++++++++++++++++++++++------------------
>> >   scripts/qapi-types.py      | 56 ++++++++++++++++++++++-------------------
>> >   scripts/qapi-visit.py      | 62 +++++++++++++++++++++++++---------------------
>> >   5 files changed, 143 insertions(+), 115 deletions(-)
>> 
>> Urgh. One annoyance of this patch is that if you switch to another branch
>> without the patch, leftover .pyc files in the source tree can cause weird
>> errors until you 'rm -f scripts/qapi/*.pyc':
>
> Pehaps make our build system set  PYTHONDONTWRITEBYTECODE=1  env variable
>
>   https://docs.python.org/3/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE

We already have configure put PYTHON=python -B into config-host.mak.

I still manage to litter my tree with .pyc files...
diff mbox

Patch

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index e97e16e828..8584cb5873 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -255,16 +255,17 @@  class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
         self._regy += gen_register_command(name, success_response)
 
 
-(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
+def main(argv):
+    (input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
 
-blurb = '''
+    blurb = '''
  * Schema-defined QAPI/QMP commands
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+    genc = QAPIGenC(blurb, __doc__)
+    genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+    genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/module.h"
@@ -279,23 +280,27 @@  genc.add(mcgen('''
 #include "%(prefix)sqmp-commands.h"
 
 ''',
-               prefix=prefix))
+                   prefix=prefix))
 
-genh.add(mcgen('''
+    genh.add(mcgen('''
 #include "%(prefix)sqapi-types.h"
 #include "qapi/qmp/dispatch.h"
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 ''',
-               prefix=prefix, c_prefix=c_name(prefix, protect=False)))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenCommandVisitor(prefix)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-    genc.write(output_dir, prefix + 'qmp-marshal.c')
-if do_h:
-    genh.write(output_dir, prefix + 'qmp-commands.h')
+                   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+
+    schema = QAPISchema(input_file)
+    vis = QAPISchemaGenCommandVisitor(prefix)
+    schema.visit(vis)
+    genc.add(vis.defn)
+    genh.add(vis.decl)
+
+    if do_c:
+        genc.write(output_dir, prefix + 'qmp-marshal.c')
+    if do_h:
+        genh.write(output_dir, prefix + 'qmp-commands.h')
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 3f98e2491a..e7e07f0055 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -171,16 +171,17 @@  class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
         self._event_names.append(name)
 
 
-(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
+def main(argv):
+    (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
 
-blurb = '''
+    blurb = '''
  * Schema-defined QAPI/QMP events
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+    genc = QAPIGenC(blurb, __doc__)
+    genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+    genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "%(prefix)sqapi-event.h"
@@ -191,22 +192,26 @@  genc.add(mcgen('''
 #include "qapi/qmp-event.h"
 
 ''',
-               prefix=prefix))
+                   prefix=prefix))
 
-genh.add(mcgen('''
+    genh.add(mcgen('''
 #include "qapi/util.h"
 #include "%(prefix)sqapi-types.h"
 
 ''',
-               prefix=prefix))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenEventVisitor(prefix)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-    genc.write(output_dir, prefix + 'qapi-event.c')
-if do_h:
-    genh.write(output_dir, prefix + 'qapi-event.h')
+                   prefix=prefix))
+
+    schema = QAPISchema(input_file)
+    vis = QAPISchemaGenEventVisitor(prefix)
+    schema.visit(vis)
+    genc.add(vis.defn)
+    genh.add(vis.decl)
+
+    if do_c:
+        genc.write(output_dir, prefix + 'qapi-event.c')
+    if do_h:
+        genh.write(output_dir, prefix + 'qapi-event.h')
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 2418b80a82..b098b95053 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -167,38 +167,44 @@  const char %(c_name)s[] = %(c_string)s;
         arg_type = arg_type or self._schema.the_empty_object_type
         self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
 
-# Debugging aid: unmask QAPI schema's type names
-# We normally mask them, because they're not QMP wire ABI
-opt_unmask = False
 
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
-    parse_command_line('u', ['unmask-non-abi-names'])
+def main(argv):
+    # Debugging aid: unmask QAPI schema's type names
+    # We normally mask them, because they're not QMP wire ABI
+    opt_unmask = False
 
-for o, a in opts:
-    if o in ('-u', '--unmask-non-abi-names'):
-        opt_unmask = True
+    (input_file, output_dir, do_c, do_h, prefix, opts) = \
+        parse_command_line('u', ['unmask-non-abi-names'])
 
-blurb = '''
+    for o, a in opts:
+        if o in ('-u', '--unmask-non-abi-names'):
+            opt_unmask = True
+
+    blurb = '''
  * QAPI/QMP schema introspection
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+    genc = QAPIGenC(blurb, __doc__)
+    genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+    genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqmp-introspect.h"
 
 ''',
-               prefix=prefix))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-    genc.write(output_dir, prefix + 'qmp-introspect.c')
-if do_h:
-    genh.write(output_dir, prefix + 'qmp-introspect.h')
+                   prefix=prefix))
+
+    schema = QAPISchema(input_file)
+    vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
+    schema.visit(vis)
+    genc.add(vis.defn)
+    genh.add(vis.decl)
+
+    if do_c:
+        genc.write(output_dir, prefix + 'qmp-introspect.c')
+    if do_h:
+        genh.write(output_dir, prefix + 'qmp-introspect.h')
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5ff2bfcf41..10955d1c01 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -240,45 +240,51 @@  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
-# opt_builtins, enabled by command line option -b.  See also
-# QAPISchemaGenTypeVisitor.visit_end().
-opt_builtins = False
 
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
-    parse_command_line('b', ['builtins'])
+def main(argv):
+    # If you link code generated from multiple schemata, you want only one
+    # instance of the code for built-in types.  Generate it only when
+    # opt_builtins, enabled by command line option -b.  See also
+    # QAPISchemaGenTypeVisitor.visit_end().
+    opt_builtins = False
 
-for o, a in opts:
-    if o in ('-b', '--builtins'):
-        opt_builtins = True
+    (input_file, output_dir, do_c, do_h, prefix, opts) = \
+        parse_command_line('b', ['builtins'])
 
-blurb = '''
+    for o, a in opts:
+        if o in ('-b', '--builtins'):
+            opt_builtins = True
+
+    blurb = '''
  * Schema-defined QAPI types
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+    genc = QAPIGenC(blurb, __doc__)
+    genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+    genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qapi/dealloc-visitor.h"
 #include "%(prefix)sqapi-types.h"
 #include "%(prefix)sqapi-visit.h"
 ''',
-               prefix=prefix))
+                   prefix=prefix))
 
-genh.add(mcgen('''
+    genh.add(mcgen('''
 #include "qapi/util.h"
 '''))
 
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenTypeVisitor(opt_builtins)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
+    schema = QAPISchema(input_file)
+    vis = QAPISchemaGenTypeVisitor(opt_builtins)
+    schema.visit(vis)
+    genc.add(vis.defn)
+    genh.add(vis.decl)
 
-if do_c:
-    genc.write(output_dir, prefix + 'qapi-types.c')
-if do_h:
-    genh.write(output_dir, prefix + 'qapi-types.h')
+    if do_c:
+        genc.write(output_dir, prefix + 'qapi-types.c')
+    if do_h:
+        genh.write(output_dir, prefix + 'qapi-types.h')
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 0a1eff7736..6d829c4d1d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -323,49 +323,55 @@  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
-# opt_builtins, enabled by command line option -b.  See also
-# QAPISchemaGenVisitVisitor.visit_end().
-opt_builtins = False
 
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
-    parse_command_line('b', ['builtins'])
+def main(argv):
+    # If you link code generated from multiple schemata, you want only one
+    # instance of the code for built-in types.  Generate it only when
+    # opt_builtins, enabled by command line option -b.  See also
+    # QAPISchemaGenVisitVisitor.visit_end().
+    opt_builtins = False
 
-for o, a in opts:
-    if o in ('-b', '--builtins'):
-        opt_builtins = True
+    (input_file, output_dir, do_c, do_h, prefix, opts) = \
+        parse_command_line('b', ['builtins'])
 
-blurb = '''
+    for o, a in opts:
+        if o in ('-b', '--builtins'):
+            opt_builtins = True
+
+    blurb = '''
  * Schema-defined QAPI visitors
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+    genc = QAPIGenC(blurb, __doc__)
+    genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+    genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
 #include "%(prefix)sqapi-visit.h"
 ''',
-               prefix=prefix))
+                   prefix=prefix))
 
-genh.add(mcgen('''
+    genh.add(mcgen('''
 #include "qapi/visitor.h"
 #include "%(prefix)sqapi-types.h"
 
 ''',
-               prefix=prefix))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenVisitVisitor(opt_builtins)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-    genc.write(output_dir, prefix + 'qapi-visit.c')
-if do_h:
-    genh.write(output_dir, prefix + 'qapi-visit.h')
+                   prefix=prefix))
+
+    schema = QAPISchema(input_file)
+    vis = QAPISchemaGenVisitVisitor(opt_builtins)
+    schema.visit(vis)
+    genc.add(vis.defn)
+    genh.add(vis.decl)
+
+    if do_c:
+        genc.write(output_dir, prefix + 'qapi-visit.c')
+    if do_h:
+        genh.write(output_dir, prefix + 'qapi-visit.h')
+
+
+if __name__ == '__main__':
+    main(sys.argv)