diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-05-09 15:46:34 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-05-09 15:46:34 +0100 |
commit | 06b4f00d53637f2c16a62c2cbaa30bffb045cf88 (patch) | |
tree | 4b3c8803e3947c3f1a87d4da1b5c77362dede250 /scripts | |
parent | 43cbeffb19877c62cbe0aaf08b2f235d98d71340 (diff) | |
parent | b690d679c1ca65d71b0544a2331d50e9f0f95116 (diff) |
Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp: (38 commits)
Revert "qapi: Clean up superfluous null check in qapi_dealloc_type_str()"
qapi: Document optional arguments' backwards compatibility
qmp: use valid JSON in transaction example
qmp: Don't use error_is_set() to suppress additional errors
dump: Drop pointless error_is_set(), DumpState member errp
qemu-option: Clean up fragile use of error_is_set()
qga: Drop superfluous error_is_set()
qga: Clean up fragile use of error_is_set()
qapi: Clean up fragile use of error_is_set()
tests/qapi-schema: Drop superfluous error_is_set()
qapi: Drop redundant, unclean error_is_set()
hmp: Guard against misuse of hmp_handle_error()
qga: Use return values instead of error_is_set(errp)
error: Consistently name Error ** objects errp, and not err
qmp: Consistently name Error ** objects errp, and not err
qga: Consistently name Error ** objects errp, and not err
qmp hmp: Consistently name Error * objects err, and not errp
pci-assign: assigned_initfn(): set monitor error in common error handler
pci-assign: propagate errors from assign_intx()
pci-assign: propagate errors from assign_device()
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/qapi-commands.py | 9 | ||||
-rw-r--r-- | scripts/qapi-types.py | 9 | ||||
-rw-r--r-- | scripts/qapi-visit.py | 9 | ||||
-rw-r--r-- | scripts/qapi.py | 69 |
4 files changed, 73 insertions, 23 deletions
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 9734ab0a53..8d9096f65c 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -369,9 +369,10 @@ 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) @@ -389,6 +390,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"): @@ -420,7 +423,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 10864efc58..b4632324a7 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -279,14 +279,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' @@ -298,6 +299,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"): @@ -378,7 +381,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 45ce3a957a..c6579beed5 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -397,13 +397,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' @@ -416,6 +417,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"): @@ -494,7 +497,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 b474c39558..ec806aabeb 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -11,7 +11,9 @@ # This work is licensed under the terms of the GNU GPL, version 2. # See the COPYING file in the top-level directory. +import re from ordereddict import OrderedDict +import os import sys builtin_types = [ @@ -35,9 +37,17 @@ builtin_type_qtypes = { 'uint64': 'QTYPE_QINT', } +def error_path(parent): + res = "" + while parent: + res = ("In file included from %s:%d:\n" % (parent['file'], + parent['line'])) + res + parent = parent['parent'] + return res + class QAPISchemaError(Exception): def __init__(self, schema, msg): - self.fp = schema.fp + self.input_file = schema.input_file self.msg = msg self.col = 1 self.line = schema.line @@ -46,23 +56,31 @@ class QAPISchemaError(Exception): self.col = (self.col + 7) % 8 + 1 else: self.col += 1 + self.info = schema.parent_info def __str__(self): - return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg) + return error_path(self.info) + \ + "%s:%d:%d: %s" % (self.input_file, self.line, self.col, self.msg) class QAPIExprError(Exception): def __init__(self, expr_info, msg): - self.fp = expr_info['fp'] - self.line = expr_info['line'] + self.info = expr_info self.msg = msg def __str__(self): - return "%s:%s: %s" % (self.fp.name, self.line, self.msg) + return error_path(self.info['parent']) + \ + "%s:%d: %s" % (self.info['file'], self.info['line'], self.msg) class QAPISchema: - def __init__(self, fp): - self.fp = fp + def __init__(self, fp, input_relname=None, include_hist=[], parent_info=None): + input_fname = os.path.abspath(fp.name) + if input_relname is None: + input_relname = fp.name + self.input_dir = os.path.dirname(input_fname) + self.input_file = input_relname + self.include_hist = include_hist + [(input_relname, input_fname)] + self.parent_info = parent_info self.src = fp.read() if self.src == '' or self.src[-1] != '\n': self.src += '\n' @@ -73,10 +91,33 @@ class QAPISchema: self.accept() 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_info = {'file': input_relname, 'line': self.line, 'parent': self.parent_info} + 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 = expr["include"] + if not isinstance(include, str): + raise QAPIExprError(expr_info, + 'Expected a file name (string), got: %s' + % include) + include_path = os.path.join(self.input_dir, include) + if any(include_path == elem[1] + for elem in self.include_hist): + raise QAPIExprError(expr_info, "Inclusion loop for %s" + % include) + try: + fobj = open(include_path, 'r') + except IOError as e: + raise QAPIExprError(expr_info, + '%s: %s' % (e.strerror, include)) + exprs_include = QAPISchema(fobj, include, + self.include_hist, expr_info) + self.exprs.extend(exprs_include.exprs) + else: + expr_elem = {'expr': expr, + 'info': expr_info} + self.exprs.append(expr_elem) def accept(self): while True: @@ -263,10 +304,10 @@ def check_exprs(schema): if expr.has_key('union'): check_union(expr, expr_elem['info']) -def parse_schema(fp): +def parse_schema(input_file): try: - schema = QAPISchema(fp) - except QAPISchemaError, e: + schema = QAPISchema(open(input_file, "r")) + except (QAPISchemaError, QAPIExprError), e: print >>sys.stderr, e exit(1) |