Message ID | 1374842387-17146-5-git-send-email-armbru@redhat.com |
---|---|
State | New |
Headers | show |
On 07/26/2013 06:39 AM, Markus Armbruster wrote: > Signed-off-by: Markus Armbruster <armbru@redhat.com> > --- > scripts/qapi.py | 29 +++++++++++++++++++++++++++-- > tests/qapi-schema/test-qapi.py | 2 ++ > tests/qapi-schema/unclosed-string.err | 2 +- > 3 files changed, 30 insertions(+), 3 deletions(-) > > +class QAPISchemaError(Exception): > + def __init__(self, schema, msg): > + self.fp = schema.fp > + self.msg = msg > + self.line = self.col = 1 > + for ch in schema.src[0:schema.pos]: > + if ch == '\n': > + self.line += 1 > + self.col = 1 > + elif ch == '\t': > + self.col = (self.col + 7) % 8 + 1 Do we even want to allow TABs in the schema files? Right now, they are tab-free; if you error out here instead of futzing with tab width, we could forcefully maintain that property. > + else: > + self.col += 1 Does python support ++ as shorthand for += 1? Reviewed-by: Eric Blake <eblake@redhat.com>
Eric Blake <eblake@redhat.com> writes: > On 07/26/2013 06:39 AM, Markus Armbruster wrote: >> Signed-off-by: Markus Armbruster <armbru@redhat.com> >> --- >> scripts/qapi.py | 29 +++++++++++++++++++++++++++-- >> tests/qapi-schema/test-qapi.py | 2 ++ >> tests/qapi-schema/unclosed-string.err | 2 +- >> 3 files changed, 30 insertions(+), 3 deletions(-) > >> >> +class QAPISchemaError(Exception): >> + def __init__(self, schema, msg): >> + self.fp = schema.fp >> + self.msg = msg >> + self.line = self.col = 1 >> + for ch in schema.src[0:schema.pos]: >> + if ch == '\n': >> + self.line += 1 >> + self.col = 1 >> + elif ch == '\t': >> + self.col = (self.col + 7) % 8 + 1 > > Do we even want to allow TABs in the schema files? Right now, they are > tab-free; if you error out here instead of futzing with tab width, we > could forcefully maintain that property. I'm not volunteering for the TAB police, but if y'all want the parser to reject TABs, I can do that. >> + else: >> + self.col += 1 > > Does python support ++ as shorthand for += 1? It doesn't, sadly. > Reviewed-by: Eric Blake <eblake@redhat.com>
Il 26/07/2013 21:33, Markus Armbruster ha scritto: > > Do we even want to allow TABs in the schema files? Right now, they are > > tab-free; if you error out here instead of futzing with tab width, we > > could forcefully maintain that property. > > I'm not volunteering for the TAB police, but if y'all want the parser to > reject TABs, I can do that. No, please don't. TAB is whitespace in JSON, and should be whitespace in schema files. Paolo
On 07/26/2013 01:48 PM, Paolo Bonzini wrote: > Il 26/07/2013 21:33, Markus Armbruster ha scritto: >>> Do we even want to allow TABs in the schema files? Right now, they are >>> tab-free; if you error out here instead of futzing with tab width, we >>> could forcefully maintain that property. >> >> I'm not volunteering for the TAB police, but if y'all want the parser to >> reject TABs, I can do that. > > No, please don't. TAB is whitespace in JSON, and should be whitespace > in schema files. Good argument. Just because we don't use it now doesn't mean we have to actively forbid it from future use; and the more we diverge from the JSON spec, the more we are stuck maintaining our parser by hand.
diff --git a/scripts/qapi.py b/scripts/qapi.py index cac56b7..35ff76e 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 sys builtin_types = [ 'str', 'int', 'number', 'bool', @@ -19,6 +20,23 @@ builtin_types = [ 'uint8', 'uint16', 'uint32', 'uint64' ] +class QAPISchemaError(Exception): + def __init__(self, schema, msg): + self.fp = schema.fp + self.msg = msg + self.line = self.col = 1 + for ch in schema.src[0:schema.pos]: + if ch == '\n': + self.line += 1 + self.col = 1 + elif ch == '\t': + self.col = (self.col + 7) % 8 + 1 + else: + self.col += 1 + + def __str__(self): + return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg) + class QAPISchema: def __init__(self, fp): @@ -37,6 +55,7 @@ class QAPISchema: while True: bol = self.cursor == 0 or self.src[self.cursor-1] == '\n' self.tok = self.src[self.cursor] + self.pos = self.cursor self.cursor += 1 self.val = None @@ -51,7 +70,8 @@ class QAPISchema: ch = self.src[self.cursor] self.cursor += 1 if ch == '\n': - raise Exception("Mismatched quotes") + raise QAPISchemaError(self, + 'Missing terminating "\'"') if esc: string += ch esc = False @@ -101,7 +121,12 @@ class QAPISchema: return expr def parse_schema(fp): - schema = QAPISchema(fp) + try: + schema = QAPISchema(fp) + except QAPISchemaError as e: + print >>sys.stderr, e + exit(1) + exprs = [] for expr_eval in schema.exprs: diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 3280eff..b3d1e1d 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -16,6 +16,8 @@ import sys try: exprs = parse_schema(sys.stdin) +except SystemExit: + raise except: print >>sys.stderr, "Crashed:", sys.exc_info()[0] exit(1) diff --git a/tests/qapi-schema/unclosed-string.err b/tests/qapi-schema/unclosed-string.err index 5af46c2..948d883 100644 --- a/tests/qapi-schema/unclosed-string.err +++ b/tests/qapi-schema/unclosed-string.err @@ -1 +1 @@ -Crashed: <type 'exceptions.Exception'> +<stdin>:1:11: Missing terminating "'"
Signed-off-by: Markus Armbruster <armbru@redhat.com> --- scripts/qapi.py | 29 +++++++++++++++++++++++++++-- tests/qapi-schema/test-qapi.py | 2 ++ tests/qapi-schema/unclosed-string.err | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-)