qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files
@ 2014-02-28 15:53 Lluís Vilanova
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file Lluís Vilanova
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Lluís Vilanova @ 2014-02-28 15:53 UTC (permalink / raw)
  To: qemu-devel

Adds the "include(...)" primitive to the syntax of QAPI schema files, allowing
these to be modularized into multiple per-topic files in the future.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---

Changes in v4:

* Rebase on 3e890c7.
* Minor cosmetic changes.
* Fix recording of included files in case of a cycle error.
* Add a more complex include cycle test.


Changes in v3:

* Fix documentation examples regarding how the input file is passed to the
  scripts.
* Add documentation for the 'include' directive.
* Detect inclusion loops.
* Fix "tests/qapi-schema/test-qapi.py" and "tests/Makefile" to use an explicit
  input file when running tests.
* Fix QAPI tests to cope with an explicit input file.
* Add tests for the "include" directive.


Changes in v2:

* Change the scripts to use an explicit input file instead of standard input.
* Fix "tests/Makefile" to use the new argument.
* Get the input directory for the "include" directive from the input file
  dirname.


Lluís Vilanova (3):
      qapi: Use an explicit input file
      qapi: Add a primitive to include other files from a QAPI schema file
      qapi: Add tests for the "include" directive


 Makefile                                      |   24 ++++++++++---
 docs/qapi-code-gen.txt                        |   12 +++++-
 scripts/qapi-commands.py                      |   10 ++++-
 scripts/qapi-types.py                         |    9 +++--
 scripts/qapi-visit.py                         |    9 +++--
 scripts/qapi.py                               |   47 +++++++++++++++++++++++--
 tests/Makefile                                |   18 +++++++---
 tests/qapi-schema/funny-char.err              |    2 +
 tests/qapi-schema/include-cycle-b.json        |    1 +
 tests/qapi-schema/include-cycle-c.json        |    1 +
 tests/qapi-schema/include-cycle.err           |    1 +
 tests/qapi-schema/include-cycle.exit          |    1 +
 tests/qapi-schema/include-cycle.json          |    1 +
 tests/qapi-schema/include-cycle.out           |    0 
 tests/qapi-schema/include-nested-err.err      |    1 +
 tests/qapi-schema/include-nested-err.exit     |    1 +
 tests/qapi-schema/include-nested-err.json     |    1 +
 tests/qapi-schema/include-nested-err.out      |    0 
 tests/qapi-schema/include-no-file.err         |    1 +
 tests/qapi-schema/include-no-file.exit        |    1 +
 tests/qapi-schema/include-no-file.json        |    1 +
 tests/qapi-schema/include-no-file.out         |    0 
 tests/qapi-schema/include-self-cycle.err      |    1 +
 tests/qapi-schema/include-self-cycle.exit     |    1 +
 tests/qapi-schema/include-self-cycle.json     |    1 +
 tests/qapi-schema/include-self-cycle.out      |    0 
 tests/qapi-schema/include-simple-sub.json     |    2 +
 tests/qapi-schema/include-simple.err          |    0 
 tests/qapi-schema/include-simple.exit         |    1 +
 tests/qapi-schema/include-simple.json         |    1 +
 tests/qapi-schema/include-simple.out          |    3 ++
 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                |    3 +-
 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 +
 42 files changed, 137 insertions(+), 38 deletions(-)
 create mode 100644 tests/qapi-schema/include-cycle-b.json
 create mode 100644 tests/qapi-schema/include-cycle-c.json
 create mode 100644 tests/qapi-schema/include-cycle.err
 create mode 100644 tests/qapi-schema/include-cycle.exit
 create mode 100644 tests/qapi-schema/include-cycle.json
 create mode 100644 tests/qapi-schema/include-cycle.out
 create mode 100644 tests/qapi-schema/include-nested-err.err
 create mode 100644 tests/qapi-schema/include-nested-err.exit
 create mode 100644 tests/qapi-schema/include-nested-err.json
 create mode 100644 tests/qapi-schema/include-nested-err.out
 create mode 100644 tests/qapi-schema/include-no-file.err
 create mode 100644 tests/qapi-schema/include-no-file.exit
 create mode 100644 tests/qapi-schema/include-no-file.json
 create mode 100644 tests/qapi-schema/include-no-file.out
 create mode 100644 tests/qapi-schema/include-self-cycle.err
 create mode 100644 tests/qapi-schema/include-self-cycle.exit
 create mode 100644 tests/qapi-schema/include-self-cycle.json
 create mode 100644 tests/qapi-schema/include-self-cycle.out
 create mode 100644 tests/qapi-schema/include-simple-sub.json
 create mode 100644 tests/qapi-schema/include-simple.err
 create mode 100644 tests/qapi-schema/include-simple.exit
 create mode 100644 tests/qapi-schema/include-simple.json
 create mode 100644 tests/qapi-schema/include-simple.out


To: qemu-devel@nongnu.org
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-02-28 15:53 [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Lluís Vilanova
@ 2014-02-28 15:53 ` Lluís Vilanova
  2014-03-01  8:35   ` Markus Armbruster
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-02-28 15:53 UTC (permalink / raw)
  To: qemu-devel

Use an explicit input file on the command-line instead of reading from standard input

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 Makefile                                      |   24 ++++++++++++++++++------
 docs/qapi-code-gen.txt                        |    4 ++--
 scripts/qapi-commands.py                      |   10 +++++++---
 scripts/qapi-types.py                         |    9 ++++++---
 scripts/qapi-visit.py                         |    9 ++++++---
 scripts/qapi.py                               |   15 +++++++++++----
 tests/Makefile                                |   14 ++++++++++----
 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                |    3 ++-
 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 +-
 19 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/Makefile b/Makefile
index 988438f..e82d49f 100644
--- a/Makefile
+++ b/Makefile
@@ -217,23 +217,35 @@ 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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -o "." -m, \
+		"  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/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 0728f36..2e9f036 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -220,7 +220,7 @@ created code.
 Example:
 
     mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
-      --output-dir="qapi-generated" --prefix="example-" < example-schema.json
+      --input-file=example-schema.json --output-dir="qapi-generated" --prefix="example-"
     mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
     /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
 
@@ -290,7 +290,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
 Example:
 
     mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
-        --output-dir="qapi-generated" --prefix="example-" < example-schema.json
+        --input-file=example-schema.json --output-dir="qapi-generated" --prefix="example-"
     mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
     /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
 
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index b12b696..1657f21 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -389,13 +389,15 @@ def gen_command_def_prologue(prefix="", proxy=False):
 
 
 try:
-    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:m",
                                    ["source", "header", "prefix=",
-                                    "output-dir=", "type=", "middle"])
+                                    "input-file=", "output-dir=",
+                                    "type=", "middle"])
 except getopt.GetoptError, err:
     print str(err)
     sys.exit(1)
 
+input_file = ""
 output_dir = ""
 prefix = ""
 dispatch_type = "sync"
@@ -409,6 +411,8 @@ do_h = False
 for o, a in opts:
     if o in ("-p", "--prefix"):
         prefix = a
+    elif o in ("-i", "--input-file"):
+        input_file = a
     elif o in ("-o", "--output-dir"):
         output_dir = a + "/"
     elif o in ("-t", "--type"):
@@ -440,7 +444,7 @@ except os.error, e:
     if e.errno != errno.EEXIST:
         raise
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(input_file)
 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 4a1652b..7304543 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -282,14 +282,15 @@ void qapi_free_%(type)s(%(c_type)s obj)
 
 
 try:
-    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
                                    ["source", "header", "builtins",
-                                    "prefix=", "output-dir="])
+                                    "prefix=", "input-file=", "output-dir="])
 except getopt.GetoptError, err:
     print str(err)
     sys.exit(1)
 
 output_dir = ""
+input_file = ""
 prefix = ""
 c_file = 'qapi-types.c'
 h_file = 'qapi-types.h'
@@ -301,6 +302,8 @@ do_builtins = False
 for o, a in opts:
     if o in ("-p", "--prefix"):
         prefix = a
+    elif o in ("-i", "--input-file"):
+        input_file = a
     elif o in ("-o", "--output-dir"):
         output_dir = a + "/"
     elif o in ("-c", "--source"):
@@ -381,7 +384,7 @@ fdecl.write(mcgen('''
 ''',
                   guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(input_file)
 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 65f1a54..856f969 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -383,13 +383,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
                 name=name)
 
 try:
-    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
                                    ["source", "header", "builtins", "prefix=",
-                                    "output-dir="])
+                                    "input-file=", "output-dir="])
 except getopt.GetoptError, err:
     print str(err)
     sys.exit(1)
 
+input_file = ""
 output_dir = ""
 prefix = ""
 c_file = 'qapi-visit.c'
@@ -402,6 +403,8 @@ do_builtins = False
 for o, a in opts:
     if o in ("-p", "--prefix"):
         prefix = a
+    elif o in ("-i", "--input-file"):
+        input_file = a
     elif o in ("-o", "--output-dir"):
         output_dir = a + "/"
     elif o in ("-c", "--source"):
@@ -480,7 +483,7 @@ fdecl.write(mcgen('''
 ''',
                   prefix=prefix, guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(input_file)
 
 # 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 9b3de4c..59c2b9b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -12,6 +12,7 @@
 # See the COPYING.LIB file in the top-level directory.
 
 from ordereddict import OrderedDict
+import os
 import sys
 
 builtin_types = [
@@ -37,6 +38,7 @@ builtin_type_qtypes = {
 
 class QAPISchemaError(Exception):
     def __init__(self, schema, msg):
+        self.base = schema.error_base
         self.fp = schema.fp
         self.msg = msg
         self.line = self.col = 1
@@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
                 self.col += 1
 
     def __str__(self):
-        return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
+        name = os.path.relpath(self.fp.name, self.base)
+        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)
 
 class QAPISchema:
 
-    def __init__(self, fp):
+    def __init__(self, fp, error_base=None):
         self.fp = fp
+        if error_base is None:
+            self.error_base = os.getcwd()
+        else:
+            self.error_base = error_base
         self.src = fp.read()
         if self.src == '' or self.src[-1] != '\n':
             self.src += '\n'
@@ -158,9 +165,9 @@ class QAPISchema:
             raise QAPISchemaError(self, 'Expected "{", "[" or string')
         return expr
 
-def parse_schema(fp):
+def parse_schema(input_path, error_base=None):
     try:
-        schema = QAPISchema(fp)
+        schema = QAPISchema(open(input_path, "r"), error_base)
     except QAPISchemaError, e:
         print >>sys.stderr, e
         exit(1)
diff --git a/tests/Makefile b/tests/Makefile
index b17d41e..02b0dbc 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -192,13 +192,19 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
 
 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   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
+		$(gen-out-type) -i "$<" -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   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
+		$(gen-out-type) -i "$<" -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   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
+		$(gen-out-type) -i "$<" -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
@@ -331,7 +337,7 @@ 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")
 	@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/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 b3d1e1d..f97e886 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -12,10 +12,11 @@
 
 from qapi import *
 from pprint import pprint
+import os
 import sys
 
 try:
-    exprs = parse_schema(sys.stdin)
+    exprs = parse_schema(sys.argv[1], os.path.dirname(sys.argv[1]))
 except SystemExit:
     raise
 except:
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 "'"

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-02-28 15:53 [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Lluís Vilanova
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file Lluís Vilanova
@ 2014-02-28 15:53 ` Lluís Vilanova
  2014-03-01  8:57   ` Markus Armbruster
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 3/3] qapi: Add tests for the "include" directive Lluís Vilanova
  2014-02-28 16:18 ` [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Eric Blake
  3 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-02-28 15:53 UTC (permalink / raw)
  To: qemu-devel

Adds the "include(...)" primitive to the syntax of QAPI schema files.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 docs/qapi-code-gen.txt |    8 ++++++++
 scripts/qapi.py        |   36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 2e9f036..e007807 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -40,6 +40,14 @@ enumeration types and union types.
 Generally speaking, types definitions should always use CamelCase for the type
 names. Command names should be all lower case with words separated by a hyphen.
 
+The QAPI schema definitions can be modularized using the 'include' directive:
+
+ include("sub-system/qapi.json")
+
+All paths are interpreted as relative to the initial input file passed to the
+QAPI parsing scripts.
+
+
 === Complex types ===
 
 A complex type is a dictionary containing a single key whose value is a
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 59c2b9b..eddbf25 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -11,10 +11,14 @@
 # This work is licensed under the terms of the GNU GPLv2.
 # See the COPYING.LIB file in the top-level directory.
 
+import os
+import re
 from ordereddict import OrderedDict
 import os
 import sys
 
+include_cre = re.compile("include\(\"([^\"]*)\"\)")
+
 builtin_types = [
     'str', 'int', 'number', 'bool',
     'int8', 'int16', 'int32', 'int64',
@@ -57,12 +61,16 @@ class QAPISchemaError(Exception):
 
 class QAPISchema:
 
-    def __init__(self, fp, error_base=None):
+    def __init__(self, fp, input_dir, error_base=None, included=[]):
         self.fp = fp
         if error_base is None:
             self.error_base = os.getcwd()
         else:
             self.error_base = error_base
+        input_path = os.path.abspath(fp.name)
+        input_path = os.path.relpath(input_path, self.error_base)
+        self.included = included + [input_path]
+        self.input_dir = input_dir
         self.src = fp.read()
         if self.src == '' or self.src[-1] != '\n':
             self.src += '\n'
@@ -107,6 +115,29 @@ class QAPISchema:
                 if self.cursor == len(self.src):
                     self.tok = None
                     return
+            elif self.tok == 'i':
+                include_src = self.src[self.cursor-1:]
+                include_match = include_cre.match(include_src)
+                if include_match is not None:
+                    include_path = os.path.join(self.input_dir,
+                                                include_match.group(1))
+                    include_path = os.path.abspath(include_path)
+                    if not os.path.isfile(include_path):
+                        raise QAPISchemaError(
+                            self,
+                            'Non-existing included file "%s"' %
+                            include_match.group(1))
+                    include_path_rel = os.path.relpath(include_path,
+                                                       self.error_base)
+                    if include_path_rel in self.included:
+                        raise QAPISchemaError(self, "Infinite inclusion loop: %s"
+                                              % " -> ".join(self.included +
+                                                            [include_path_rel]))
+                    include_schema = QAPISchema(open(include_path, "r"),
+                                                self.input_dir, self.error_base,
+                                                self.included)
+                    self.exprs += include_schema.exprs
+                    self.cursor += include_match.span()[1] - 1
             elif not self.tok.isspace():
                 raise QAPISchemaError(self, 'Stray "%s"' % self.tok)
 
@@ -166,8 +197,9 @@ class QAPISchema:
         return expr
 
 def parse_schema(input_path, error_base=None):
+    input_dir = os.path.dirname(input_path)
     try:
-        schema = QAPISchema(open(input_path, "r"), error_base)
+        schema = QAPISchema(open(input_path, "r"), input_dir, error_base)
     except QAPISchemaError, e:
         print >>sys.stderr, e
         exit(1)

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v4 3/3] qapi: Add tests for the "include" directive
  2014-02-28 15:53 [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Lluís Vilanova
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file Lluís Vilanova
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
@ 2014-02-28 15:53 ` Lluís Vilanova
  2014-02-28 16:18 ` [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Eric Blake
  3 siblings, 0 replies; 24+ messages in thread
From: Lluís Vilanova @ 2014-02-28 15:53 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 tests/Makefile                            |    4 +++-
 tests/qapi-schema/include-cycle-b.json    |    1 +
 tests/qapi-schema/include-cycle-c.json    |    1 +
 tests/qapi-schema/include-cycle.err       |    1 +
 tests/qapi-schema/include-cycle.exit      |    1 +
 tests/qapi-schema/include-cycle.json      |    1 +
 tests/qapi-schema/include-cycle.out       |    0 
 tests/qapi-schema/include-nested-err.err  |    1 +
 tests/qapi-schema/include-nested-err.exit |    1 +
 tests/qapi-schema/include-nested-err.json |    1 +
 tests/qapi-schema/include-nested-err.out  |    0 
 tests/qapi-schema/include-no-file.err     |    1 +
 tests/qapi-schema/include-no-file.exit    |    1 +
 tests/qapi-schema/include-no-file.json    |    1 +
 tests/qapi-schema/include-no-file.out     |    0 
 tests/qapi-schema/include-self-cycle.err  |    1 +
 tests/qapi-schema/include-self-cycle.exit |    1 +
 tests/qapi-schema/include-self-cycle.json |    1 +
 tests/qapi-schema/include-self-cycle.out  |    0 
 tests/qapi-schema/include-simple-sub.json |    2 ++
 tests/qapi-schema/include-simple.err      |    0 
 tests/qapi-schema/include-simple.exit     |    1 +
 tests/qapi-schema/include-simple.json     |    1 +
 tests/qapi-schema/include-simple.out      |    3 +++
 24 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 tests/qapi-schema/include-cycle-b.json
 create mode 100644 tests/qapi-schema/include-cycle-c.json
 create mode 100644 tests/qapi-schema/include-cycle.err
 create mode 100644 tests/qapi-schema/include-cycle.exit
 create mode 100644 tests/qapi-schema/include-cycle.json
 create mode 100644 tests/qapi-schema/include-cycle.out
 create mode 100644 tests/qapi-schema/include-nested-err.err
 create mode 100644 tests/qapi-schema/include-nested-err.exit
 create mode 100644 tests/qapi-schema/include-nested-err.json
 create mode 100644 tests/qapi-schema/include-nested-err.out
 create mode 100644 tests/qapi-schema/include-no-file.err
 create mode 100644 tests/qapi-schema/include-no-file.exit
 create mode 100644 tests/qapi-schema/include-no-file.json
 create mode 100644 tests/qapi-schema/include-no-file.out
 create mode 100644 tests/qapi-schema/include-self-cycle.err
 create mode 100644 tests/qapi-schema/include-self-cycle.exit
 create mode 100644 tests/qapi-schema/include-self-cycle.json
 create mode 100644 tests/qapi-schema/include-self-cycle.out
 create mode 100644 tests/qapi-schema/include-simple-sub.json
 create mode 100644 tests/qapi-schema/include-simple.err
 create mode 100644 tests/qapi-schema/include-simple.exit
 create mode 100644 tests/qapi-schema/include-simple.json
 create mode 100644 tests/qapi-schema/include-simple.out

diff --git a/tests/Makefile b/tests/Makefile
index 02b0dbc..f4aae8c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -142,7 +142,9 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
         missing-comma-object.json non-objects.json \
         qapi-schema-test.json quoted-structural-chars.json \
         trailing-comma-list.json trailing-comma-object.json \
-        unclosed-list.json unclosed-object.json unclosed-string.json)
+        unclosed-list.json unclosed-object.json unclosed-string.json \
+        include-simple.json include-nested-err.json include-no-file.json \
+        include-self-cycle.json include-cycle.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-cycle-b.json b/tests/qapi-schema/include-cycle-b.json
new file mode 100644
index 0000000..baf4282
--- /dev/null
+++ b/tests/qapi-schema/include-cycle-b.json
@@ -0,0 +1 @@
+include("include-cycle-c.json")
diff --git a/tests/qapi-schema/include-cycle-c.json b/tests/qapi-schema/include-cycle-c.json
new file mode 100644
index 0000000..90ffa6a
--- /dev/null
+++ b/tests/qapi-schema/include-cycle-c.json
@@ -0,0 +1 @@
+include("include-cycle.json")
diff --git a/tests/qapi-schema/include-cycle.err b/tests/qapi-schema/include-cycle.err
new file mode 100644
index 0000000..48003d3
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.err
@@ -0,0 +1 @@
+include-cycle-c.json:1:1: Infinite inclusion loop: include-cycle.json -> include-cycle-b.json -> include-cycle-c.json -> include-cycle.json
diff --git a/tests/qapi-schema/include-cycle.exit b/tests/qapi-schema/include-cycle.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-cycle.json b/tests/qapi-schema/include-cycle.json
new file mode 100644
index 0000000..4f00e7e
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.json
@@ -0,0 +1 @@
+include("include-cycle-b.json")
diff --git a/tests/qapi-schema/include-cycle.out b/tests/qapi-schema/include-cycle.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include-nested-err.err b/tests/qapi-schema/include-nested-err.err
new file mode 100644
index 0000000..676cce5
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.err
@@ -0,0 +1 @@
+missing-colon.json:1:10: Expected ":"
diff --git a/tests/qapi-schema/include-nested-err.exit b/tests/qapi-schema/include-nested-err.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-nested-err.json b/tests/qapi-schema/include-nested-err.json
new file mode 100644
index 0000000..ff53883
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.json
@@ -0,0 +1 @@
+include("missing-colon.json")
diff --git a/tests/qapi-schema/include-nested-err.out b/tests/qapi-schema/include-nested-err.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include-no-file.err b/tests/qapi-schema/include-no-file.err
new file mode 100644
index 0000000..24832c1
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.err
@@ -0,0 +1 @@
+include-no-file.json:1:1: Non-existing included file "include-no-file-sub.json"
diff --git a/tests/qapi-schema/include-no-file.exit b/tests/qapi-schema/include-no-file.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-no-file.json b/tests/qapi-schema/include-no-file.json
new file mode 100644
index 0000000..df762c2
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.json
@@ -0,0 +1 @@
+include("include-no-file-sub.json")
diff --git a/tests/qapi-schema/include-no-file.out b/tests/qapi-schema/include-no-file.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include-self-cycle.err b/tests/qapi-schema/include-self-cycle.err
new file mode 100644
index 0000000..c2b216a
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.err
@@ -0,0 +1 @@
+include-self-cycle.json:1:1: Infinite inclusion loop: include-self-cycle.json -> include-self-cycle.json
diff --git a/tests/qapi-schema/include-self-cycle.exit b/tests/qapi-schema/include-self-cycle.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-self-cycle.json b/tests/qapi-schema/include-self-cycle.json
new file mode 100644
index 0000000..1c418c0
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.json
@@ -0,0 +1 @@
+include("include-self-cycle.json")
diff --git a/tests/qapi-schema/include-self-cycle.out b/tests/qapi-schema/include-self-cycle.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include-simple-sub.json b/tests/qapi-schema/include-simple-sub.json
new file mode 100644
index 0000000..4bd4af4
--- /dev/null
+++ b/tests/qapi-schema/include-simple-sub.json
@@ -0,0 +1,2 @@
+{ 'enum': 'Status',
+  'data': [ 'good', 'bad', 'ugly' ] }
diff --git a/tests/qapi-schema/include-simple.err b/tests/qapi-schema/include-simple.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/include-simple.exit b/tests/qapi-schema/include-simple.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/include-simple.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/include-simple.json b/tests/qapi-schema/include-simple.json
new file mode 100644
index 0000000..31c81d1
--- /dev/null
+++ b/tests/qapi-schema/include-simple.json
@@ -0,0 +1 @@
+include("include-simple-sub.json")
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
new file mode 100644
index 0000000..e3bd904
--- /dev/null
+++ b/tests/qapi-schema/include-simple.out
@@ -0,0 +1,3 @@
+[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
+['Status']
+[]

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files
  2014-02-28 15:53 [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Lluís Vilanova
                   ` (2 preceding siblings ...)
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 3/3] qapi: Add tests for the "include" directive Lluís Vilanova
@ 2014-02-28 16:18 ` Eric Blake
  3 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2014-02-28 16:18 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

On 02/28/2014 08:53 AM, Lluís Vilanova wrote:
> Adds the "include(...)" primitive to the syntax of QAPI schema files, allowing
> these to be modularized into multiple per-topic files in the future.
> 
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---

Series: Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file Lluís Vilanova
@ 2014-03-01  8:35   ` Markus Armbruster
  2014-03-03 14:25     ` Lluís Vilanova
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Armbruster @ 2014-03-01  8:35 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Use an explicit input file on the command-line instead of reading from standard input
>
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  Makefile                                      |   24 ++++++++++++++++++------
>  docs/qapi-code-gen.txt                        |    4 ++--
>  scripts/qapi-commands.py                      |   10 +++++++---
>  scripts/qapi-types.py                         |    9 ++++++---
>  scripts/qapi-visit.py                         |    9 ++++++---
>  scripts/qapi.py                               |   15 +++++++++++----
>  tests/Makefile                                |   14 ++++++++++----
>  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                |    3 ++-
>  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 +-
>  19 files changed, 73 insertions(+), 37 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 988438f..e82d49f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -217,23 +217,35 @@ 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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -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) -i "$<" -o "." -m, \
> +		"  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/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
> index 0728f36..2e9f036 100644
> --- a/docs/qapi-code-gen.txt
> +++ b/docs/qapi-code-gen.txt
> @@ -220,7 +220,7 @@ created code.
>  Example:
>  
>      mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
> -      --output-dir="qapi-generated" --prefix="example-" < example-schema.json
> +      --input-file=example-schema.json --output-dir="qapi-generated" --prefix="example-"
>      mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
>      /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
>  
> @@ -290,7 +290,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
>  Example:
>  
>      mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
> -        --output-dir="qapi-generated" --prefix="example-" < example-schema.json
> +        --input-file=example-schema.json --output-dir="qapi-generated" --prefix="example-"
>      mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
>      /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
>  
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index b12b696..1657f21 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -389,13 +389,15 @@ def gen_command_def_prologue(prefix="", proxy=False):
>  
>  
>  try:
> -    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
> +    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:m",
>                                     ["source", "header", "prefix=",
> -                                    "output-dir=", "type=", "middle"])
> +                                    "input-file=", "output-dir=",
> +                                    "type=", "middle"])
>  except getopt.GetoptError, err:
>      print str(err)
>      sys.exit(1)
>  
> +input_file = ""
>  output_dir = ""
>  prefix = ""
>  dispatch_type = "sync"
> @@ -409,6 +411,8 @@ do_h = False
>  for o, a in opts:
>      if o in ("-p", "--prefix"):
>          prefix = a
> +    elif o in ("-i", "--input-file"):
> +        input_file = a
>      elif o in ("-o", "--output-dir"):
>          output_dir = a + "/"
>      elif o in ("-t", "--type"):
> @@ -440,7 +444,7 @@ except os.error, e:
>      if e.errno != errno.EEXIST:
>          raise
>  
> -exprs = parse_schema(sys.stdin)
> +exprs = parse_schema(input_file)
>  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 4a1652b..7304543 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -282,14 +282,15 @@ void qapi_free_%(type)s(%(c_type)s obj)
>  
>  
>  try:
> -    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
> +    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
>                                     ["source", "header", "builtins",
> -                                    "prefix=", "output-dir="])
> +                                    "prefix=", "input-file=", "output-dir="])
>  except getopt.GetoptError, err:
>      print str(err)
>      sys.exit(1)
>  
>  output_dir = ""
> +input_file = ""
>  prefix = ""
>  c_file = 'qapi-types.c'
>  h_file = 'qapi-types.h'
> @@ -301,6 +302,8 @@ do_builtins = False
>  for o, a in opts:
>      if o in ("-p", "--prefix"):
>          prefix = a
> +    elif o in ("-i", "--input-file"):
> +        input_file = a
>      elif o in ("-o", "--output-dir"):
>          output_dir = a + "/"
>      elif o in ("-c", "--source"):

Option -i isn't optional:

    $ python ../scripts/qapi-types.py -o tests
    Traceback (most recent call last):
      File "../scripts/qapi-types.py", line 387, in <module>
        exprs = parse_schema(input_file)
      File "/work/armbru/qemu/scripts/qapi.py", line 202, in parse_schema
        schema = QAPISchema(open(input_path, "r"), input_dir, error_base)
    IOError: [Errno 2] No such file or directory: ''

The error message is is atrocious, but it's what we get from python
programs when the authors can't be bothered to give a rat's ass on
usability.  Not your fault.

Either default the input file to standard input, so that -i is optional,
or make the input file a required non-option argument rather than an
option.  I'd prefer the latter.

Hmm, -o isn't optional, either.  And extra non-option arguments aren't
caught.  Okay, I declare this thing crap.  Your patch doesn't make it
crappier than it already is, so I'm retracting my request.

> @@ -381,7 +384,7 @@ fdecl.write(mcgen('''
>  ''',
>                    guard=guardname(h_file)))
>  
> -exprs = parse_schema(sys.stdin)
> +exprs = parse_schema(input_file)
>  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 65f1a54..856f969 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -383,13 +383,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
>                  name=name)
>  
>  try:
> -    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
> +    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
>                                     ["source", "header", "builtins", "prefix=",
> -                                    "output-dir="])
> +                                    "input-file=", "output-dir="])
>  except getopt.GetoptError, err:
>      print str(err)
>      sys.exit(1)
>  
> +input_file = ""
>  output_dir = ""
>  prefix = ""
>  c_file = 'qapi-visit.c'
> @@ -402,6 +403,8 @@ do_builtins = False
>  for o, a in opts:
>      if o in ("-p", "--prefix"):
>          prefix = a
> +    elif o in ("-i", "--input-file"):
> +        input_file = a
>      elif o in ("-o", "--output-dir"):
>          output_dir = a + "/"
>      elif o in ("-c", "--source"):
> @@ -480,7 +483,7 @@ fdecl.write(mcgen('''
>  ''',
>                    prefix=prefix, guard=guardname(h_file)))
>  
> -exprs = parse_schema(sys.stdin)
> +exprs = parse_schema(input_file)
>  
>  # 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 9b3de4c..59c2b9b 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -12,6 +12,7 @@
>  # See the COPYING.LIB file in the top-level directory.
>  
>  from ordereddict import OrderedDict
> +import os
>  import sys
>  
>  builtin_types = [
> @@ -37,6 +38,7 @@ builtin_type_qtypes = {
>  
>  class QAPISchemaError(Exception):
>      def __init__(self, schema, msg):
> +        self.base = schema.error_base

Non-obvious identifiers.  Took me some reading on to figure out that
this is a directory.

>          self.fp = schema.fp
>          self.msg = msg
>          self.line = self.col = 1
> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>                  self.col += 1
>  
>      def __str__(self):
> -        return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
> +        name = os.path.relpath(self.fp.name, self.base)
> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)

Can you explain what this change does, and why it's wanted?

>  
>  class QAPISchema:
>  
> -    def __init__(self, fp):
> +    def __init__(self, fp, error_base=None):
>          self.fp = fp
> +        if error_base is None:
> +            self.error_base = os.getcwd()
> +        else:
> +            self.error_base = error_base
>          self.src = fp.read()
>          if self.src == '' or self.src[-1] != '\n':
>              self.src += '\n'
> @@ -158,9 +165,9 @@ class QAPISchema:
>              raise QAPISchemaError(self, 'Expected "{", "[" or string')
>          return expr
>  
> -def parse_schema(fp):
> +def parse_schema(input_path, error_base=None):

The only caller that passes the optional argument is
tests/qapi-schema/test-qapi.py.  Is it really necessary?

>      try:
> -        schema = QAPISchema(fp)
> +        schema = QAPISchema(open(input_path, "r"), error_base)
>      except QAPISchemaError, e:
>          print >>sys.stderr, e
>          exit(1)
> diff --git a/tests/Makefile b/tests/Makefile
> index b17d41e..02b0dbc 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -192,13 +192,19 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
>  
>  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   $@")
> +	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
> +		$(gen-out-type) -i "$<" -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   $@")
> +	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
> +		$(gen-out-type) -i "$<" -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   $@")
> +	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
> +		$(gen-out-type) -i "$<" -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
> @@ -331,7 +337,7 @@ 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")
>  	@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/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 b3d1e1d..f97e886 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -12,10 +12,11 @@
>  
>  from qapi import *
>  from pprint import pprint
> +import os
>  import sys
>  
>  try:
> -    exprs = parse_schema(sys.stdin)
> +    exprs = parse_schema(sys.argv[1], os.path.dirname(sys.argv[1]))
>  except SystemExit:
>      raise
>  except:

This is the caller that passes the optional argument.

> 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 "'"

Error messages improved :)

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
@ 2014-03-01  8:57   ` Markus Armbruster
  2014-03-03 14:21     ` Lluís Vilanova
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Armbruster @ 2014-03-01  8:57 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Adds the "include(...)" primitive to the syntax of QAPI schema files.
>
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  docs/qapi-code-gen.txt |    8 ++++++++
>  scripts/qapi.py        |   36 ++++++++++++++++++++++++++++++++++--
>  2 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
> index 2e9f036..e007807 100644
> --- a/docs/qapi-code-gen.txt
> +++ b/docs/qapi-code-gen.txt
> @@ -40,6 +40,14 @@ enumeration types and union types.
>  Generally speaking, types definitions should always use CamelCase for the type
>  names. Command names should be all lower case with words separated by a hyphen.
>  
> +The QAPI schema definitions can be modularized using the 'include' directive:
> +
> + include("sub-system/qapi.json")

And now it isn't JSON anymore.

To keep it JSON, use syntax like

    { "include": "sub-system/qapi.json" }

If you absolutely must make it non-JSON, you better rename the .json
files.

Hmm, we already are non-JSON, because we use ' instead of " for no sane
reason.

Our JSON parser accepts ' as an extension, to save us quoting in C
strings.  That reason doesn't apply to .json files.

> +
> +All paths are interpreted as relative to the initial input file passed to the
> +QAPI parsing scripts.

Really?

Consider foo.json includes lib/a.json, which wants to include
lib/b.json.

foo.json:       include("lib/a.json")
lib/a.json:     include("lib/b.json")   # relative to foo.json's directory

Now throw in bar/bar.json including lib/a.json:

bar/bar.json:   include("../lib/a.json")
lib/a.json:     include("lib/b.json")   # relative to bar/ -> ENOENT

Make it relative to the file with the include directive.

> +
> +
>  === Complex types ===
>  
>  A complex type is a dictionary containing a single key whose value is a
[...]

Are you aware of Wenchao Xia's "[PATCH V8 00/10] qapi script: support
enum as discriminator and better enum name"?  I'm afraid there's a
(semantic?) conflict.  With include files, "[PATCH V8 03/10] qapi
script: remember line number in schema parsing" needs to remember the
source file, too.

Wenchao's series is likely go in first.  Perhaps you want to base on it
now.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-01  8:57   ` Markus Armbruster
@ 2014-03-03 14:21     ` Lluís Vilanova
  2014-03-03 15:27       ` Markus Armbruster
  0 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-03 14:21 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Markus Armbruster writes:

> Lluís Vilanova <vilanova@ac.upc.edu> writes:
>> Adds the "include(...)" primitive to the syntax of QAPI schema files.
>> 
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
>> docs/qapi-code-gen.txt |    8 ++++++++
>> scripts/qapi.py        |   36 ++++++++++++++++++++++++++++++++++--
>> 2 files changed, 42 insertions(+), 2 deletions(-)
>> 
>> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
>> index 2e9f036..e007807 100644
>> --- a/docs/qapi-code-gen.txt
>> +++ b/docs/qapi-code-gen.txt
>> @@ -40,6 +40,14 @@ enumeration types and union types.
>> Generally speaking, types definitions should always use CamelCase for the type
>> names. Command names should be all lower case with words separated by a hyphen.
>> 
>> +The QAPI schema definitions can be modularized using the 'include' directive:
>> +
>> + include("sub-system/qapi.json")

> And now it isn't JSON anymore.

> To keep it JSON, use syntax like

>     { "include": "sub-system/qapi.json" }

> If you absolutely must make it non-JSON, you better rename the .json
> files.

> Hmm, we already are non-JSON, because we use ' instead of " for no sane
> reason.

> Our JSON parser accepts ' as an extension, to save us quoting in C
> strings.  That reason doesn't apply to .json files.

Is it a problem if they are not pure JSON? In the end, they are parsed by
qapi.py (which already knows about file syntax), and having a separate syntax
for includes makes it somewhat easier to spot when that happens.


>> +
>> +All paths are interpreted as relative to the initial input file passed to the
>> +QAPI parsing scripts.

> Really?

> Consider foo.json includes lib/a.json, which wants to include
> lib/b.json.

> foo.json:       include("lib/a.json")
> lib/a.json:     include("lib/b.json")   # relative to foo.json's directory

> Now throw in bar/bar.json including lib/a.json:

> bar/bar.json:   include("../lib/a.json")
> lib/a.json:     include("lib/b.json")   # relative to bar/ -> ENOENT

> Make it relative to the file with the include directive.

Right, sorry. The documentation was not updated after removing the explicit
include directory argument. What I'm not sure though is what would be a better
option, having current-file-relative includes, or resuscitating the old explicit
include argument.


>> +
>> +
>> === Complex types ===
>> 
>> A complex type is a dictionary containing a single key whose value is a
> [...]

> Are you aware of Wenchao Xia's "[PATCH V8 00/10] qapi script: support
> enum as discriminator and better enum name"?  I'm afraid there's a
> (semantic?) conflict.  With include files, "[PATCH V8 03/10] qapi
> script: remember line number in schema parsing" needs to remember the
> source file, too.

> Wenchao's series is likely go in first.  Perhaps you want to base on it
> now.

I was not aware of that. Since I'm managing multiple series on a single branch
with stgit (and extracting that is somewhat tedious), I will redo this series
once Xia's is merged upstream. Is the merge going to happen anytime soon?


Thanks,
  Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-03-01  8:35   ` Markus Armbruster
@ 2014-03-03 14:25     ` Lluís Vilanova
  2014-03-03 15:42       ` Markus Armbruster
  0 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-03 14:25 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Markus Armbruster writes:

> Lluís Vilanova <vilanova@ac.upc.edu> writes:
[...]
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 9b3de4c..59c2b9b 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -12,6 +12,7 @@
>> # See the COPYING.LIB file in the top-level directory.
>> 
>> from ordereddict import OrderedDict
>> +import os
>> import sys
>> 
>> builtin_types = [
>> @@ -37,6 +38,7 @@ builtin_type_qtypes = {
>> 
>> class QAPISchemaError(Exception):
>> def __init__(self, schema, msg):
>> +        self.base = schema.error_base

> Non-obvious identifiers.  Took me some reading on to figure out that
> this is a directory.

Will fix.


>> self.fp = schema.fp
>> self.msg = msg
>> self.line = self.col = 1
>> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>> self.col += 1
>> 
>> def __str__(self):
>> -        return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
>> +        name = os.path.relpath(self.fp.name, self.base)
>> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)

> Can you explain what this change does, and why it's wanted?

Paths are shown as relative so that the test outputs (stderr) can be verified
with diff. Otherwise the actual message depends on the path from which you're
running the tests.


>> 
>> class QAPISchema:
>> 
>> -    def __init__(self, fp):
>> +    def __init__(self, fp, error_base=None):
>> self.fp = fp
>> +        if error_base is None:
>> +            self.error_base = os.getcwd()
>> +        else:
>> +            self.error_base = error_base
>> self.src = fp.read()
>> if self.src == '' or self.src[-1] != '\n':
>> self.src += '\n'
>> @@ -158,9 +165,9 @@ class QAPISchema:
>> raise QAPISchemaError(self, 'Expected "{", "[" or string')
>> return expr
>> 
>> -def parse_schema(fp):
>> +def parse_schema(input_path, error_base=None):

> The only caller that passes the optional argument is
> tests/qapi-schema/test-qapi.py.  Is it really necessary?

It's part of the previous answer; that's also true for your next comment (which
I elided). When running tests, paths are shown as relative.


Thanks,
  Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-03 14:21     ` Lluís Vilanova
@ 2014-03-03 15:27       ` Markus Armbruster
  2014-03-03 17:04         ` Lluís Vilanova
  2014-03-03 17:56         ` Eric Blake
  0 siblings, 2 replies; 24+ messages in thread
From: Markus Armbruster @ 2014-03-03 15:27 UTC (permalink / raw)
  To: qemu-devel

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Markus Armbruster writes:
>
>> Lluís Vilanova <vilanova@ac.upc.edu> writes:
>>> Adds the "include(...)" primitive to the syntax of QAPI schema files.
>>> 
>>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>>> ---
>>> docs/qapi-code-gen.txt |    8 ++++++++
>>> scripts/qapi.py        |   36 ++++++++++++++++++++++++++++++++++--
>>> 2 files changed, 42 insertions(+), 2 deletions(-)
>>> 
>>> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
>>> index 2e9f036..e007807 100644
>>> --- a/docs/qapi-code-gen.txt
>>> +++ b/docs/qapi-code-gen.txt
>>> @@ -40,6 +40,14 @@ enumeration types and union types.
>>> Generally speaking, types definitions should always use CamelCase
>>> for the type
>>> names. Command names should be all lower case with words separated
>>> by a hyphen.
>>> 
>>> +The QAPI schema definitions can be modularized using the 'include'
>>> directive:
>>> +
>>> + include("sub-system/qapi.json")
>
>> And now it isn't JSON anymore.
>
>> To keep it JSON, use syntax like
>
>>     { "include": "sub-system/qapi.json" }
>
>> If you absolutely must make it non-JSON, you better rename the .json
>> files.
>
>> Hmm, we already are non-JSON, because we use ' instead of " for no sane
>> reason.
>
>> Our JSON parser accepts ' as an extension, to save us quoting in C
>> strings.  That reason doesn't apply to .json files.
>
> Is it a problem if they are not pure JSON? In the end, they are parsed by
> qapi.py (which already knows about file syntax), and having a separate syntax
> for includes makes it somewhat easier to spot when that happens.

I don't particularly care whether schema syntax is pure JSON, some
bastardized variation of JSON, or something else entirely.  But as long
as we advertize schema files it as .json, they better contain JSON.  If
they contain something else, they should be called something else.

>>> +
>>> +All paths are interpreted as relative to the initial input file
>>> passed to the
>>> +QAPI parsing scripts.
>
>> Really?
>
>> Consider foo.json includes lib/a.json, which wants to include
>> lib/b.json.
>
>> foo.json:       include("lib/a.json")
>> lib/a.json:     include("lib/b.json")   # relative to foo.json's directory
>
>> Now throw in bar/bar.json including lib/a.json:
>
>> bar/bar.json:   include("../lib/a.json")
>> lib/a.json:     include("lib/b.json")   # relative to bar/ -> ENOENT
>
>> Make it relative to the file with the include directive.
>
> Right, sorry. The documentation was not updated after removing the explicit
> include directory argument. What I'm not sure though is what would be a better
> option, having current-file-relative includes, or resuscitating the old explicit
> include argument.

Include relative to the including file is simple.  If we needed
not-so-simple semantics, I suspect we'd be better off piping through
cpp.

>>> +
>>> +
>>> === Complex types ===
>>> 
>>> A complex type is a dictionary containing a single key whose value is a
>> [...]
>
>> Are you aware of Wenchao Xia's "[PATCH V8 00/10] qapi script: support
>> enum as discriminator and better enum name"?  I'm afraid there's a
>> (semantic?) conflict.  With include files, "[PATCH V8 03/10] qapi
>> script: remember line number in schema parsing" needs to remember the
>> source file, too.
>
>> Wenchao's series is likely go in first.  Perhaps you want to base on it
>> now.
>
> I was not aware of that. Since I'm managing multiple series on a single branch
> with stgit (and extracting that is somewhat tedious), I will redo this series
> once Xia's is merged upstream. Is the merge going to happen anytime soon?

I reviewed v7, and it looked almost ready to me.  If v8 is ready, it'll
hopefully get merged fairly quickly (days, not weeks).

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-03-03 14:25     ` Lluís Vilanova
@ 2014-03-03 15:42       ` Markus Armbruster
  2014-03-03 16:59         ` Lluís Vilanova
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Armbruster @ 2014-03-03 15:42 UTC (permalink / raw)
  To: qemu-devel

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Markus Armbruster writes:
>
>> Lluís Vilanova <vilanova@ac.upc.edu> writes:
> [...]
>>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>>> index 9b3de4c..59c2b9b 100644
>>> --- a/scripts/qapi.py
>>> +++ b/scripts/qapi.py
>>> @@ -12,6 +12,7 @@
>>> # See the COPYING.LIB file in the top-level directory.
>>> 
>>> from ordereddict import OrderedDict
>>> +import os
>>> import sys
>>> 
>>> builtin_types = [
>>> @@ -37,6 +38,7 @@ builtin_type_qtypes = {
>>> 
>>> class QAPISchemaError(Exception):
>>> def __init__(self, schema, msg):
>>> +        self.base = schema.error_base
>
>> Non-obvious identifiers.  Took me some reading on to figure out that
>> this is a directory.
>
> Will fix.
>
>
>>> self.fp = schema.fp
>>> self.msg = msg
>>> self.line = self.col = 1
>>> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>>> self.col += 1
>>> 
>>> def __str__(self):
>>> - return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col,
>>> self.msg)
>>> +        name = os.path.relpath(self.fp.name, self.base)
>>> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)
>
>> Can you explain what this change does, and why it's wanted?
>
> Paths are shown as relative so that the test outputs (stderr) can be verified
> with diff. Otherwise the actual message depends on the path from which you're
> running the tests.

Hmm.  This is the applicable make rule:

$(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")
	@diff -q $(SRC_PATH)/$*.out $*.test.out
	@diff -q $(SRC_PATH)/$*.err $*.test.err
	@diff -q $(SRC_PATH)/$*.exit $*.test.exit

Since $^ is in $(SRC_PATH), it's like $(SRC_PATH)/foo.json.  If
$(SRC_PATH)/foo.json has an error, the error messages duly points to
$(SRC_PATH)/foo.json.

The "diff -q $(SRC_PATH)/$*.err $*.test.err" fails unless your SRC_PATH
matches the one that's encoded in tests/qapi-schema/foo.err.  Is that
the problem you're trying to solve?

[...]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-03-03 15:42       ` Markus Armbruster
@ 2014-03-03 16:59         ` Lluís Vilanova
  2014-03-04 13:17           ` Markus Armbruster
  0 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-03 16:59 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Markus Armbruster writes:
[...]
>>>> self.fp = schema.fp
>>>> self.msg = msg
>>>> self.line = self.col = 1
>>>> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>>>> self.col += 1
>>>> 
>>>> def __str__(self):
>>>> - return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col,
>>>> self.msg)
>>>> +        name = os.path.relpath(self.fp.name, self.base)
>>>> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)
>> 
>>> Can you explain what this change does, and why it's wanted?
>> 
>> Paths are shown as relative so that the test outputs (stderr) can be verified
>> with diff. Otherwise the actual message depends on the path from which you're
>> running the tests.

> Hmm.  This is the applicable make rule:

> $(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")
> 	@diff -q $(SRC_PATH)/$*.out $*.test.out
> 	@diff -q $(SRC_PATH)/$*.err $*.test.err
> 	@diff -q $(SRC_PATH)/$*.exit $*.test.exit

> Since $^ is in $(SRC_PATH), it's like $(SRC_PATH)/foo.json.  If
> $(SRC_PATH)/foo.json has an error, the error messages duly points to
> $(SRC_PATH)/foo.json.

> The "diff -q $(SRC_PATH)/$*.err $*.test.err" fails unless your SRC_PATH
> matches the one that's encoded in tests/qapi-schema/foo.err.  Is that
> the problem you're trying to solve?

Right. Paths are internally stored as absolute in "qapi.py" (to check for
include cycles), and the "base directory" is only used to show them as
relative. I can try to change the code to retain this functionality but without
special-casing the tests.


Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-03 15:27       ` Markus Armbruster
@ 2014-03-03 17:04         ` Lluís Vilanova
  2014-03-03 17:56         ` Eric Blake
  1 sibling, 0 replies; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-03 17:04 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Markus Armbruster writes:

> Lluís Vilanova <vilanova@ac.upc.edu> writes:
>> Markus Armbruster writes:
>> 
>>> Lluís Vilanova <vilanova@ac.upc.edu> writes:
>>>> Adds the "include(...)" primitive to the syntax of QAPI schema files.
>>>> 
>>>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>>>> ---
>>>> docs/qapi-code-gen.txt |    8 ++++++++
>>>> scripts/qapi.py        |   36 ++++++++++++++++++++++++++++++++++--
>>>> 2 files changed, 42 insertions(+), 2 deletions(-)
>>>> 
>>>> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
>>>> index 2e9f036..e007807 100644
>>>> --- a/docs/qapi-code-gen.txt
>>>> +++ b/docs/qapi-code-gen.txt
>>>> @@ -40,6 +40,14 @@ enumeration types and union types.
>>>> Generally speaking, types definitions should always use CamelCase
>>>> for the type
>>>> names. Command names should be all lower case with words separated
>>>> by a hyphen.
>>>> 
>>>> +The QAPI schema definitions can be modularized using the 'include'
>>>> directive:
>>>> +
>>>> + include("sub-system/qapi.json")
>> 
>>> And now it isn't JSON anymore.
>> 
>>> To keep it JSON, use syntax like
>> 
>>> { "include": "sub-system/qapi.json" }
>> 
>>> If you absolutely must make it non-JSON, you better rename the .json
>>> files.
>> 
>>> Hmm, we already are non-JSON, because we use ' instead of " for no sane
>>> reason.
>> 
>>> Our JSON parser accepts ' as an extension, to save us quoting in C
>>> strings.  That reason doesn't apply to .json files.
>> 
>> Is it a problem if they are not pure JSON? In the end, they are parsed by
>> qapi.py (which already knows about file syntax), and having a separate syntax
>> for includes makes it somewhat easier to spot when that happens.

> I don't particularly care whether schema syntax is pure JSON, some
> bastardized variation of JSON, or something else entirely.  But as long
> as we advertize schema files it as .json, they better contain JSON.  If
> they contain something else, they should be called something else.

Both are simple enough to implement. Is there any consensus on what's preferred?


>>>> +
>>>> +All paths are interpreted as relative to the initial input file
>>>> passed to the
>>>> +QAPI parsing scripts.
>> 
>>> Really?
>> 
>>> Consider foo.json includes lib/a.json, which wants to include
>>> lib/b.json.
>> 
>>> foo.json:       include("lib/a.json")
>>> lib/a.json:     include("lib/b.json")   # relative to foo.json's directory
>> 
>>> Now throw in bar/bar.json including lib/a.json:
>> 
>>> bar/bar.json:   include("../lib/a.json")
>>> lib/a.json:     include("lib/b.json")   # relative to bar/ -> ENOENT
>> 
>>> Make it relative to the file with the include directive.
>> 
>> Right, sorry. The documentation was not updated after removing the explicit
>> include directory argument. What I'm not sure though is what would be a better
>> option, having current-file-relative includes, or resuscitating the old explicit
>> include argument.

> Include relative to the including file is simple.  If we needed
> not-so-simple semantics, I suspect we'd be better off piping through
> cpp.

I tried, but it chokes on the comment syntax.


>>>> +
>>>> +
>>>> === Complex types ===
>>>> 
>>>> A complex type is a dictionary containing a single key whose value is a
>>> [...]
>> 
>>> Are you aware of Wenchao Xia's "[PATCH V8 00/10] qapi script: support
>>> enum as discriminator and better enum name"?  I'm afraid there's a
>>> (semantic?) conflict.  With include files, "[PATCH V8 03/10] qapi
>>> script: remember line number in schema parsing" needs to remember the
>>> source file, too.
>> 
>>> Wenchao's series is likely go in first.  Perhaps you want to base on it
>>> now.
>> 
>> I was not aware of that. Since I'm managing multiple series on a single branch
>> with stgit (and extracting that is somewhat tedious), I will redo this series
>> once Xia's is merged upstream. Is the merge going to happen anytime soon?

> I reviewed v7, and it looked almost ready to me.  If v8 is ready, it'll
> hopefully get merged fairly quickly (days, not weeks).

Excellent.


Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-03 15:27       ` Markus Armbruster
  2014-03-03 17:04         ` Lluís Vilanova
@ 2014-03-03 17:56         ` Eric Blake
  2014-03-04  8:02           ` Markus Armbruster
  1 sibling, 1 reply; 24+ messages in thread
From: Eric Blake @ 2014-03-03 17:56 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2446 bytes --]

On 03/03/2014 08:27 AM, Markus Armbruster wrote:

>>>> +The QAPI schema definitions can be modularized using the 'include'
>>>> directive:
>>>> +
>>>> + include("sub-system/qapi.json")
>>
>>> And now it isn't JSON anymore.
>>
>>> To keep it JSON, use syntax like
>>
>>>     { "include": "sub-system/qapi.json" }

I actually think this looks nicer - makes the file more consistent.

>>
>>> If you absolutely must make it non-JSON, you better rename the .json
>>> files.
>>
>>> Hmm, we already are non-JSON, because we use ' instead of " for no sane
>>> reason.

A weak argument: ' is easier than " to type (at least on US keyboards -
no shift key required).

Another weak argument: using ' in the qapi files vs. " in actual QMP
makes it easy to interleave discussions about semantics vs. examples of
those semantics in use (you can see whether a code snippet is talking
about qapi or wire format based on what quoting it used)

Our files are already non-JSON due to comments (JSON has no notion of #
introducing a comment to ignore text to the next newline).  But both our
use of comments and our use of ' instead of " can be remedied in a
one-pass sed script to get a true JSON output if such is needed, at
least as long as we don't need to quote any " characters in the schema.

Therefore, I agree that making the include syntax closer to true JSON is
desirable, whether or not we also decide to use " in the files to begin
with.  I don't see any way around the fact that JSON doesn't define
comments, vs. our absolute need for comments in our schema files, though.

>>
>>> Our JSON parser accepts ' as an extension, to save us quoting in C
>>> strings.  That reason doesn't apply to .json files.
>>
>> Is it a problem if they are not pure JSON? In the end, they are parsed by
>> qapi.py (which already knows about file syntax), and having a separate syntax
>> for includes makes it somewhat easier to spot when that happens.
> 
> I don't particularly care whether schema syntax is pure JSON, some
> bastardized variation of JSON, or something else entirely.  But as long
> as we advertize schema files it as .json, they better contain JSON.  If
> they contain something else, they should be called something else.

Maybe .qapi? But the name qapi-schema.qapi sounds redundant...

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-03 17:56         ` Eric Blake
@ 2014-03-04  8:02           ` Markus Armbruster
  2014-03-13 15:33             ` Benoît Canet
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Armbruster @ 2014-03-04  8:02 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

Eric Blake <eblake@redhat.com> writes:

> On 03/03/2014 08:27 AM, Markus Armbruster wrote:
>
>>>>> +The QAPI schema definitions can be modularized using the 'include'
>>>>> directive:
>>>>> +
>>>>> + include("sub-system/qapi.json")
>>>
>>>> And now it isn't JSON anymore.
>>>
>>>> To keep it JSON, use syntax like
>>>
>>>>     { "include": "sub-system/qapi.json" }
>
> I actually think this looks nicer - makes the file more consistent.

I suspect qapi.py would look nicer, too :)

>>>> If you absolutely must make it non-JSON, you better rename the .json
>>>> files.
>>>
>>>> Hmm, we already are non-JSON, because we use ' instead of " for no sane
>>>> reason.
>
> A weak argument: ' is easier than " to type (at least on US keyboards -
> no shift key required).
>
> Another weak argument: using ' in the qapi files vs. " in actual QMP
> makes it easy to interleave discussions about semantics vs. examples of
> those semantics in use (you can see whether a code snippet is talking
> about qapi or wire format based on what quoting it used)
>
> Our files are already non-JSON due to comments (JSON has no notion of #
> introducing a comment to ignore text to the next newline).  But both our
> use of comments and our use of ' instead of " can be remedied in a
> one-pass sed script to get a true JSON output if such is needed, at
> least as long as we don't need to quote any " characters in the schema.
>
> Therefore, I agree that making the include syntax closer to true JSON is
> desirable, whether or not we also decide to use " in the files to begin
> with.  I don't see any way around the fact that JSON doesn't define
> comments, vs. our absolute need for comments in our schema files, though.

We certainly can't do without comments.

JSON is designed for easy data exchange, but we use it as programming
language syntax.  Its restrictions make sense for easy data exchange,
but hurt our use.  We're not the first ones experiencing that pain:
http://json5.org/

No idea how much momentum this JSON5 thingy has...

>>>> Our JSON parser accepts ' as an extension, to save us quoting in C
>>>> strings.  That reason doesn't apply to .json files.
>>>
>>> Is it a problem if they are not pure JSON? In the end, they are parsed by
>>> qapi.py (which already knows about file syntax), and having a separate syntax
>>> for includes makes it somewhat easier to spot when that happens.
>> 
>> I don't particularly care whether schema syntax is pure JSON, some
>> bastardized variation of JSON, or something else entirely.  But as long
>> as we advertize schema files it as .json, they better contain JSON.  If
>> they contain something else, they should be called something else.
>
> Maybe .qapi? But the name qapi-schema.qapi sounds redundant...

schema.qapi?

Switch to JSON5 and call it qapi-schema.json5?

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-03-03 16:59         ` Lluís Vilanova
@ 2014-03-04 13:17           ` Markus Armbruster
  2014-03-05  0:58             ` Lluís Vilanova
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Armbruster @ 2014-03-04 13:17 UTC (permalink / raw)
  To: qemu-devel

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Markus Armbruster writes:
> [...]
>>>>> self.fp = schema.fp
>>>>> self.msg = msg
>>>>> self.line = self.col = 1
>>>>> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>>>>> self.col += 1
>>>>> 
>>>>> def __str__(self):
>>>>> - return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col,
>>>>> self.msg)
>>>>> +        name = os.path.relpath(self.fp.name, self.base)
>>>>> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)
>>> 
>>>> Can you explain what this change does, and why it's wanted?
>>> 
>>> Paths are shown as relative so that the test outputs (stderr) can be verified
>>> with diff. Otherwise the actual message depends on the path from which you're
>>> running the tests.
>
>> Hmm.  This is the applicable make rule:
>
>> $(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")
>> 	@diff -q $(SRC_PATH)/$*.out $*.test.out
>> 	@diff -q $(SRC_PATH)/$*.err $*.test.err
>> 	@diff -q $(SRC_PATH)/$*.exit $*.test.exit
>
>> Since $^ is in $(SRC_PATH), it's like $(SRC_PATH)/foo.json.  If
>> $(SRC_PATH)/foo.json has an error, the error messages duly points to
>> $(SRC_PATH)/foo.json.
>
>> The "diff -q $(SRC_PATH)/$*.err $*.test.err" fails unless your SRC_PATH
>> matches the one that's encoded in tests/qapi-schema/foo.err.  Is that
>> the problem you're trying to solve?
>
> Right. Paths are internally stored as absolute in "qapi.py" (to check for
> include cycles), and the "base directory" is only used to show them as
> relative. I can try to change the code to retain this functionality but without
> special-casing the tests.

Well, my fav method to check for include cycles is really simple:

1. Estimate how many levels of inclusion you're going to need.

2. Shift left a couple of times.

3. Error out when inclusion depth hits that limit.

Obviously 100% reliable.  File name comparisons tend to be unreliable or
unobvious :)

With this realpath business out of the way, file names in tests should
all be of the form $(SRC_PATH)/tests/qapi-schema/*.json, shouldn't they?

The $(SRC_PATH) prefix depends on where the user's build tree is, the
rest is fixed.  We could strip the prefix from error messages with a
simple filter:

    perl -pe 's,\Q$(SRC_PATH)/tests/qapi-schema/\E,tests/qapi-schema/,'

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file
  2014-03-04 13:17           ` Markus Armbruster
@ 2014-03-05  0:58             ` Lluís Vilanova
  0 siblings, 0 replies; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-05  0:58 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Markus Armbruster writes:

> Lluís Vilanova <vilanova@ac.upc.edu> writes:
>> Markus Armbruster writes:
>> [...]
>>>>>> self.fp = schema.fp
>>>>>> self.msg = msg
>>>>>> self.line = self.col = 1
>>>>>> @@ -50,12 +52,17 @@ class QAPISchemaError(Exception):
>>>>>> self.col += 1
>>>>>> 
>>>>>> def __str__(self):
>>>>>> - return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col,
>>>>>> self.msg)
>>>>>> +        name = os.path.relpath(self.fp.name, self.base)
>>>>>> +        return "%s:%s:%s: %s" % (name, self.line, self.col, self.msg)
>>>> 
>>>>> Can you explain what this change does, and why it's wanted?
>>>> 
>>>> Paths are shown as relative so that the test outputs (stderr) can be verified
>>>> with diff. Otherwise the actual message depends on the path from which you're
>>>> running the tests.
>> 
>>> Hmm.  This is the applicable make rule:
>> 
>>> $(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")
>>> @diff -q $(SRC_PATH)/$*.out $*.test.out
>>> @diff -q $(SRC_PATH)/$*.err $*.test.err
>>> @diff -q $(SRC_PATH)/$*.exit $*.test.exit
>> 
>>> Since $^ is in $(SRC_PATH), it's like $(SRC_PATH)/foo.json.  If
>>> $(SRC_PATH)/foo.json has an error, the error messages duly points to
>>> $(SRC_PATH)/foo.json.
>> 
>>> The "diff -q $(SRC_PATH)/$*.err $*.test.err" fails unless your SRC_PATH
>>> matches the one that's encoded in tests/qapi-schema/foo.err.  Is that
>>> the problem you're trying to solve?
>> 
>> Right. Paths are internally stored as absolute in "qapi.py" (to check for
>> include cycles), and the "base directory" is only used to show them as
>> relative. I can try to change the code to retain this functionality but without
>> special-casing the tests.

> Well, my fav method to check for include cycles is really simple:

> 1. Estimate how many levels of inclusion you're going to need.

> 2. Shift left a couple of times.

> 3. Error out when inclusion depth hits that limit.

> Obviously 100% reliable.  File name comparisons tend to be unreliable or
> unobvious :)

Yes, I just wanted to error-out in a more helpful way. I really hate to have
some arbitrary limit and an unhelpful (or unnecessarily long) message.


> With this realpath business out of the way, file names in tests should
> all be of the form $(SRC_PATH)/tests/qapi-schema/*.json, shouldn't they?

> The $(SRC_PATH) prefix depends on where the user's build tree is, the
> rest is fixed.  We could strip the prefix from error messages with a
> simple filter:

>     perl -pe 's,\Q$(SRC_PATH)/tests/qapi-schema/\E,tests/qapi-schema/,'

Right, post-processing is the other option, silly me.


Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-04  8:02           ` Markus Armbruster
@ 2014-03-13 15:33             ` Benoît Canet
  2014-03-13 15:54               ` Eric Blake
  0 siblings, 1 reply; 24+ messages in thread
From: Benoît Canet @ 2014-03-13 15:33 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

The Tuesday 04 Mar 2014 à 09:02:57 (+0100), Markus Armbruster wrote :
> Eric Blake <eblake@redhat.com> writes:
> 
> > On 03/03/2014 08:27 AM, Markus Armbruster wrote:
> >
> >>>>> +The QAPI schema definitions can be modularized using the 'include'
> >>>>> directive:
> >>>>> +
> >>>>> + include("sub-system/qapi.json")
> >>>
> >>>> And now it isn't JSON anymore.
> >>>
> >>>> To keep it JSON, use syntax like
> >>>
> >>>>     { "include": "sub-system/qapi.json" }
> >
> > I actually think this looks nicer - makes the file more consistent.
> 
> I suspect qapi.py would look nicer, too :)
> 
> >>>> If you absolutely must make it non-JSON, you better rename the .json
> >>>> files.
> >>>
> >>>> Hmm, we already are non-JSON, because we use ' instead of " for no sane
> >>>> reason.
> >
> > A weak argument: ' is easier than " to type (at least on US keyboards -
> > no shift key required).
> >
> > Another weak argument: using ' in the qapi files vs. " in actual QMP
> > makes it easy to interleave discussions about semantics vs. examples of
> > those semantics in use (you can see whether a code snippet is talking
> > about qapi or wire format based on what quoting it used)
> >
> > Our files are already non-JSON due to comments (JSON has no notion of #
> > introducing a comment to ignore text to the next newline).  But both our
> > use of comments and our use of ' instead of " can be remedied in a
> > one-pass sed script to get a true JSON output if such is needed, at
> > least as long as we don't need to quote any " characters in the schema.
> >
> > Therefore, I agree that making the include syntax closer to true JSON is
> > desirable, whether or not we also decide to use " in the files to begin
> > with.  I don't see any way around the fact that JSON doesn't define
> > comments, vs. our absolute need for comments in our schema files, though.
> 
> We certainly can't do without comments.
> 
> JSON is designed for easy data exchange, but we use it as programming
> language syntax.  Its restrictions make sense for easy data exchange,
> but hurt our use.  We're not the first ones experiencing that pain:
> http://json5.org/
> 
> No idea how much momentum this JSON5 thingy has...
> 
> >>>> Our JSON parser accepts ' as an extension, to save us quoting in C
> >>>> strings.  That reason doesn't apply to .json files.
> >>>
> >>> Is it a problem if they are not pure JSON? In the end, they are parsed by
> >>> qapi.py (which already knows about file syntax), and having a separate syntax
> >>> for includes makes it somewhat easier to spot when that happens.
> >> 
> >> I don't particularly care whether schema syntax is pure JSON, some
> >> bastardized variation of JSON, or something else entirely.  But as long
> >> as we advertize schema files it as .json, they better contain JSON.  If
> >> they contain something else, they should be called something else.
> >
> > Maybe .qapi? But the name qapi-schema.qapi sounds redundant...
> 
> schema.qapi?
> 
> Switch to JSON5 and call it qapi-schema.json5?
> 

Hmm don't we want something that python and other language know how to parse out
of the box ? Or will we write yet another delicate work of art to parse it ?

Best regards

Benoît

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-13 15:33             ` Benoît Canet
@ 2014-03-13 15:54               ` Eric Blake
  2014-03-13 18:05                 ` Lluís Vilanova
  2014-03-17 14:20                 ` Benoît Canet
  0 siblings, 2 replies; 24+ messages in thread
From: Eric Blake @ 2014-03-13 15:54 UTC (permalink / raw)
  To: Benoît Canet, Markus Armbruster; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1448 bytes --]

On 03/13/2014 09:33 AM, Benoît Canet wrote:

>> We certainly can't do without comments.
>>
>> JSON is designed for easy data exchange, but we use it as programming
>> language syntax.  Its restrictions make sense for easy data exchange,
>> but hurt our use.  We're not the first ones experiencing that pain:
>> http://json5.org/
>>
>> No idea how much momentum this JSON5 thingy has...

If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
everything else in our files is already compliant with JSON5.

>>
>> Switch to JSON5 and call it qapi-schema.json5?

This actually seems like a rather nice idea - but due to our choice of
comments, it means rewriting the bulk of the file and tweaking our parser.

>>
> 
> Hmm don't we want something that python and other language know how to parse out
> of the box ? Or will we write yet another delicate work of art to parse it ?

Our existing parser would only need to learn a new comment syntax to
parse the subset of JSON5 that we currently actually use.  Parsing FULL
JSON5 would mean also learning about trailing commas, unquoted names in
name:value pairs, multiline strings, and alternative numeric
representations.  But a point made on the JSON5 page is that ES5
JavaScript already parses JSON5, just as it already parses original JSON.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-13 15:54               ` Eric Blake
@ 2014-03-13 18:05                 ` Lluís Vilanova
  2014-03-14 16:35                   ` Benoît Canet
  2014-03-17 14:20                 ` Benoît Canet
  1 sibling, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-13 18:05 UTC (permalink / raw)
  To: Eric Blake; +Cc: Benoît Canet, Markus Armbruster, qemu-devel

Eric Blake writes:

> On 03/13/2014 09:33 AM, Benoît Canet wrote:
>>> We certainly can't do without comments.
>>> 
>>> JSON is designed for easy data exchange, but we use it as programming
>>> language syntax.  Its restrictions make sense for easy data exchange,
>>> but hurt our use.  We're not the first ones experiencing that pain:
>>> http://json5.org/
>>> 
>>> No idea how much momentum this JSON5 thingy has...

> If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
> everything else in our files is already compliant with JSON5.

>>> 
>>> Switch to JSON5 and call it qapi-schema.json5?

> This actually seems like a rather nice idea - but due to our choice of
> comments, it means rewriting the bulk of the file and tweaking our parser.

>>> 
>> 
>> Hmm don't we want something that python and other language know how to parse out
>> of the box ? Or will we write yet another delicate work of art to parse it ?

> Our existing parser would only need to learn a new comment syntax to
> parse the subset of JSON5 that we currently actually use.  Parsing FULL
> JSON5 would mean also learning about trailing commas, unquoted names in
> name:value pairs, multiline strings, and alternative numeric
> representations.  But a point made on the JSON5 page is that ES5
> JavaScript already parses JSON5, just as it already parses original JSON.

Another option is to bump QEMU requirements to python 2.6 or later. Then we can
use the json parser that comes with python. A simple pre-processing could
eliminate the comments before passing them to the json package for loading into
python structures. The commands/enums/etc should also be elements of a list for
it to work (that must be either changed on the qapi files, or hackishly
"injected" before parsing).


Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-13 18:05                 ` Lluís Vilanova
@ 2014-03-14 16:35                   ` Benoît Canet
  2014-03-14 20:24                     ` Lluís Vilanova
  0 siblings, 1 reply; 24+ messages in thread
From: Benoît Canet @ 2014-03-14 16:35 UTC (permalink / raw)
  To: Eric Blake, Benoît Canet, Markus Armbruster, qemu-devel

The Thursday 13 Mar 2014 à 19:05:12 (+0100), Lluís Vilanova wrote :
> Eric Blake writes:
> 
> > On 03/13/2014 09:33 AM, Benoît Canet wrote:
> >>> We certainly can't do without comments.
> >>> 
> >>> JSON is designed for easy data exchange, but we use it as programming
> >>> language syntax.  Its restrictions make sense for easy data exchange,
> >>> but hurt our use.  We're not the first ones experiencing that pain:
> >>> http://json5.org/
> >>> 
> >>> No idea how much momentum this JSON5 thingy has...
> 
> > If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
> > everything else in our files is already compliant with JSON5.
> 
> >>> 
> >>> Switch to JSON5 and call it qapi-schema.json5?
> 
> > This actually seems like a rather nice idea - but due to our choice of
> > comments, it means rewriting the bulk of the file and tweaking our parser.
> 
> >>> 
> >> 
> >> Hmm don't we want something that python and other language know how to parse out
> >> of the box ? Or will we write yet another delicate work of art to parse it ?
> 
> > Our existing parser would only need to learn a new comment syntax to
> > parse the subset of JSON5 that we currently actually use.  Parsing FULL
> > JSON5 would mean also learning about trailing commas, unquoted names in
> > name:value pairs, multiline strings, and alternative numeric
> > representations.  But a point made on the JSON5 page is that ES5
> > JavaScript already parses JSON5, just as it already parses original JSON.
> 
> Another option is to bump QEMU requirements to python 2.6 or later. Then we can
> use the json parser that comes with python. A simple pre-processing could
> eliminate the comments before passing them to the json package for loading into
> python structures. The commands/enums/etc should also be elements of a list for
> it to work (that must be either changed on the qapi files, or hackishly
> "injected" before parsing).
> 
> 
> Lluis

I have an use case for this series.

Lluis: Do you plan to respin this series ? Or should I do it ?

Best regards

Benoît

> 
> -- 
>  "And it's much the same thing with knowledge, for whenever you learn
>  something new, the whole world becomes that much richer."
>  -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
>  Tollbooth
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-14 16:35                   ` Benoît Canet
@ 2014-03-14 20:24                     ` Lluís Vilanova
  2014-03-14 21:55                       ` Benoît Canet
  0 siblings, 1 reply; 24+ messages in thread
From: Lluís Vilanova @ 2014-03-14 20:24 UTC (permalink / raw)
  To: Benoît Canet; +Cc: Markus Armbruster, qemu-devel

Benoît Canet writes:

> The Thursday 13 Mar 2014 à 19:05:12 (+0100), Lluís Vilanova wrote :
>> Eric Blake writes:
>> 
>> > On 03/13/2014 09:33 AM, Benoît Canet wrote:
>> >>> We certainly can't do without comments.
>> >>> 
>> >>> JSON is designed for easy data exchange, but we use it as programming
>> >>> language syntax.  Its restrictions make sense for easy data exchange,
>> >>> but hurt our use.  We're not the first ones experiencing that pain:
>> >>> http://json5.org/
>> >>> 
>> >>> No idea how much momentum this JSON5 thingy has...
>> 
>> > If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
>> > everything else in our files is already compliant with JSON5.
>> 
>> >>> 
>> >>> Switch to JSON5 and call it qapi-schema.json5?
>> 
>> > This actually seems like a rather nice idea - but due to our choice of
>> > comments, it means rewriting the bulk of the file and tweaking our parser.
>> 
>> >>> 
>> >> 
>> >> Hmm don't we want something that python and other language know how to parse out
>> >> of the box ? Or will we write yet another delicate work of art to parse it ?
>> 
>> > Our existing parser would only need to learn a new comment syntax to
>> > parse the subset of JSON5 that we currently actually use.  Parsing FULL
>> > JSON5 would mean also learning about trailing commas, unquoted names in
>> > name:value pairs, multiline strings, and alternative numeric
>> > representations.  But a point made on the JSON5 page is that ES5
>> > JavaScript already parses JSON5, just as it already parses original JSON.
>> 
>> Another option is to bump QEMU requirements to python 2.6 or later. Then we can
>> use the json parser that comes with python. A simple pre-processing could
>> eliminate the comments before passing them to the json package for loading into
>> python structures. The commands/enums/etc should also be elements of a list for
>> it to work (that must be either changed on the qapi files, or hackishly
>> "injected" before parsing).
>> 
>> 
>> Lluis

> I have an use case for this series.

> Lluis: Do you plan to respin this series ? Or should I do it ?

I was waiting for some other series to get merged, since they conflict. But I
still did not change the "include" syntax.

I will probably not be able to get to this until May 1st.


Lluis


-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-14 20:24                     ` Lluís Vilanova
@ 2014-03-14 21:55                       ` Benoît Canet
  0 siblings, 0 replies; 24+ messages in thread
From: Benoît Canet @ 2014-03-14 21:55 UTC (permalink / raw)
  To: Benoît Canet, Eric Blake, Markus Armbruster, qemu-devel

The Friday 14 Mar 2014 à 21:24:38 (+0100), Lluís Vilanova wrote :
> Benoît Canet writes:
> 
> > The Thursday 13 Mar 2014 à 19:05:12 (+0100), Lluís Vilanova wrote :
> >> Eric Blake writes:
> >> 
> >> > On 03/13/2014 09:33 AM, Benoît Canet wrote:
> >> >>> We certainly can't do without comments.
> >> >>> 
> >> >>> JSON is designed for easy data exchange, but we use it as programming
> >> >>> language syntax.  Its restrictions make sense for easy data exchange,
> >> >>> but hurt our use.  We're not the first ones experiencing that pain:
> >> >>> http://json5.org/
> >> >>> 
> >> >>> No idea how much momentum this JSON5 thingy has...
> >> 
> >> > If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
> >> > everything else in our files is already compliant with JSON5.
> >> 
> >> >>> 
> >> >>> Switch to JSON5 and call it qapi-schema.json5?
> >> 
> >> > This actually seems like a rather nice idea - but due to our choice of
> >> > comments, it means rewriting the bulk of the file and tweaking our parser.
> >> 
> >> >>> 
> >> >> 
> >> >> Hmm don't we want something that python and other language know how to parse out
> >> >> of the box ? Or will we write yet another delicate work of art to parse it ?
> >> 
> >> > Our existing parser would only need to learn a new comment syntax to
> >> > parse the subset of JSON5 that we currently actually use.  Parsing FULL
> >> > JSON5 would mean also learning about trailing commas, unquoted names in
> >> > name:value pairs, multiline strings, and alternative numeric
> >> > representations.  But a point made on the JSON5 page is that ES5
> >> > JavaScript already parses JSON5, just as it already parses original JSON.
> >> 
> >> Another option is to bump QEMU requirements to python 2.6 or later. Then we can
> >> use the json parser that comes with python. A simple pre-processing could
> >> eliminate the comments before passing them to the json package for loading into
> >> python structures. The commands/enums/etc should also be elements of a list for
> >> it to work (that must be either changed on the qapi files, or hackishly
> >> "injected" before parsing).
> >> 
> >> 
> >> Lluis
> 
> > I have an use case for this series.
> 
> > Lluis: Do you plan to respin this series ? Or should I do it ?
> 
> I was waiting for some other series to get merged, since they conflict. But I
> still did not change the "include" syntax.
> 
> I will probably not be able to get to this until May 1st.

Ok, I think I need the include feature more badly than you I will do it.

Best regards

Benoît

> 
> 
> Lluis
> 
> 
> -- 
>  "And it's much the same thing with knowledge, for whenever you learn
>  something new, the whole world becomes that much richer."
>  -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
>  Tollbooth

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file
  2014-03-13 15:54               ` Eric Blake
  2014-03-13 18:05                 ` Lluís Vilanova
@ 2014-03-17 14:20                 ` Benoît Canet
  1 sibling, 0 replies; 24+ messages in thread
From: Benoît Canet @ 2014-03-17 14:20 UTC (permalink / raw)
  To: Eric Blake; +Cc: Benoît Canet, Markus Armbruster, qemu-devel

The Thursday 13 Mar 2014 à 09:54:15 (-0600), Eric Blake wrote :
> On 03/13/2014 09:33 AM, Benoît Canet wrote:
> 
> >> We certainly can't do without comments.
> >>
> >> JSON is designed for easy data exchange, but we use it as programming
> >> language syntax.  Its restrictions make sense for easy data exchange,
> >> but hurt our use.  We're not the first ones experiencing that pain:
> >> http://json5.org/
> >>
> >> No idea how much momentum this JSON5 thingy has...
> 
> If we 's,#,//,', our comments magically fall in line with JSON5 syntax;
> everything else in our files is already compliant with JSON5.

Not really qapi-schema.json is missing comas between types to be a
valid json file.

The fragment:

{ 'type'  : 'InputBtnEvent',
  'data'  : { 'button'  : 'InputButton',
              'down'    : 'bool' } }

{ 'type'  : 'InputMoveEvent',
  'data'  : { 'axis'    : 'InputAxis',
              'value'   : 'int' } }

Should be:

[

{ 'type'  : 'InputBtnEvent',
  'data'  : { 'button'  : 'InputButton',
              'down'    : 'bool' } },

{ 'type'  : 'InputMoveEvent',
  'data'  : { 'axis'    : 'InputAxis',
              'value'   : 'int' } }

]

to hope being a valid json file.

Best regards

Benoît

> 
> >>
> >> Switch to JSON5 and call it qapi-schema.json5?
> 
> This actually seems like a rather nice idea - but due to our choice of
> comments, it means rewriting the bulk of the file and tweaking our parser.
> 
> >>
> > 
> > Hmm don't we want something that python and other language know how to parse out
> > of the box ? Or will we write yet another delicate work of art to parse it ?
> 
> Our existing parser would only need to learn a new comment syntax to
> parse the subset of JSON5 that we currently actually use.  Parsing FULL
> JSON5 would mean also learning about trailing commas, unquoted names in
> name:value pairs, multiline strings, and alternative numeric
> representations.  But a point made on the JSON5 page is that ES5
> JavaScript already parses JSON5, just as it already parses original JSON.
> 
> -- 
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2014-03-17 14:20 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-28 15:53 [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Lluís Vilanova
2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 1/3] qapi: Use an explicit input file Lluís Vilanova
2014-03-01  8:35   ` Markus Armbruster
2014-03-03 14:25     ` Lluís Vilanova
2014-03-03 15:42       ` Markus Armbruster
2014-03-03 16:59         ` Lluís Vilanova
2014-03-04 13:17           ` Markus Armbruster
2014-03-05  0:58             ` Lluís Vilanova
2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 2/3] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
2014-03-01  8:57   ` Markus Armbruster
2014-03-03 14:21     ` Lluís Vilanova
2014-03-03 15:27       ` Markus Armbruster
2014-03-03 17:04         ` Lluís Vilanova
2014-03-03 17:56         ` Eric Blake
2014-03-04  8:02           ` Markus Armbruster
2014-03-13 15:33             ` Benoît Canet
2014-03-13 15:54               ` Eric Blake
2014-03-13 18:05                 ` Lluís Vilanova
2014-03-14 16:35                   ` Benoît Canet
2014-03-14 20:24                     ` Lluís Vilanova
2014-03-14 21:55                       ` Benoît Canet
2014-03-17 14:20                 ` Benoît Canet
2014-02-28 15:53 ` [Qemu-devel] [PATCH v4 3/3] qapi: Add tests for the "include" directive Lluís Vilanova
2014-02-28 16:18 ` [Qemu-devel] [PATCH v4 0/3] qapi: Allow modularization of QAPI schema files Eric Blake

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).