[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCHv52/3] qapi: Add a primitive to include other files f
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCHv52/3] qapi: Add a primitive to include other files from a QAPI schema file |
Date: |
Sun, 30 Mar 2014 22:35:21 +0200 |
User-agent: |
StGit/0.17.1-dirty |
Signed-off-by: Lluís Vilanova <address@hidden>
---
docs/qapi-code-gen.txt | 7 +++++++
scripts/qapi.py | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 824f6e5..1e19f64 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -40,6 +40,13 @@ 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': 'path/to/file.json'}
+
+Include paths are relative to the file using the directive.
+
+
=== 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 3a38e27..f6e16ff 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -11,6 +11,8 @@
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
+import os
+import re
from ordereddict import OrderedDict
import os
import sys
@@ -62,8 +64,11 @@ class QAPIExprError(Exception):
class QAPISchema:
- def __init__(self, fp):
+ def __init__(self, fp, included=[]):
self.fp = fp
+ input_path = os.path.abspath(fp.name)
+ self.included = included + [input_path]
+ self.input_dir = os.path.dirname(input_path)
self.src = fp.read()
if self.src == '' or self.src[-1] != '\n':
self.src += '\n'
@@ -75,9 +80,29 @@ class QAPISchema:
while self.tok != None:
expr_info = {'fp': fp, 'line': self.line}
- expr_elem = {'expr': self.get_expr(False),
- 'info': expr_info}
- self.exprs.append(expr_elem)
+ expr = self.get_expr(False)
+ if isinstance(expr, dict) and "include" in expr:
+ if len(expr) != 1:
+ raise QAPIExprError(expr_info, "Invalid 'include'
directive")
+ include_path = expr["include"]
+ if not os.path.isabs(include_path):
+ include_path = os.path.join(self.input_dir, include_path)
+ if not os.path.isfile(include_path):
+ raise QAPIExprError(
+ expr_info,
+ 'Non-existing included file "%s"' %
+ include_path)
+ if include_path in self.included:
+ raise QAPIExprError(expr_info, "Infinite inclusion loop:
%s"
+ % " -> ".join(self.included +
+ [include_path]))
+ exprs_include = QAPISchema(open(include_path, "r"),
+ self.included)
+ self.exprs.extend(exprs_include.exprs)
+ else:
+ expr_elem = {'expr': expr,
+ 'info': expr_info}
+ self.exprs.append(expr_elem)
def accept(self):
while True:
@@ -267,7 +292,7 @@ def check_exprs(schema):
def parse_schema(input_path):
try:
schema = QAPISchema(open(input_path, "r"))
- except QAPISchemaError, e:
+ except (QAPISchemaError, QAPIExprError), e:
print >>sys.stderr, e
exit(1)