Marc-André Lureau <marcandre.lur...@redhat.com> writes: > Use a base class QAPIError, and QAPIParseError for parser errors and > QAPISemError for semantic errors, suggested by Markus Armbruster. > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > scripts/qapi.py | 338 > ++++++++++++++++++++++++++------------------------------ > 1 file changed, 158 insertions(+), 180 deletions(-) > > diff --git a/scripts/qapi.py b/scripts/qapi.py > index 21bc32fda3..5885c9e4ad 100644 > --- a/scripts/qapi.py > +++ b/scripts/qapi.py > @@ -91,35 +91,38 @@ def error_path(parent): > return res > > > -class QAPISchemaError(Exception): > - def __init__(self, schema, msg): > +class QAPIError(Exception): > + def __init__(self, fname, line, col, incl_info, msg): > Exception.__init__(self) > - self.fname = schema.fname > + self.fname = fname > + self.line = line > + self.col = col > + self.info = incl_info > self.msg = msg > - self.col = 1 > - self.line = schema.line > - for ch in schema.src[schema.line_pos:schema.pos]: > - if ch == '\t': > - self.col = (self.col + 7) % 8 + 1 > - else: > - self.col += 1 > - self.info = schema.incl_info > > def __str__(self): > - return error_path(self.info) + \ > - "%s:%d:%d: %s" % (self.fname, self.line, self.col, self.msg) > + loc = "%s:%d" % (self.fname, self.line) > + if self.col is not None: > + loc += ":%s" % self.col > + return error_path(self.info) + "%s: %s" % (loc, self.msg) > > > -class QAPIExprError(Exception): > - def __init__(self, expr_info, msg): > - Exception.__init__(self) > - assert expr_info > - self.info = expr_info > - self.msg = msg > +class QAPIParseError(QAPIError): > + def __init__(self, parser, msg): > + col = 1 > + for ch in parser.src[parser.line_pos:parser.pos]: > + if ch == '\t': > + col = (col + 7) % 8 + 1 > + else: > + col += 1 > + QAPIError.__init__(self, parser.fname, parser.line, > + col, parser.incl_info, msg)
Let's break the line after col, so that line and columns stay together. Could be done on commit. > > - def __str__(self): > - return error_path(self.info['parent']) + \ > - "%s:%d: %s" % (self.info['file'], self.info['line'], self.msg) > + > +class QAPISemError(QAPIError): > + def __init__(self, info, msg): > + QAPIError.__init__(self, info['file'], info['line'], None, > + info['parent'], msg) > > > class QAPISchemaParser(object): > @@ -140,25 +143,24 @@ class QAPISchemaParser(object): > self.accept() > > while self.tok is not None: > - expr_info = {'file': fname, 'line': self.line, > - 'parent': self.incl_info} > + info = {'file': fname, 'line': self.line, > + 'parent': self.incl_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") > + raise QAPISemError(info, "Invalid 'include' directive") > include = expr["include"] > if not isinstance(include, str): > - raise QAPIExprError(expr_info, > - "Value of 'include' must be a > string") > + raise QAPISemError(info, > + "Value of 'include' must be a string") > incl_abs_fname = os.path.join(os.path.dirname(abs_fname), > include) > # catch inclusion cycle > - inf = expr_info > + inf = info > while inf: > if incl_abs_fname == os.path.abspath(inf['file']): > - raise QAPIExprError(expr_info, "Inclusion loop for > %s" > - % include) > + raise QAPISemError(info, "Inclusion loop for %s" > + % include) > inf = inf['parent'] > # skip multiple include of the same file > if incl_abs_fname in previously_included: > @@ -166,14 +168,13 @@ class QAPISchemaParser(object): > try: > fobj = open(incl_abs_fname, 'r') > except IOError as e: > - raise QAPIExprError(expr_info, > - '%s: %s' % (e.strerror, include)) > + raise QAPISemError(info, '%s: %s' % (e.strerror, > include)) > exprs_include = QAPISchemaParser(fobj, previously_included, > - expr_info) > + info) > self.exprs.extend(exprs_include.exprs) > else: > expr_elem = {'expr': expr, > - 'info': expr_info} > + 'info': info} > self.exprs.append(expr_elem) > > def accept(self): > @@ -194,8 +195,7 @@ class QAPISchemaParser(object): > ch = self.src[self.cursor] > self.cursor += 1 > if ch == '\n': > - raise QAPISchemaError(self, > - 'Missing terminating "\'"') > + raise QAPIParseError(self, 'Missing terminating > "\'"') > if esc: > if ch == 'b': > string += '\b' > @@ -213,25 +213,25 @@ class QAPISchemaParser(object): > ch = self.src[self.cursor] > self.cursor += 1 > if ch not in "0123456789abcdefABCDEF": > - raise QAPISchemaError(self, > - '\\u escape needs > 4 ' > - 'hex digits') > + raise QAPIParseError(self, > + '\\u escape needs 4 > ' > + 'hex digits') > value = (value << 4) + int(ch, 16) > # If Python 2 and 3 didn't disagree so much on > # how to handle Unicode, then we could allow > # Unicode string defaults. But most of QAPI is > # ASCII-only, so we aren't losing much for now. > if not value or value > 0x7f: > - raise QAPISchemaError(self, > - 'For now, \\u escape ' > - 'only supports > non-zero ' > - 'values up to \\u007f') > + raise QAPIParseError(self, > + 'For now, \\u escape ' > + 'only supports non-zero > ' > + 'values up to \\u007f') > string += chr(value) > elif ch in "\\/'\"": > string += ch > else: > - raise QAPISchemaError(self, > - "Unknown escape \\%s" % ch) > + raise QAPIParseError(self, > + "Unknown escape \\%s" % ch) > esc = False > elif ch == "\\": > esc = True > @@ -259,7 +259,7 @@ class QAPISchemaParser(object): > self.line += 1 > self.line_pos = self.cursor > elif not self.tok.isspace(): > - raise QAPISchemaError(self, 'Stray "%s"' % self.tok) > + raise QAPIParseError(self, 'Stray "%s"' % self.tok) > > def get_members(self): > expr = OrderedDict() > @@ -267,24 +267,24 @@ class QAPISchemaParser(object): > self.accept() > return expr > if self.tok != "'": > - raise QAPISchemaError(self, 'Expected string or "}"') > + raise QAPIParseError(self, 'Expected string or "}"') > while True: > key = self.val > self.accept() > if self.tok != ':': > - raise QAPISchemaError(self, 'Expected ":"') > + raise QAPIParseError(self, 'Expected ":"') > self.accept() > if key in expr: > - raise QAPISchemaError(self, 'Duplicate key "%s"' % key) > + raise QAPIParseError(self, 'Duplicate key "%s"' % key) > expr[key] = self.get_expr(True) > if self.tok == '}': > self.accept() > return expr > if self.tok != ',': > - raise QAPISchemaError(self, 'Expected "," or "}"') > + raise QAPIParseError(self, 'Expected "," or "}"') > self.accept() > if self.tok != "'": > - raise QAPISchemaError(self, 'Expected string') > + raise QAPIParseError(self, 'Expected string') > > def get_values(self): > expr = [] > @@ -292,20 +292,20 @@ class QAPISchemaParser(object): > self.accept() > return expr > if self.tok not in "{['tfn": > - raise QAPISchemaError(self, 'Expected "{", "[", "]", string, ' > - 'boolean or "null"') > + raise QAPIParseError(self, 'Expected "{", "[", "]", string, ' > + 'boolean or "null"') > while True: > expr.append(self.get_expr(True)) > if self.tok == ']': > self.accept() > return expr > if self.tok != ',': > - raise QAPISchemaError(self, 'Expected "," or "]"') > + raise QAPIParseError(self, 'Expected "," or "]"') > self.accept() > > def get_expr(self, nested): > if self.tok != '{' and not nested: > - raise QAPISchemaError(self, 'Expected "{"') > + raise QAPIParseError(self, 'Expected "{"') > if self.tok == '{': > self.accept() > expr = self.get_members() > @@ -316,7 +316,7 @@ class QAPISchemaParser(object): > expr = self.val > self.accept() > else: > - raise QAPISchemaError(self, 'Expected "{", "[" or string') > + raise QAPIParseError(self, 'Expected "{", "[" or string') > return expr > > # > @@ -375,20 +375,18 @@ valid_name = re.compile('^(__[a-zA-Z0-9.-]+_)?' > '[a-zA-Z][a-zA-Z0-9_-]*$') > > > -def check_name(expr_info, source, name, allow_optional=False, > +def check_name(info, source, name, allow_optional=False, > enum_member=False): > global valid_name > membername = name > > if not isinstance(name, str): > - raise QAPIExprError(expr_info, > - "%s requires a string name" % source) > + raise QAPISemError(info, "%s requires a string name" % source) > if name.startswith('*'): > membername = name[1:] > if not allow_optional: > - raise QAPIExprError(expr_info, > - "%s does not allow optional name '%s'" > - % (source, name)) > + raise QAPISemError(info, "%s does not allow optional name '%s'" > + % (source, name)) > # Enum members can start with a digit, because the generated C > # code always prefixes it with the enum name > if enum_member and membername[0].isdigit(): > @@ -397,8 +395,7 @@ def check_name(expr_info, source, name, > allow_optional=False, > # and 'q_obj_*' implicit type names. > if not valid_name.match(membername) or \ > c_name(membername, False).startswith('q_'): > - raise QAPIExprError(expr_info, > - "%s uses invalid name '%s'" % (source, name)) > + raise QAPISemError(info, "%s uses invalid name '%s'" % (source, > name)) > > > def add_name(name, info, meta, implicit=False): > @@ -407,13 +404,11 @@ def add_name(name, info, meta, implicit=False): > # FIXME should reject names that differ only in '_' vs. '.' > # vs. '-', because they're liable to clash in generated C. > if name in all_names: > - raise QAPIExprError(info, > - "%s '%s' is already defined" > - % (all_names[name], name)) > + raise QAPISemError(info, "%s '%s' is already defined" > + % (all_names[name], name)) > if not implicit and (name.endswith('Kind') or name.endswith('List')): > - raise QAPIExprError(info, > - "%s '%s' should not end in '%s'" > - % (meta, name, name[-4:])) > + raise QAPISemError(info, "%s '%s' should not end in '%s'" > + % (meta, name, name[-4:])) > all_names[name] = meta > > > @@ -465,7 +460,7 @@ def is_enum(name): > return find_enum(name) is not None > > > -def check_type(expr_info, source, value, allow_array=False, > +def check_type(info, source, value, allow_array=False, > allow_dict=False, allow_optional=False, > allow_metas=[]): > global all_names > @@ -476,69 +471,64 @@ def check_type(expr_info, source, value, > allow_array=False, > # Check if array type for value is okay > if isinstance(value, list): > if not allow_array: > - raise QAPIExprError(expr_info, > - "%s cannot be an array" % source) > + raise QAPISemError(info, "%s cannot be an array" % source) > if len(value) != 1 or not isinstance(value[0], str): > - raise QAPIExprError(expr_info, > - "%s: array type must contain single type > name" > - % source) > + raise QAPISemError(info, > + "%s: array type must contain single type > name" % > + source) > value = value[0] > > # Check if type name for value is okay > if isinstance(value, str): > if value not in all_names: > - raise QAPIExprError(expr_info, > - "%s uses unknown type '%s'" > - % (source, value)) > + raise QAPISemError(info, "%s uses unknown type '%s'" > + % (source, value)) > if not all_names[value] in allow_metas: > - raise QAPIExprError(expr_info, > - "%s cannot use %s type '%s'" > - % (source, all_names[value], value)) > + raise QAPISemError(info, "%s cannot use %s type '%s'" % > + (source, all_names[value], value)) > return > > if not allow_dict: > - raise QAPIExprError(expr_info, > - "%s should be a type name" % source) > + raise QAPISemError(info, "%s should be a type name" % source) > > if not isinstance(value, OrderedDict): > - raise QAPIExprError(expr_info, > - "%s should be a dictionary or type name" % > source) > + raise QAPISemError(info, > + "%s should be a dictionary or type name" % source) > > # value is a dictionary, check that each member is okay > for (key, arg) in value.items(): > - check_name(expr_info, "Member of %s" % source, key, > + check_name(info, "Member of %s" % source, key, > allow_optional=allow_optional) > if c_name(key, False) == 'u' or c_name(key, > False).startswith('has_'): > - raise QAPIExprError(expr_info, > - "Member of %s uses reserved name '%s'" > - % (source, key)) > + raise QAPISemError(info, "Member of %s uses reserved name '%s'" > + % (source, key)) > # Todo: allow dictionaries to represent default values of > # an optional argument. > - check_type(expr_info, "Member '%s' of %s" % (key, source), arg, > + check_type(info, "Member '%s' of %s" % (key, source), arg, > allow_array=True, > allow_metas=['built-in', 'union', 'alternate', 'struct', > 'enum']) > > > -def check_command(expr, expr_info): > +def check_command(expr, info): > name = expr['command'] > boxed = expr.get('boxed', False) > > args_meta = ['struct'] > if boxed: > args_meta += ['union', 'alternate'] > - check_type(expr_info, "'data' for command '%s'" % name, > + check_type(info, "'data' for command '%s'" % name, > expr.get('data'), allow_dict=not boxed, allow_optional=True, > allow_metas=args_meta) > returns_meta = ['union', 'struct'] > if name in returns_whitelist: > returns_meta += ['built-in', 'alternate', 'enum'] > - check_type(expr_info, "'returns' for command '%s'" % name, > + check_type(info, "'returns' for command '%s'" % name, > expr.get('returns'), allow_array=True, > allow_optional=True, allow_metas=returns_meta) > > > -def check_event(expr, expr_info): > +def check_event(expr, info): > global events > name = expr['event'] > boxed = expr.get('boxed', False) > @@ -547,12 +537,12 @@ def check_event(expr, expr_info): > if boxed: > meta += ['union', 'alternate'] > events.append(name) > - check_type(expr_info, "'data' for event '%s'" % name, > + check_type(info, "'data' for event '%s'" % name, > expr.get('data'), allow_dict=not boxed, allow_optional=True, > allow_metas=meta) > > > -def check_union(expr, expr_info): > +def check_union(expr, info): > name = expr['union'] > base = expr.get('base') > discriminator = expr.get('discriminator') > @@ -565,123 +555,117 @@ def check_union(expr, expr_info): > enum_define = None > allow_metas = ['built-in', 'union', 'alternate', 'struct', 'enum'] > if base is not None: > - raise QAPIExprError(expr_info, > - "Simple union '%s' must not have a base" > - % name) > + raise QAPISemError(info, "Simple union '%s' must not have a > base" % > + name) > > # Else, it's a flat union. > else: > # The object must have a string or dictionary 'base'. > - check_type(expr_info, "'base' for union '%s'" % name, > + check_type(info, "'base' for union '%s'" % name, > base, allow_dict=True, allow_optional=True, > allow_metas=['struct']) > if not base: > - raise QAPIExprError(expr_info, > - "Flat union '%s' must have a base" > - % name) > + raise QAPISemError(info, "Flat union '%s' must have a base" > + % name) > base_members = find_base_members(base) > assert base_members > > # The value of member 'discriminator' must name a non-optional > # member of the base struct. > - check_name(expr_info, "Discriminator of flat union '%s'" % name, > + check_name(info, "Discriminator of flat union '%s'" % name, > discriminator) > discriminator_type = base_members.get(discriminator) > if not discriminator_type: > - raise QAPIExprError(expr_info, > - "Discriminator '%s' is not a member of base " > - "struct '%s'" > - % (discriminator, base)) > + raise QAPISemError(info, > + "Discriminator '%s' is not a member of base " > + "struct '%s'" > + % (discriminator, base)) > enum_define = find_enum(discriminator_type) > allow_metas = ['struct'] > # Do not allow string discriminator > if not enum_define: > - raise QAPIExprError(expr_info, > - "Discriminator '%s' must be of enumeration " > - "type" % discriminator) > + raise QAPISemError(info, > + "Discriminator '%s' must be of enumeration " > + "type" % discriminator) > > # Check every branch; don't allow an empty union > if len(members) == 0: > - raise QAPIExprError(expr_info, > - "Union '%s' cannot have empty 'data'" % name) > + raise QAPISemError(info, "Union '%s' cannot have empty 'data'" % > name) > for (key, value) in members.items(): > - check_name(expr_info, "Member of union '%s'" % name, key) > + check_name(info, "Member of union '%s'" % name, key) > > # Each value must name a known type > - check_type(expr_info, "Member '%s' of union '%s'" % (key, name), > + check_type(info, "Member '%s' of union '%s'" % (key, name), > value, allow_array=not base, allow_metas=allow_metas) > > # If the discriminator names an enum type, then all members > # of 'data' must also be members of the enum type. > if enum_define: > if key not in enum_define['enum_values']: > - raise QAPIExprError(expr_info, > - "Discriminator value '%s' is not found > in " > - "enum '%s'" % > - (key, enum_define["enum_name"])) > + raise QAPISemError(info, > + "Discriminator value '%s' is not found in > " > + "enum '%s'" > + % (key, enum_define["enum_name"])) > > # If discriminator is user-defined, ensure all values are covered > if enum_define: > for value in enum_define['enum_values']: > if value not in members.keys(): > - raise QAPIExprError(expr_info, > - "Union '%s' data missing '%s' branch" > - % (name, value)) > + raise QAPISemError(info, "Union '%s' data missing '%s' > branch" > + % (name, value)) > > > -def check_alternate(expr, expr_info): > +def check_alternate(expr, info): > name = expr['alternate'] > members = expr['data'] > types_seen = {} > > # Check every branch; require at least two branches > if len(members) < 2: > - raise QAPIExprError(expr_info, > - "Alternate '%s' should have at least two > branches " > - "in 'data'" % name) > + raise QAPISemError(info, > + "Alternate '%s' should have at least two branches > " > + "in 'data'" % name) > for (key, value) in members.items(): > - check_name(expr_info, "Member of alternate '%s'" % name, key) > + check_name(info, "Member of alternate '%s'" % name, key) > > # Ensure alternates have no type conflicts. > - check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name), > + check_type(info, "Member '%s' of alternate '%s'" % (key, name), > value, > allow_metas=['built-in', 'union', 'struct', 'enum']) > qtype = find_alternate_member_qtype(value) > if not qtype: > - raise QAPIExprError(expr_info, > - "Alternate '%s' member '%s' cannot use " > - "type '%s'" % (name, key, value)) > + raise QAPISemError(info, "Alternate '%s' member '%s' cannot use " > + "type '%s'" % (name, key, value)) > if qtype in types_seen: > - raise QAPIExprError(expr_info, > - "Alternate '%s' member '%s' can't " > - "be distinguished from member '%s'" > - % (name, key, types_seen[qtype])) > + raise QAPISemError(info, "Alternate '%s' member '%s' can't " > + "be distinguished from member '%s'" > + % (name, key, types_seen[qtype])) > types_seen[qtype] = key > > > -def check_enum(expr, expr_info): > +def check_enum(expr, info): > name = expr['enum'] > members = expr.get('data') > prefix = expr.get('prefix') > > if not isinstance(members, list): > - raise QAPIExprError(expr_info, > - "Enum '%s' requires an array for 'data'" % name) > + raise QAPISemError(info, > + "Enum '%s' requires an array for 'data'" % name) > if prefix is not None and not isinstance(prefix, str): > - raise QAPIExprError(expr_info, > - "Enum '%s' requires a string for 'prefix'" % > name) > + raise QAPISemError(info, > + "Enum '%s' requires a string for 'prefix'" % name) > for member in members: > - check_name(expr_info, "Member of enum '%s'" % name, member, > + check_name(info, "Member of enum '%s'" % name, member, > enum_member=True) > > > -def check_struct(expr, expr_info): > +def check_struct(expr, info): > name = expr['struct'] > members = expr['data'] > > - check_type(expr_info, "'data' for struct '%s'" % name, members, > + check_type(info, "'data' for struct '%s'" % name, members, > allow_dict=True, allow_optional=True) > - check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'), > + check_type(info, "'base' for struct '%s'" % name, expr.get('base'), > allow_metas=['struct']) > > > @@ -690,27 +674,24 @@ def check_keys(expr_elem, meta, required, optional=[]): > info = expr_elem['info'] > name = expr[meta] > if not isinstance(name, str): > - raise QAPIExprError(info, > - "'%s' key must have a string value" % meta) > + raise QAPISemError(info, "'%s' key must have a string value" % meta) > required = required + [meta] > for (key, value) in expr.items(): > if key not in required and key not in optional: > - raise QAPIExprError(info, > - "Unknown key '%s' in %s '%s'" > - % (key, meta, name)) > + raise QAPISemError(info, "Unknown key '%s' in %s '%s'" > + % (key, meta, name)) > if (key == 'gen' or key == 'success-response') and value is not > False: > - raise QAPIExprError(info, > - "'%s' of %s '%s' should only use false value" > - % (key, meta, name)) > + raise QAPISemError(info, > + "'%s' of %s '%s' should only use false value" > + % (key, meta, name)) > if key == 'boxed' and value is not True: > - raise QAPIExprError(info, > - "'%s' of %s '%s' should only use true value" > - % (key, meta, name)) > + raise QAPISemError(info, > + "'%s' of %s '%s' should only use true value" > + % (key, meta, name)) > for key in required: > if key not in expr: > - raise QAPIExprError(info, > - "Key '%s' is missing from %s '%s'" > - % (key, meta, name)) > + raise QAPISemError(info, "Key '%s' is missing from %s '%s'" > + % (key, meta, name)) > > > def check_exprs(exprs): > @@ -743,8 +724,8 @@ def check_exprs(exprs): > check_keys(expr_elem, 'event', [], ['data', 'boxed']) > add_name(expr['event'], info, 'event') > else: > - raise QAPIExprError(expr_elem['info'], > - "Expression is missing metatype") > + raise QAPISemError(expr_elem['info'], > + "Expression is missing metatype") > > # Try again for hidden UnionKind enum > for expr_elem in exprs: > @@ -978,8 +959,8 @@ class QAPISchemaObjectType(QAPISchemaType): > > def check(self, schema): > if self.members is False: # check for cycles > - raise QAPIExprError(self.info, > - "Object %s contains itself" % self.name) > + raise QAPISemError(self.info, > + "Object %s contains itself" % self.name) > if self.members: > return > self.members = False # mark as being checked > @@ -1051,12 +1032,11 @@ class QAPISchemaMember(object): > def check_clash(self, info, seen): > cname = c_name(self.name) > if cname.lower() != cname and self.owner not in case_whitelist: > - raise QAPIExprError(info, > - "%s should not use uppercase" % > self.describe()) > + raise QAPISemError(info, > + "%s should not use uppercase" % > self.describe()) > if cname in seen: > - raise QAPIExprError(info, > - "%s collides with %s" > - % (self.describe(), seen[cname].describe())) > + raise QAPISemError(info, "%s collides with %s" % > + (self.describe(), seen[cname].describe())) > seen[cname] = self > > def _pretty_owner(self): > @@ -1201,14 +1181,13 @@ class QAPISchemaCommand(QAPISchemaEntity): > self.arg_type.check(schema) > if self.boxed: > if self.arg_type.is_empty(): > - raise QAPIExprError(self.info, > - "Cannot use 'boxed' with empty type") > + raise QAPISemError(self.info, > + "Cannot use 'boxed' with empty type") > else: > assert not isinstance(self.arg_type, QAPISchemaAlternateType) > assert not self.arg_type.variants > elif self.boxed: > - raise QAPIExprError(self.info, > - "Use of 'boxed' requires 'data'") > + raise QAPISemError(self.info, "Use of 'boxed' requires 'data'") > if self._ret_type_name: > self.ret_type = schema.lookup_type(self._ret_type_name) > assert isinstance(self.ret_type, QAPISchemaType) > @@ -1235,14 +1214,13 @@ class QAPISchemaEvent(QAPISchemaEntity): > self.arg_type.check(schema) > if self.boxed: > if self.arg_type.is_empty(): > - raise QAPIExprError(self.info, > - "Cannot use 'boxed' with empty type") > + raise QAPISemError(self.info, > + "Cannot use 'boxed' with empty type") > else: > assert not isinstance(self.arg_type, QAPISchemaAlternateType) > assert not self.arg_type.variants > elif self.boxed: > - raise QAPIExprError(self.info, > - "Use of 'boxed' requires 'data'") > + raise QAPISemError(self.info, "Use of 'boxed' requires 'data'") > > def visit(self, visitor): > visitor.visit_event(self.name, self.info, self.arg_type, self.boxed) > @@ -1258,7 +1236,7 @@ class QAPISchema(object): > self._predefining = False > self._def_exprs() > self.check() > - except (QAPISchemaError, QAPIExprError) as err: > + except QAPIError as err: > print >>sys.stderr, err > exit(1) > > @@ -1557,8 +1535,8 @@ def c_name(name, protect=True): > # namespace pollution: > polluted_words = set(['unix', 'errno', 'mips', 'sparc']) > name = name.translate(c_name_trans) > - if protect and (name in c89_words | c99_words | c11_words | gcc_words > - | cpp_words | polluted_words): > + if protect and (name in c89_words | c99_words | c11_words | gcc_words | > + cpp_words | polluted_words): > return "q_" + name > return name Spurious hunk. Could drop on commit. The change is mostly mechanical. Would be easier to review if the rename from expr_info to info was a separate patch, but I guess it's not worth splitting off now. I'm not sure the rename is an improvement, but backing it out seems not worth it now, either. With the two touch-ups: Reviewed-by: Markus Armbruster <arm...@redhat.com>