From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56023) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WlK6B-0003Rw-Vi for qemu-devel@nongnu.org; Fri, 16 May 2014 11:31:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WlK66-0006FH-95 for qemu-devel@nongnu.org; Fri, 16 May 2014 11:31:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:16620) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WlK66-0006FD-1y for qemu-devel@nongnu.org; Fri, 16 May 2014 11:30:58 -0400 From: Luiz Capitulino Date: Fri, 16 May 2014 11:30:35 -0400 Message-Id: <1400254235-9435-21-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1400254235-9435-1-git-send-email-lcapitulino@redhat.com> References: <1400254235-9435-1-git-send-email-lcapitulino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 20/20] qapi: skip redundant includes List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: peter.maydell@linaro.org Cc: qemu-devel@nongnu.org, anthony@codemonkey.ws From: Beno=C3=AEt Canet The purpose of this change is to help create a json file containing common definitions; each bit of generated C code must be emitted only one time. A second history global to all QAPISchema instances has been added to detect when a file is included more than one time and skip these includes. It does not act as a stack and the changes made to it by the __init__ function are propagated back to the caller so it's really a global state. Signed-off-by: Benoit Canet Reviewed-by: Eric Blake Signed-off-by: Luiz Capitulino --- docs/qapi-code-gen.txt | 2 +- scripts/qapi.py | 14 +++++++++++--- tests/Makefile | 3 ++- tests/qapi-schema/include-repetition-sub.json | 2 ++ tests/qapi-schema/include-repetition.err | 0 tests/qapi-schema/include-repetition.exit | 1 + tests/qapi-schema/include-repetition.json | 3 +++ tests/qapi-schema/include-repetition.out | 3 +++ 8 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 tests/qapi-schema/include-repetition-sub.json create mode 100644 tests/qapi-schema/include-repetition.err create mode 100644 tests/qapi-schema/include-repetition.exit create mode 100644 tests/qapi-schema/include-repetition.json create mode 100644 tests/qapi-schema/include-repetition.out diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 867d124..dea0d50 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -48,7 +48,7 @@ The QAPI schema definitions can be modularized using th= e 'include' directive: { 'include': 'path/to/file.json'} =20 The directive is evaluated recursively, and include paths are relative t= o the -file using the directive. +file using the directive. Multiple includes of the same file are safe. =20 =20 =3D=3D=3D Complex types =3D=3D=3D diff --git a/scripts/qapi.py b/scripts/qapi.py index ec806aa..0265b40 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -73,13 +73,18 @@ class QAPIExprError(Exception): =20 class QAPISchema: =20 - def __init__(self, fp, input_relname=3DNone, include_hist=3D[], pare= nt_info=3DNone): + def __init__(self, fp, input_relname=3DNone, include_hist=3D[], + previously_included=3D[], parent_info=3DNone): + """ include_hist is a stack used to detect inclusion cycles + previously_included is a global state used to avoid multiple + inclusions of the same file""" input_fname =3D os.path.abspath(fp.name) if input_relname is None: input_relname =3D fp.name self.input_dir =3D os.path.dirname(input_fname) self.input_file =3D input_relname self.include_hist =3D include_hist + [(input_relname, input_fnam= e)] + previously_included.append(input_fname) self.parent_info =3D parent_info self.src =3D fp.read() if self.src =3D=3D '' or self.src[-1] !=3D '\n': @@ -106,13 +111,16 @@ class QAPISchema: for elem in self.include_hist): raise QAPIExprError(expr_info, "Inclusion loop for %= s" % include) + # skip multiple include of the same file + if include_path in previously_included: + continue try: fobj =3D open(include_path, 'r') except IOError as e: raise QAPIExprError(expr_info, '%s: %s' % (e.strerror, include)= ) - exprs_include =3D QAPISchema(fobj, include, - self.include_hist, expr_info) + exprs_include =3D QAPISchema(fobj, include, self.include= _hist, + previously_included, expr_inf= o) self.exprs.extend(exprs_include.exprs) else: expr_elem =3D {'expr': expr, diff --git a/tests/Makefile b/tests/Makefile index 6b8b6f2..9f7ca61 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -193,7 +193,8 @@ check-qapi-schema-y :=3D $(addprefix tests/qapi-schem= a/, \ flat-union-string-discriminator.json \ include-simple.json include-relpath.json include-format-err.json= \ include-non-file.json include-no-file.json include-before-err.js= on \ - include-nested-err.json include-self-cycle.json include-cycle.js= on) + include-nested-err.json include-self-cycle.json include-cycle.js= on \ + include-repetition.json) =20 GENERATED_HEADERS +=3D tests/test-qapi-types.h tests/test-qapi-visit.h t= ests/test-qmp-commands.h =20 diff --git a/tests/qapi-schema/include-repetition-sub.json b/tests/qapi-s= chema/include-repetition-sub.json new file mode 100644 index 0000000..6bfffdf --- /dev/null +++ b/tests/qapi-schema/include-repetition-sub.json @@ -0,0 +1,2 @@ +{ 'include': 'comments.json' } +{ 'include': 'comments.json' } diff --git a/tests/qapi-schema/include-repetition.err b/tests/qapi-schema= /include-repetition.err new file mode 100644 index 0000000..e69de29 diff --git a/tests/qapi-schema/include-repetition.exit b/tests/qapi-schem= a/include-repetition.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/qapi-schema/include-repetition.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/include-repetition.json b/tests/qapi-schem= a/include-repetition.json new file mode 100644 index 0000000..ec329dd --- /dev/null +++ b/tests/qapi-schema/include-repetition.json @@ -0,0 +1,3 @@ +{ 'include': 'comments.json' } +{ 'include': 'include-repetition-sub.json' } +{ 'include': 'comments.json' } diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema= /include-repetition.out new file mode 100644 index 0000000..4ce3dcf --- /dev/null +++ b/tests/qapi-schema/include-repetition.out @@ -0,0 +1,3 @@ +[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])] +[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}] +[] --=20 1.9.0