aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/qapi.py163
-rw-r--r--tests/qapi-schema/indented-expr.out2
-rw-r--r--tests/qapi-schema/missing-colon.out4
-rw-r--r--tests/qapi-schema/quoted-structural-chars.err1
-rw-r--r--tests/qapi-schema/quoted-structural-chars.exit2
-rw-r--r--tests/qapi-schema/quoted-structural-chars.out3
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', [])])]
-[]
-[]