diff options
-rw-r--r-- | scripts/qapi.py | 163 | ||||
-rw-r--r-- | tests/qapi-schema/indented-expr.out | 2 | ||||
-rw-r--r-- | tests/qapi-schema/missing-colon.out | 4 | ||||
-rw-r--r-- | tests/qapi-schema/quoted-structural-chars.err | 1 | ||||
-rw-r--r-- | tests/qapi-schema/quoted-structural-chars.exit | 2 | ||||
-rw-r--r-- | tests/qapi-schema/quoted-structural-chars.out | 3 |
6 files changed, 88 insertions, 87 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py index 38c808e..58e315b 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -2,9 +2,11 @@ # QAPI helper library # # Copyright IBM, Corp. 2011 +# Copyright (c) 2013 Red Hat Inc. # # Authors: # Anthony Liguori <aliguori@us.ibm.com> +# Markus Armbruster <armbru@redhat.com> # # This work is licensed under the terms of the GNU GPLv2. # See the COPYING.LIB file in the top-level directory. @@ -32,91 +34,92 @@ builtin_type_qtypes = { 'uint64': 'QTYPE_QINT', } -def tokenize(data): - while len(data): - ch = data[0] - data = data[1:] - if ch in ['{', '}', ':', ',', '[', ']']: - yield ch - elif ch in ' \n': - None - elif ch == "'": - string = '' - esc = False - while True: - if (data == ''): - raise Exception("Mismatched quotes") - ch = data[0] - data = data[1:] - if esc: - string += ch - esc = False - elif ch == "\\": - esc = True - elif ch == "'": - break - else: - string += ch - yield string - -def parse(tokens): - if tokens[0] == '{': - ret = OrderedDict() - tokens = tokens[1:] - while tokens[0] != '}': - key = tokens[0] - tokens = tokens[1:] - - tokens = tokens[1:] # : - - value, tokens = parse(tokens) - - if tokens[0] == ',': - tokens = tokens[1:] - - ret[key] = value - tokens = tokens[1:] - return ret, tokens - elif tokens[0] == '[': - ret = [] - tokens = tokens[1:] - while tokens[0] != ']': - value, tokens = parse(tokens) - if tokens[0] == ',': - tokens = tokens[1:] - ret.append(value) - tokens = tokens[1:] - return ret, tokens - else: - return tokens[0], tokens[1:] - -def evaluate(string): - return parse(map(lambda x: x, tokenize(string)))[0] - -def get_expr(fp): - expr = '' - - for line in fp: - if line.startswith('#') or line == '\n': - continue - - if line.startswith(' '): - expr += line - elif expr: - yield expr - expr = line +class QAPISchema: + + def __init__(self, fp): + self.fp = fp + self.src = fp.read() + if self.src == '' or self.src[-1] != '\n': + self.src += '\n' + self.cursor = 0 + self.exprs = [] + self.accept() + + while self.tok != None: + self.exprs.append(self.get_expr()) + + def accept(self): + while True: + bol = self.cursor == 0 or self.src[self.cursor-1] == '\n' + self.tok = self.src[self.cursor] + self.cursor += 1 + self.val = None + + if self.tok == '#' and bol: + self.cursor = self.src.find('\n', self.cursor) + elif self.tok in ['{', '}', ':', ',', '[', ']']: + return + elif self.tok == "'": + string = '' + esc = False + while True: + ch = self.src[self.cursor] + self.cursor += 1 + if ch == '\n': + raise Exception("Mismatched quotes") + if esc: + string += ch + esc = False + elif ch == "\\": + esc = True + elif ch == "'": + self.val = string + return + else: + string += ch + elif self.tok == '\n': + if self.cursor == len(self.src): + self.tok = None + return + + def get_members(self): + expr = OrderedDict() + while self.tok != '}': + key = self.val + self.accept() + self.accept() # : + expr[key] = self.get_expr() + if self.tok == ',': + self.accept() + self.accept() + return expr + + def get_values(self): + expr = [] + while self.tok != ']': + expr.append(self.get_expr()) + if self.tok == ',': + self.accept() + self.accept() + return expr + + def get_expr(self): + if self.tok == '{': + self.accept() + expr = self.get_members() + elif self.tok == '[': + self.accept() + expr = self.get_values() else: - expr += line - - if expr: - yield expr + expr = self.val + self.accept() + return expr def parse_schema(fp): + schema = QAPISchema(fp) exprs = [] - for expr in get_expr(fp): - expr_eval = evaluate(expr) - + for expr_eval in schema.exprs: if expr_eval.has_key('enum'): add_enum(expr_eval['enum']) elif expr_eval.has_key('union'): diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index 98ae692..98af89a 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -1,3 +1,3 @@ -[OrderedDict([('id', 'eins')])] +[OrderedDict([('id', 'eins')]), OrderedDict([('id', 'zwei')])] [] [] diff --git a/tests/qapi-schema/missing-colon.out b/tests/qapi-schema/missing-colon.out index 50f827e..e67068c 100644 --- a/tests/qapi-schema/missing-colon.out +++ b/tests/qapi-schema/missing-colon.out @@ -1,3 +1,3 @@ -[OrderedDict([('enum', ','), ('data', ['good', 'bad', 'ugly'])])] -[','] +[OrderedDict([('enum', None), ('data', ['good', 'bad', 'ugly'])])] +[None] [] diff --git a/tests/qapi-schema/quoted-structural-chars.err b/tests/qapi-schema/quoted-structural-chars.err index e69de29..48c849d 100644 --- a/tests/qapi-schema/quoted-structural-chars.err +++ b/tests/qapi-schema/quoted-structural-chars.err @@ -0,0 +1 @@ +Crashed: <type 'exceptions.AttributeError'> diff --git a/tests/qapi-schema/quoted-structural-chars.exit b/tests/qapi-schema/quoted-structural-chars.exit index 573541a..d00491f 100644 --- a/tests/qapi-schema/quoted-structural-chars.exit +++ b/tests/qapi-schema/quoted-structural-chars.exit @@ -1 +1 @@ -0 +1 diff --git a/tests/qapi-schema/quoted-structural-chars.out b/tests/qapi-schema/quoted-structural-chars.out index 85405be..e69de29 100644 --- a/tests/qapi-schema/quoted-structural-chars.out +++ b/tests/qapi-schema/quoted-structural-chars.out @@ -1,3 +0,0 @@ -[OrderedDict([('key1', 'value1'), ('key2', [])])] -[] -[] |