Exemplo n.º 1
0
 def check(self, schema, seen):
     if not self.tag_member:  # flat union
         self.tag_member = seen.get(c_name(self._tag_name))
         base = "'base'"
         # Pointing to the base type when not implicit would be
         # nice, but we don't know it here
         if not self.tag_member or self._tag_name != self.tag_member.name:
             raise QAPISemError(
                 self.info, "discriminator '%s' is not a member of %s" %
                 (self._tag_name, base))
         # Here we do:
         base_type = schema.lookup_type(self.tag_member.defined_in)
         assert base_type
         if not base_type.is_implicit():
             base = "base type '%s'" % self.tag_member.defined_in
         if not isinstance(self.tag_member.type, QAPISchemaEnumType):
             raise QAPISemError(
                 self.info,
                 "discriminator member '%s' of %s must be of enum type" %
                 (self._tag_name, base))
         if self.tag_member.optional:
             raise QAPISemError(
                 self.info,
                 "discriminator member '%s' of %s must not be optional" %
                 (self._tag_name, base))
         if self.tag_member.ifcond:
             raise QAPISemError(
                 self.info,
                 "discriminator member '%s' of %s must not be conditional" %
                 (self._tag_name, base))
     else:  # simple union
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         assert not self.tag_member.optional
         assert self.tag_member.ifcond == []
     if self._tag_name:  # flat union
         # branches that are not explicitly covered get an empty type
         cases = set([v.name for v in self.variants])
         for m in self.tag_member.type.members:
             if m.name not in cases:
                 v = QAPISchemaObjectTypeVariant(m.name, self.info,
                                                 'q_empty', m.ifcond)
                 v.set_defined_in(self.tag_member.defined_in)
                 self.variants.append(v)
     if not self.variants:
         raise QAPISemError(self.info, "union has no branches")
     for v in self.variants:
         v.check(schema)
         # Union names must match enum values; alternate names are
         # checked separately. Use 'seen' to tell the two apart.
         if seen:
             if v.name not in self.tag_member.type.member_names():
                 raise QAPISemError(
                     self.info, "branch '%s' is not a value of %s" %
                     (v.name, self.tag_member.type.describe()))
             if (not isinstance(v.type, QAPISchemaObjectType)
                     or v.type.variants):
                 raise QAPISemError(
                     self.info, "%s cannot use %s" %
                     (v.describe(self.info), v.type.describe()))
             v.type.check(schema)
Exemplo n.º 2
0
 def check_clash(self, info, seen):
     cname = c_name(self.name)
     if cname in seen:
         raise QAPISemError(
             info, "%s collides with %s" %
             (self.describe(info), seen[cname].describe(info)))
     seen[cname] = self
Exemplo n.º 3
0
def check_type(value, info, source, allow_array=False, allow_dict=False):
    if value is None:
        return

    # Array type
    if isinstance(value, list):
        if not allow_array:
            raise QAPISemError(info, "%s cannot be an array" % source)
        if len(value) != 1 or not isinstance(value[0], str):
            raise QAPISemError(
                info, "%s: array type must contain single type name" % source)
        return

    # Type name
    if isinstance(value, str):
        return

    # Anonymous type

    if not allow_dict:
        raise QAPISemError(info, "%s should be a type name" % source)

    if not isinstance(value, OrderedDict):
        raise QAPISemError(info,
                           "%s should be an object or type name" % source)

    permit_upper = allow_dict in info.pragma.name_case_whitelist

    # value is a dictionary, check that each member is okay
    for (key, arg) in value.items():
        key_source = "%s member '%s'" % (source, key)
        check_name_str(key,
                       info,
                       key_source,
                       allow_optional=True,
                       permit_upper=permit_upper)
        if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'):
            raise QAPISemError(info, "%s uses reserved name" % key_source)
        check_keys(arg, info, key_source, ['type'], ['if', 'features'])
        check_if(arg, info, key_source)
        check_features(arg.get('features'), info)
        check_type(arg['type'], info, key_source, allow_array=True)
Exemplo n.º 4
0
def check_name_str(name, info, source,
                   allow_optional=False, enum_member=False,
                   permit_upper=False):
    membername = name

    if allow_optional and name.startswith('*'):
        membername = name[1:]
    # 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():
        membername = 'D' + membername
    # Reserve the entire 'q_' namespace for c_name(), and for 'q_empty'
    # and 'q_obj_*' implicit type names.
    if not valid_name.match(membername) or \
       c_name(membername, False).startswith('q_'):
        raise QAPISemError(info, "%s has an invalid name" % source)
    if not permit_upper and name.lower() != name:
        raise QAPISemError(
            info, "%s uses uppercase in name" % source)
    assert not membername.startswith('*')
Exemplo n.º 5
0
 def c_type(self):
     return c_name(self.name) + pointer_suffix
Exemplo n.º 6
0
 def c_name(self):
     return c_name(self.name)
Exemplo n.º 7
0
 def c_unboxed_type(self):
     return c_name(self.name)
Exemplo n.º 8
0
 def c_type(self):
     assert not self.is_implicit()
     return c_name(self.name) + pointer_suffix