From: "Benoît Canet" <benoit.canet@irqsave.net>
To: qemu-devel@nongnu.org
Cc: "Benoît Canet" <benoit.canet@irqsave.net>,
wenchaoqemu@gmail.com, armbru@redhat.com, lcapitulino@redhat.com,
anthony@codemonkey.ws, "Benoit Canet" <benoit@irqsave.net>
Subject: [Qemu-devel] [PATCH V2 3/3] qapi: Create an include directive for use in the JSON description files.
Date: Thu, 27 Mar 2014 16:33:19 +0100 [thread overview]
Message-ID: <1395934399-18769-4-git-send-email-benoit.canet@irqsave.net> (raw)
In-Reply-To: <1395934399-18769-1-git-send-email-benoit.canet@irqsave.net>
The new directive in the form { 'include': 'path/to/file.json' } will trigger the
parsing of path/to/file.json.
The directive will be replaced by the result of the parsing.
This will allow for easy modularisation of qapi JSON descriptions files.
Signed-off-by: Benoit Canet <benoit@irqsave.net>
---
docs/qapi-code-gen.txt | 14 ++++++++++++++
scripts/qapi.py | 17 ++++++++++++++++-
tests/Makefile | 2 +-
tests/qapi-schema/include.exit | 1 +
tests/qapi-schema/include.json | 4 ++++
tests/qapi-schema/include.out | 8 ++++++++
tests/qapi-schema/include/include.json | 7 +++++++
tests/qapi-schema/include_loop.exit | 1 +
tests/qapi-schema/include_loop.json | 1 +
tests/qapi-schema/include_loop.out | 1 +
10 files changed, 54 insertions(+), 2 deletions(-)
create mode 100644 tests/qapi-schema/include.err
create mode 100644 tests/qapi-schema/include.exit
create mode 100644 tests/qapi-schema/include.json
create mode 100644 tests/qapi-schema/include.out
create mode 100644 tests/qapi-schema/include/include.json
create mode 100644 tests/qapi-schema/include_loop.err
create mode 100644 tests/qapi-schema/include_loop.exit
create mode 100644 tests/qapi-schema/include_loop.json
create mode 100644 tests/qapi-schema/include_loop.out
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index d78921f..a16aa47 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -180,6 +180,20 @@ An example command is:
'data': { 'arg1': 'str', '*arg2': 'str' },
'returns': 'str' }
+=== Includes ===
+
+A schema file can include other sub schema files with the include
+directive.
+
+An example of include directive is:
+
+{ 'include': 'path/to/sub_schema.json' }
+
+The include path is relative to the current schema file.
+The include parsing method is recursive.
+The expressions resulting from the parsing of the sub schema are injected
+in place of the include directive like a C #include would do.
+
== Code generation ==
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 597042a..0b0c8e4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -269,6 +269,8 @@ def check_exprs(schema):
if expr.has_key('union'):
check_union(expr, expr_elem['info'])
+modules = []
+
def build_schema(path):
with open(path, "r") as fp:
try:
@@ -281,13 +283,26 @@ def build_schema(path):
def parse_schema(path):
path = os.path.abspath(path)
+ if path in modules:
+ print "Module inclusion loop detected with module: %s" %\
+ get_filename(path)
+ sys.exit(1)
+
+ modules.append(path)
+
schema = build_schema(path)
exprs = []
for expr_elem in schema.exprs:
expr = expr_elem['expr']
- if expr.has_key('enum'):
+ if expr.has_key('include'):
+ prefix = os.path.split(path)[0]
+ sub_path = os.path.join(prefix, expr['include'])
+ sub_exprs = parse_schema(sub_path)
+ exprs += sub_exprs
+ continue
+ elif expr.has_key('enum'):
add_enum(expr['enum'], expr['data'])
elif expr.has_key('union'):
add_union(expr)
diff --git a/tests/Makefile b/tests/Makefile
index c4ed5c2..b5e4cf0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -164,7 +164,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
duplicate-key.json union-invalid-base.json flat-union-no-base.json \
flat-union-invalid-discriminator.json \
flat-union-invalid-branch-key.json flat-union-reverse-define.json \
- flat-union-string-discriminator.json)
+ flat-union-string-discriminator.json include.json include_loop.json)
GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
diff --git a/tests/qapi-schema/include.err b/tests/qapi-schema/include.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include.exit b/tests/qapi-schema/include.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/include.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/include.json b/tests/qapi-schema/include.json
new file mode 100644
index 0000000..ffece21
--- /dev/null
+++ b/tests/qapi-schema/include.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
+{ 'include': './include/include.json' }
+{ 'foo': '42' }
diff --git a/tests/qapi-schema/include.out b/tests/qapi-schema/include.out
new file mode 100644
index 0000000..89e43e8
--- /dev/null
+++ b/tests/qapi-schema/include.out
@@ -0,0 +1,8 @@
+[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])]),
+ OrderedDict([('bar', '33')]),
+ OrderedDict([('enum', 'Fruits'), ('data', ['orange', 'apple', 'gooseberry'])]),
+ OrderedDict([('baz', '54')]),
+ OrderedDict([('foo', '42')])]
+[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']},
+ {'enum_name': 'Fruits', 'enum_values': ['orange', 'apple', 'gooseberry']}]
+[]
diff --git a/tests/qapi-schema/include/include.json b/tests/qapi-schema/include/include.json
new file mode 100644
index 0000000..f445eee
--- /dev/null
+++ b/tests/qapi-schema/include/include.json
@@ -0,0 +1,7 @@
+
+{ 'bar': '33' }
+
+{ 'enum': 'Fruits',
+ 'data': [ 'orange', 'apple', 'gooseberry' ] }
+
+{ 'baz': '54' }
diff --git a/tests/qapi-schema/include_loop.err b/tests/qapi-schema/include_loop.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include_loop.exit b/tests/qapi-schema/include_loop.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include_loop.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include_loop.json b/tests/qapi-schema/include_loop.json
new file mode 100644
index 0000000..cb8ff03
--- /dev/null
+++ b/tests/qapi-schema/include_loop.json
@@ -0,0 +1 @@
+{ 'include': 'include_loop.json' }
diff --git a/tests/qapi-schema/include_loop.out b/tests/qapi-schema/include_loop.out
new file mode 100644
index 0000000..35da4dd
--- /dev/null
+++ b/tests/qapi-schema/include_loop.out
@@ -0,0 +1 @@
+Module inclusion loop detected with module: include_loop.json
--
1.7.10.4
next prev parent reply other threads:[~2014-03-27 15:33 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-27 15:33 [Qemu-devel] [PATCH V2 0/3] Create an include directive for QAPI JSON files Benoît Canet
2014-03-27 15:33 ` [Qemu-devel] [PATCH V2 1/3] test-qapi: Make test-qapi.py spit useful error messages Benoît Canet
2014-03-27 15:33 ` [Qemu-devel] [PATCH V2 2/3] qapi: Change the qapi scripts to take their input as first argument Benoît Canet
2014-03-27 17:27 ` Eric Blake
2014-03-28 8:27 ` Markus Armbruster
2014-03-27 17:56 ` Markus Armbruster
2014-03-27 15:33 ` Benoît Canet [this message]
2014-03-27 17:39 ` [Qemu-devel] [PATCH V2 3/3] qapi: Create an include directive for use in the JSON description files Eric Blake
2014-03-27 18:07 ` Markus Armbruster
2014-03-27 19:46 ` Benoît Canet
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=1395934399-18769-4-git-send-email-benoit.canet@irqsave.net \
--to=benoit.canet@irqsave.net \
--cc=anthony@codemonkey.ws \
--cc=armbru@redhat.com \
--cc=benoit@irqsave.net \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=wenchaoqemu@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).