* [Qemu-devel] [PATCH V3 2/3] qapi: Change the qapi scripts to take their input as first argument.
2014-03-28 16:25 [Qemu-devel] [PATCH V3 0/3] Create an include directive for QAPI JSON files Benoît Canet
2014-03-28 16:25 ` [Qemu-devel] [PATCH V3 1/3] test-qapi: Make test-qapi.py spit useful error messages Benoît Canet
@ 2014-03-28 16:25 ` Benoît Canet
2014-03-28 16:25 ` [Qemu-devel] [PATCH V3 3/3] qapi: Create an include directive for use in the JSON description files Benoît Canet
2014-05-15 12:55 ` [Qemu-devel] [PATCH V3 0/3] Create an include directive for QAPI JSON files Wenchao Xia
3 siblings, 0 replies; 7+ messages in thread
From: Benoît Canet @ 2014-03-28 16:25 UTC (permalink / raw)
To: qemu-devel
Cc: Benoît Canet, wenchaoqemu, armbru, lcapitulino, anthony,
Benoit Canet
This patch is here to pave the way for the JSON include directive which
will need to do include loop detection.
Signed-off-by: Benoit Canet <benoit@irqsave.net>
---
Makefile | 12 ++++++------
scripts/qapi-commands.py | 6 +++++-
scripts/qapi-types.py | 6 +++++-
scripts/qapi-visit.py | 6 +++++-
scripts/qapi.py | 18 ++++++++++++------
tests/Makefile | 16 +++++++++-------
tests/qapi-schema/duplicate-key.err | 2 +-
tests/qapi-schema/flat-union-invalid-branch-key.err | 2 +-
.../qapi-schema/flat-union-invalid-discriminator.err | 2 +-
tests/qapi-schema/flat-union-no-base.err | 2 +-
.../qapi-schema/flat-union-string-discriminator.err | 2 +-
tests/qapi-schema/funny-char.err | 2 +-
tests/qapi-schema/missing-colon.err | 2 +-
tests/qapi-schema/missing-comma-list.err | 2 +-
tests/qapi-schema/missing-comma-object.err | 2 +-
tests/qapi-schema/non-objects.err | 2 +-
tests/qapi-schema/quoted-structural-chars.err | 2 +-
tests/qapi-schema/test-qapi.py | 6 +++++-
tests/qapi-schema/trailing-comma-list.err | 2 +-
tests/qapi-schema/trailing-comma-object.err | 2 +-
tests/qapi-schema/unclosed-list.err | 2 +-
tests/qapi-schema/unclosed-object.err | 2 +-
tests/qapi-schema/unclosed-string.err | 2 +-
tests/qapi-schema/union-invalid-base.err | 2 +-
24 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/Makefile b/Makefile
index ec74039..f420140 100644
--- a/Makefile
+++ b/Makefile
@@ -237,23 +237,23 @@ qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, " GEN $@")
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, " GEN $@")
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, " GEN $@")
qapi-types.c qapi-types.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b $<, " GEN $@")
qapi-visit.c qapi-visit.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b $<, " GEN $@")
qmp-commands.h qmp-marshal.c :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." $<, " GEN $@")
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 9734ab0..ad366a0 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -376,6 +376,10 @@ except getopt.GetoptError, err:
print str(err)
sys.exit(1)
+if len(args) != 1:
+ print "The non optional argument must be the file name to parse"
+ sys.exit(1)
+
output_dir = ""
prefix = ""
dispatch_type = "sync"
@@ -420,7 +424,7 @@ except os.error, e:
if e.errno != errno.EEXIST:
raise
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(args[0])
commands = filter(lambda expr: expr.has_key('command'), exprs)
commands = filter(lambda expr: not expr.has_key('gen'), commands)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 10864ef..08159fd 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -286,6 +286,10 @@ except getopt.GetoptError, err:
print str(err)
sys.exit(1)
+if len(args) != 1:
+ print "The non optional argument must be the file name to parse"
+ sys.exit(1)
+
output_dir = ""
prefix = ""
c_file = 'qapi-types.c'
@@ -378,7 +382,7 @@ fdecl.write(mcgen('''
''',
guard=guardname(h_file)))
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(args[0])
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 45ce3a9..dce307a 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -404,6 +404,10 @@ except getopt.GetoptError, err:
print str(err)
sys.exit(1)
+if len(args) != 1:
+ print "The non optional argument must be the file name to parse"
+ sys.exit(1)
+
output_dir = ""
prefix = ""
c_file = 'qapi-visit.c'
@@ -494,7 +498,7 @@ fdecl.write(mcgen('''
''',
prefix=prefix, guard=guardname(h_file)))
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(args[0])
# to avoid header dependency hell, we always generate declarations
# for built-in types in our header files and simply guard them
diff --git a/scripts/qapi.py b/scripts/qapi.py
index b474c39..ae3f756 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -12,6 +12,7 @@
# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
+import os
import sys
builtin_types = [
@@ -263,12 +264,17 @@ def check_exprs(schema):
if expr.has_key('union'):
check_union(expr, expr_elem['info'])
-def parse_schema(fp):
- try:
- schema = QAPISchema(fp)
- except QAPISchemaError, e:
- print >>sys.stderr, e
- exit(1)
+def build_schema(filename):
+ with open(filename, "r") as fp:
+ try:
+ schema = QAPISchema(fp)
+ except QAPISchemaError, e:
+ print >>sys.stderr, e
+ exit(1)
+ return schema
+
+def parse_schema(filename):
+ schema = build_schema(filename)
exprs = []
diff --git a/tests/Makefile b/tests/Makefile
index 2d021fb..0a3c439 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -215,14 +215,14 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
libqemuutil.a
tests/test-qapi-types.c tests/test-qapi-types.h :\
-$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
+$(SRC_PATH)/scripts/qapi-types.py
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
tests/test-qapi-visit.c tests/test-qapi-visit.h :\
-$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
+$(SRC_PATH)/scripts/qapi-visit.py
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
-$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
+$(SRC_PATH)/scripts/qapi-commands.py
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
@@ -362,7 +362,9 @@ check-tests/test-qapi.py: tests/test-qapi.py
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
$(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 $$? >$*.test.exit, " TEST $*.out")
+ $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py $^ >$*.test.out 2>$*.test.err; echo $$? >$*.test.exit, " TEST $*.out")
+# filter in a second step to avoid redirection madness
+ @sed -i s=.*/== $*.test.err
@diff -q $(SRC_PATH)/$*.out $*.test.out
@diff -q $(SRC_PATH)/$*.err $*.test.err
@diff -q $(SRC_PATH)/$*.exit $*.test.exit
diff --git a/tests/qapi-schema/duplicate-key.err b/tests/qapi-schema/duplicate-key.err
index 0801c6a..21303ef 100644
--- a/tests/qapi-schema/duplicate-key.err
+++ b/tests/qapi-schema/duplicate-key.err
@@ -1 +1 @@
-<stdin>:2:10: Duplicate key "key"
+duplicate-key.json:2:10: Duplicate key "key"
diff --git a/tests/qapi-schema/flat-union-invalid-branch-key.err b/tests/qapi-schema/flat-union-invalid-branch-key.err
index 1125caf..34b4584 100644
--- a/tests/qapi-schema/flat-union-invalid-branch-key.err
+++ b/tests/qapi-schema/flat-union-invalid-branch-key.err
@@ -1 +1 @@
-<stdin>:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
+flat-union-invalid-branch-key.json:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.err b/tests/qapi-schema/flat-union-invalid-discriminator.err
index cad9dbf..b6ce3b7 100644
--- a/tests/qapi-schema/flat-union-invalid-discriminator.err
+++ b/tests/qapi-schema/flat-union-invalid-discriminator.err
@@ -1 +1 @@
-<stdin>:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
+flat-union-invalid-discriminator.json:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
diff --git a/tests/qapi-schema/flat-union-no-base.err b/tests/qapi-schema/flat-union-no-base.err
index e2d7443..7929455 100644
--- a/tests/qapi-schema/flat-union-no-base.err
+++ b/tests/qapi-schema/flat-union-no-base.err
@@ -1 +1 @@
-<stdin>:7: Flat union 'TestUnion' must have a base field
+flat-union-no-base.json:7: Flat union 'TestUnion' must have a base field
diff --git a/tests/qapi-schema/flat-union-string-discriminator.err b/tests/qapi-schema/flat-union-string-discriminator.err
index 8748270..fc1e2d5 100644
--- a/tests/qapi-schema/flat-union-string-discriminator.err
+++ b/tests/qapi-schema/flat-union-string-discriminator.err
@@ -1 +1 @@
-<stdin>:13: Discriminator 'kind' must be of enumeration type
+flat-union-string-discriminator.json:13: Discriminator 'kind' must be of enumeration type
diff --git a/tests/qapi-schema/funny-char.err b/tests/qapi-schema/funny-char.err
index d3dd293..ee65869 100644
--- a/tests/qapi-schema/funny-char.err
+++ b/tests/qapi-schema/funny-char.err
@@ -1 +1 @@
-<stdin>:2:36: Stray ";"
+funny-char.json:2:36: Stray ";"
diff --git a/tests/qapi-schema/missing-colon.err b/tests/qapi-schema/missing-colon.err
index 9f2a355..676cce5 100644
--- a/tests/qapi-schema/missing-colon.err
+++ b/tests/qapi-schema/missing-colon.err
@@ -1 +1 @@
-<stdin>:1:10: Expected ":"
+missing-colon.json:1:10: Expected ":"
diff --git a/tests/qapi-schema/missing-comma-list.err b/tests/qapi-schema/missing-comma-list.err
index 4fe0700..d0ed8c3 100644
--- a/tests/qapi-schema/missing-comma-list.err
+++ b/tests/qapi-schema/missing-comma-list.err
@@ -1 +1 @@
-<stdin>:2:20: Expected "," or "]"
+missing-comma-list.json:2:20: Expected "," or "]"
diff --git a/tests/qapi-schema/missing-comma-object.err b/tests/qapi-schema/missing-comma-object.err
index b0121b5..ad9b457 100644
--- a/tests/qapi-schema/missing-comma-object.err
+++ b/tests/qapi-schema/missing-comma-object.err
@@ -1 +1 @@
-<stdin>:2:3: Expected "," or "}"
+missing-comma-object.json:2:3: Expected "," or "}"
diff --git a/tests/qapi-schema/non-objects.err b/tests/qapi-schema/non-objects.err
index a6c2dc2..e958cf0 100644
--- a/tests/qapi-schema/non-objects.err
+++ b/tests/qapi-schema/non-objects.err
@@ -1 +1 @@
-<stdin>:1:1: Expected "{"
+non-objects.json:1:1: Expected "{"
diff --git a/tests/qapi-schema/quoted-structural-chars.err b/tests/qapi-schema/quoted-structural-chars.err
index a6c2dc2..77732d0 100644
--- a/tests/qapi-schema/quoted-structural-chars.err
+++ b/tests/qapi-schema/quoted-structural-chars.err
@@ -1 +1 @@
-<stdin>:1:1: Expected "{"
+quoted-structural-chars.json:1:1: Expected "{"
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index ac6da13..c9e740e 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -14,8 +14,12 @@ from qapi import *
from pprint import pprint
import sys
+if len(sys.argv) != 2:
+ print("The file name to parse must be provided.")
+ sys.exit(1)
+
try:
- exprs = parse_schema(sys.stdin)
+ exprs = parse_schema(sys.argv[1])
except SystemExit:
raise
except Exception, e:
diff --git a/tests/qapi-schema/trailing-comma-list.err b/tests/qapi-schema/trailing-comma-list.err
index ff839a3..13b79f9 100644
--- a/tests/qapi-schema/trailing-comma-list.err
+++ b/tests/qapi-schema/trailing-comma-list.err
@@ -1 +1 @@
-<stdin>:2:36: Expected "{", "[" or string
+trailing-comma-list.json:2:36: Expected "{", "[" or string
diff --git a/tests/qapi-schema/trailing-comma-object.err b/tests/qapi-schema/trailing-comma-object.err
index f540962..d1d57f0 100644
--- a/tests/qapi-schema/trailing-comma-object.err
+++ b/tests/qapi-schema/trailing-comma-object.err
@@ -1 +1 @@
-<stdin>:2:38: Expected string
+trailing-comma-object.json:2:38: Expected string
diff --git a/tests/qapi-schema/unclosed-list.err b/tests/qapi-schema/unclosed-list.err
index 0e837a7..1a699a2 100644
--- a/tests/qapi-schema/unclosed-list.err
+++ b/tests/qapi-schema/unclosed-list.err
@@ -1 +1 @@
-<stdin>:1:20: Expected "," or "]"
+unclosed-list.json:1:20: Expected "," or "]"
diff --git a/tests/qapi-schema/unclosed-object.err b/tests/qapi-schema/unclosed-object.err
index e6dc950..3ddb126 100644
--- a/tests/qapi-schema/unclosed-object.err
+++ b/tests/qapi-schema/unclosed-object.err
@@ -1 +1 @@
-<stdin>:1:21: Expected "," or "}"
+unclosed-object.json:1:21: Expected "," or "}"
diff --git a/tests/qapi-schema/unclosed-string.err b/tests/qapi-schema/unclosed-string.err
index 948d883..cdd3dca 100644
--- a/tests/qapi-schema/unclosed-string.err
+++ b/tests/qapi-schema/unclosed-string.err
@@ -1 +1 @@
-<stdin>:1:11: Missing terminating "'"
+unclosed-string.json:1:11: Missing terminating "'"
diff --git a/tests/qapi-schema/union-invalid-base.err b/tests/qapi-schema/union-invalid-base.err
index dd8e3d1..5e38b12 100644
--- a/tests/qapi-schema/union-invalid-base.err
+++ b/tests/qapi-schema/union-invalid-base.err
@@ -1 +1 @@
-<stdin>:7: Base 'TestBaseWrong' is not a valid type
+union-invalid-base.json:7: Base 'TestBaseWrong' is not a valid type
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH V3 3/3] qapi: Create an include directive for use in the JSON description files.
2014-03-28 16:25 [Qemu-devel] [PATCH V3 0/3] Create an include directive for QAPI JSON files Benoît Canet
2014-03-28 16:25 ` [Qemu-devel] [PATCH V3 1/3] test-qapi: Make test-qapi.py spit useful error messages Benoît Canet
2014-03-28 16:25 ` [Qemu-devel] [PATCH V3 2/3] qapi: Change the qapi scripts to take their input as first argument Benoît Canet
@ 2014-03-28 16:25 ` Benoît Canet
2014-03-31 16:45 ` Eric Blake
2014-05-15 12:55 ` [Qemu-devel] [PATCH V3 0/3] Create an include directive for QAPI JSON files Wenchao Xia
3 siblings, 1 reply; 7+ messages in thread
From: Benoît Canet @ 2014-03-28 16:25 UTC (permalink / raw)
To: qemu-devel
Cc: Benoît Canet, wenchaoqemu, armbru, lcapitulino, anthony,
Benoit Canet
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 | 38 +++++++++++++++++++-
tests/Makefile | 8 +++--
.../qapi-schema/error_after_sucessful_include.err | 1 +
.../qapi-schema/error_after_sucessful_include.exit | 1 +
.../qapi-schema/error_after_sucessful_include.json | 4 +++
tests/qapi-schema/error_in_included_file.err | 1 +
tests/qapi-schema/error_in_included_file.exit | 1 +
tests/qapi-schema/error_in_included_file.json | 4 +++
tests/qapi-schema/include.exit | 1 +
tests/qapi-schema/include.json | 4 +++
tests/qapi-schema/include.out | 8 +++++
tests/qapi-schema/include/error.json | 6 ++++
tests/qapi-schema/include/include.json | 7 ++++
tests/qapi-schema/include/multi.json | 1 +
tests/qapi-schema/include/multi_loop.json | 1 +
tests/qapi-schema/include_loop.exit | 1 +
tests/qapi-schema/include_loop.json | 1 +
tests/qapi-schema/include_loop.out | 3 ++
tests/qapi-schema/include_non_filename.err | 1 +
tests/qapi-schema/include_non_filename.exit | 1 +
tests/qapi-schema/include_non_filename.json | 4 +++
tests/qapi-schema/multi_file_loop_include.exit | 1 +
tests/qapi-schema/multi_file_loop_include.json | 4 +++
tests/qapi-schema/multi_file_loop_include.out | 4 +++
.../multiple_relative_path_include.exit | 1 +
.../multiple_relative_path_include.json | 4 +++
.../qapi-schema/multiple_relative_path_include.out | 6 ++++
28 files changed, 128 insertions(+), 3 deletions(-)
create mode 100644 tests/qapi-schema/error_after_sucessful_include.err
create mode 100644 tests/qapi-schema/error_after_sucessful_include.exit
create mode 100644 tests/qapi-schema/error_after_sucessful_include.json
create mode 100644 tests/qapi-schema/error_after_sucessful_include.out
create mode 100644 tests/qapi-schema/error_in_included_file.err
create mode 100644 tests/qapi-schema/error_in_included_file.exit
create mode 100644 tests/qapi-schema/error_in_included_file.json
create mode 100644 tests/qapi-schema/error_in_included_file.out
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/error.json
create mode 100644 tests/qapi-schema/include/include.json
create mode 100644 tests/qapi-schema/include/multi.json
create mode 100644 tests/qapi-schema/include/multi_loop.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
create mode 100644 tests/qapi-schema/include_non_filename.err
create mode 100644 tests/qapi-schema/include_non_filename.exit
create mode 100644 tests/qapi-schema/include_non_filename.json
create mode 100644 tests/qapi-schema/include_non_filename.out
create mode 100644 tests/qapi-schema/multi_file_loop_include.err
create mode 100644 tests/qapi-schema/multi_file_loop_include.exit
create mode 100644 tests/qapi-schema/multi_file_loop_include.json
create mode 100644 tests/qapi-schema/multi_file_loop_include.out
create mode 100644 tests/qapi-schema/multiple_relative_path_include.err
create mode 100644 tests/qapi-schema/multiple_relative_path_include.exit
create mode 100644 tests/qapi-schema/multiple_relative_path_include.json
create mode 100644 tests/qapi-schema/multiple_relative_path_include.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 ae3f756..df624ce 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -273,14 +273,47 @@ def build_schema(filename):
exit(1)
return schema
+loop_stack = []
+
+def include_sub_file(filename, expr_elem):
+ expr = expr_elem['expr']
+ expr_info = expr_elem['info']
+
+ # is the include a string ?
+ include = expr['include']
+ if not isinstance(include, str):
+ raise QAPIExprError(expr_info,
+ "filename to include must be a string")
+
+ # get sub filename
+ prefix = os.path.split(filename)[0]
+ sub_filename = os.path.join(prefix, include)
+
+ return parse_schema(sub_filename)
+
def parse_schema(filename):
+ abspath = os.path.abspath(filename)
+
+ if abspath in loop_stack:
+ print "Inclusion loop detected with file: %s"% filename
+ print "Path to the broken include is:"
+ for i in loop_stack:
+ print "\t%s" % i
+ sys.exit(1)
+
+ # push the abspath of the current file in the stack
+ loop_stack.append(abspath)
+
schema = build_schema(filename)
exprs = []
for expr_elem in schema.exprs:
expr = expr_elem['expr']
- if expr.has_key('enum'):
+ if expr.has_key('include'):
+ exprs += include_sub_file(filename, expr_elem)
+ continue
+ elif expr.has_key('enum'):
add_enum(expr['enum'], expr['data'])
elif expr.has_key('union'):
add_union(expr)
@@ -301,6 +334,9 @@ def parse_schema(filename):
print >>sys.stderr, e
exit(1)
+ # pop the abspath of the current file from the stack
+ loop_stack.pop()
+
return exprs
def parse_args(typeinfo):
diff --git a/tests/Makefile b/tests/Makefile
index 0a3c439..7ad20d1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -164,7 +164,10 @@ 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 \
+ include_non_filename.json error_in_included_file.json \
+ error_after_sucessful_include.json multi_file_loop_include.json \
+ multiple_relative_path_include.json)
GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
@@ -363,8 +366,9 @@ check-tests/test-qapi.py: tests/test-qapi.py
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
$(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 $$? >$*.test.exit, " TEST $*.out")
-# filter in a second step to avoid redirection madness
+# filter abspaths
@sed -i s=.*/== $*.test.err
+ @sed -i s="/.*/"== $*.test.out
@diff -q $(SRC_PATH)/$*.out $*.test.out
@diff -q $(SRC_PATH)/$*.err $*.test.err
@diff -q $(SRC_PATH)/$*.exit $*.test.exit
diff --git a/tests/qapi-schema/error_after_sucessful_include.err b/tests/qapi-schema/error_after_sucessful_include.err
new file mode 100644
index 0000000..d562a83
--- /dev/null
+++ b/tests/qapi-schema/error_after_sucessful_include.err
@@ -0,0 +1 @@
+error_after_sucessful_include.json:4:10: Stray "T"
diff --git a/tests/qapi-schema/error_after_sucessful_include.exit b/tests/qapi-schema/error_after_sucessful_include.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/error_after_sucessful_include.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/error_after_sucessful_include.json b/tests/qapi-schema/error_after_sucessful_include.json
new file mode 100644
index 0000000..c6cf313
--- /dev/null
+++ b/tests/qapi-schema/error_after_sucessful_include.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
+{ 'include': './include/include.json' }
+{ 'foo': True }
diff --git a/tests/qapi-schema/error_after_sucessful_include.out b/tests/qapi-schema/error_after_sucessful_include.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/error_in_included_file.err b/tests/qapi-schema/error_in_included_file.err
new file mode 100644
index 0000000..c011fee
--- /dev/null
+++ b/tests/qapi-schema/error_in_included_file.err
@@ -0,0 +1 @@
+error.json:4:12: Stray "T"
diff --git a/tests/qapi-schema/error_in_included_file.exit b/tests/qapi-schema/error_in_included_file.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/error_in_included_file.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/error_in_included_file.json b/tests/qapi-schema/error_in_included_file.json
new file mode 100644
index 0000000..ae8c732
--- /dev/null
+++ b/tests/qapi-schema/error_in_included_file.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
+{ 'include': 'include/error.json' }
+{ 'foo': '42' }
diff --git a/tests/qapi-schema/error_in_included_file.out b/tests/qapi-schema/error_in_included_file.out
new file mode 100644
index 0000000..e69de29
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/error.json b/tests/qapi-schema/include/error.json
new file mode 100644
index 0000000..33ac12c
--- /dev/null
+++ b/tests/qapi-schema/include/error.json
@@ -0,0 +1,6 @@
+
+{ 'foo': '43' }
+
+{ 'zerg' : True }
+
+{ 'bar' : '65' }
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/multi.json b/tests/qapi-schema/include/multi.json
new file mode 100644
index 0000000..692480c
--- /dev/null
+++ b/tests/qapi-schema/include/multi.json
@@ -0,0 +1 @@
+{ 'include': '../comments.json' }
diff --git a/tests/qapi-schema/include/multi_loop.json b/tests/qapi-schema/include/multi_loop.json
new file mode 100644
index 0000000..7c187b8
--- /dev/null
+++ b/tests/qapi-schema/include/multi_loop.json
@@ -0,0 +1 @@
+{ 'include': '../multi_file_loop_include.json' }
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..eaecfd3
--- /dev/null
+++ b/tests/qapi-schema/include_loop.out
@@ -0,0 +1,3 @@
+Inclusion loop detected with file: include_loop.json
+Path to the broken include is:
+ include_loop.json
diff --git a/tests/qapi-schema/include_non_filename.err b/tests/qapi-schema/include_non_filename.err
new file mode 100644
index 0000000..9b02b3a
--- /dev/null
+++ b/tests/qapi-schema/include_non_filename.err
@@ -0,0 +1 @@
+include_non_filename.json:3: filename to include must be a string
diff --git a/tests/qapi-schema/include_non_filename.exit b/tests/qapi-schema/include_non_filename.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include_non_filename.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include_non_filename.json b/tests/qapi-schema/include_non_filename.json
new file mode 100644
index 0000000..6042b12
--- /dev/null
+++ b/tests/qapi-schema/include_non_filename.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
+{ 'include': [ 'foo', 'bar'] }
+{ 'foo': '42' }
diff --git a/tests/qapi-schema/include_non_filename.out b/tests/qapi-schema/include_non_filename.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/multi_file_loop_include.err b/tests/qapi-schema/multi_file_loop_include.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/multi_file_loop_include.exit b/tests/qapi-schema/multi_file_loop_include.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/multi_file_loop_include.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/multi_file_loop_include.json b/tests/qapi-schema/multi_file_loop_include.json
new file mode 100644
index 0000000..0b11f27
--- /dev/null
+++ b/tests/qapi-schema/multi_file_loop_include.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
+{ 'include': './include/multi_loop.json' }
+{ 'foo': '42' }
diff --git a/tests/qapi-schema/multi_file_loop_include.out b/tests/qapi-schema/multi_file_loop_include.out
new file mode 100644
index 0000000..9af609b
--- /dev/null
+++ b/tests/qapi-schema/multi_file_loop_include.out
@@ -0,0 +1,4 @@
+Inclusion loop detected with file: multi_file_loop_include.json
+Path to the broken include is:
+ multi_file_loop_include.json
+ multi_loop.json
diff --git a/tests/qapi-schema/multiple_relative_path_include.err b/tests/qapi-schema/multiple_relative_path_include.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/multiple_relative_path_include.exit b/tests/qapi-schema/multiple_relative_path_include.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/multiple_relative_path_include.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/multiple_relative_path_include.json b/tests/qapi-schema/multiple_relative_path_include.json
new file mode 100644
index 0000000..3afd95b
--- /dev/null
+++ b/tests/qapi-schema/multiple_relative_path_include.json
@@ -0,0 +1,4 @@
+{ 'enum': 'Failure',
+ 'data': [ 'orange', 'apple', 'apricot' ] }
+{ 'include': './include/multi.json' }
+{ 'foo': '42' }
diff --git a/tests/qapi-schema/multiple_relative_path_include.out b/tests/qapi-schema/multiple_relative_path_include.out
new file mode 100644
index 0000000..e75c817
--- /dev/null
+++ b/tests/qapi-schema/multiple_relative_path_include.out
@@ -0,0 +1,6 @@
+[OrderedDict([('enum', 'Failure'), ('data', ['orange', 'apple', 'apricot'])]),
+ OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])]),
+ OrderedDict([('foo', '42')])]
+[{'enum_name': 'Failure', 'enum_values': ['orange', 'apple', 'apricot']},
+ {'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
+[]
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread