Example #1
0
    def check_two_call_array(self, param_name, param_elem, match):
        """Check a two-call-idiom command's array output parameter."""
        optional = param_elem.get('optional')
        if optional != 'true':
            self.record_error(
                'Two-call-idiom call array parameter has incorrect "optional" attribute',
                optional, '- expected "true"')

        type_elem = param_elem.find('type')
        assert (type_elem is not None)

        tail = type_elem.tail.strip()
        if '*' not in tail:
            self.record_error('Two-call-idiom call has array parameter',
                              param_name, 'that is not a pointer:',
                              type_elem.text, type_elem.tail)

        length = LengthEntry.parse_len_from_param(param_elem)
        if not length[0].other_param_name:
            self.record_error('Two-call-idiom call has array parameter',
                              param_name,
                              'whose first length is not another parameter:',
                              length[0])

        # Only valid reason to have more than 1 comma-separated entry in len is for strings,
        # which are named "buffer".
        if length is None:
            self.record_error('Two-call-idiom call has array parameter',
                              param_name, 'with no length attribute specified')
        else:
            if len(length) > 2:
                self.record_error(
                    'Two-call-idiom call has array parameter', param_name,
                    'with too many lengths - should be 1 or 2 comma-separated lengths, not',
                    len(length))
            if len(length) == 2:
                if not length[1].null_terminated:
                    self.record_error(
                        'Two-call-idiom call has two-length array parameter',
                        param_name,
                        'whose second length is not "null-terminated":',
                        length[1])

                param_type = getElemType(param_elem)
                if param_type != 'char':
                    self.record_error(
                        'Two-call-idiom call has two-length array parameter',
                        param_name, 'that is not a string:', param_type)

                if param_name != TWO_CALL_STRING_NAME:
                    self.record_error(
                        'Two-call-idiom call has two-length array parameter',
                        param_name, 'that is not named "buffer"')
    def isStructAlwaysValid(self, structname):
        """Try to do check if a structure is always considered valid (i.e. there is no rules to its acceptance)."""
        # A conventions object is required for this call.
        if not self.conventions:
            raise RuntimeError(
                "To use isStructAlwaysValid, be sure your options include a Conventions object."
            )

        if self.conventions.type_always_valid(structname):
            return True

        category = self.getTypeCategory(structname)
        if self.conventions.category_requires_validation(category):
            return False

        info = self.registry.typedict.get(structname)
        if info is None:
            self.logMsg(
                'error',
                f'isStructAlwaysValid({structname}) - structure not found in typedict'
            )

        members = info.getMembers()

        for member in members:
            member_name = getElemName(member)
            if member_name in (self.conventions.structtype_member_name,
                               self.conventions.nextpointer_member_name):
                return False

            if member.get('noautovalidity'):
                return False

            member_type = getElemType(member)

            if member_type in ('void', 'char') or self.paramIsArray(
                    member) or self.paramIsPointer(member):
                return False

            if self.conventions.type_always_valid(member_type):
                continue

            member_category = self.getTypeCategory(member_type)

            if self.conventions.category_requires_validation(member_category):
                return False

            if member_category in ('struct', 'union'):
                if self.isStructAlwaysValid(member_type) is False:
                    return False

        return True
    def check_two_call_capacity_input(self, param_name, param_elem, match):
        """Check a two-call-idiom command's CapacityInput parameter."""
        param_type = getElemType(param_elem)
        if param_type != 'uint32_t':
            self.record_error('Two-call-idiom call has capacity parameter', param_name,
                              'with type', param_type, 'instead of uint32_t')
        optional = param_elem.get('optional')
        if optional != 'true':
            self.record_error('Two-call-idiom call capacity parameter has incorrect "optional" attribute',
                              optional, '- expected "true"')

        prefix = match.group('itemname')
        if prefix.endswith('s'):
            self.record_error('"Item name" part of capacity input parameter name appears to be plural:', prefix)
    def genStruct(self, typeinfo, typeName, alias):
        OutputGenerator.genStruct(self, typeinfo, typeName, alias)

        typeElem = typeinfo.elem

        if alias:
            return

        structTypeName = None
        members = []
        for member in typeinfo.getMembers():
            memberName = getElemName(member)
            memberType = getElemType(member)
            if self.conventions.is_structure_type_member(memberType, memberName):
                structTypeName = member.get("values")

            members.append(memberName)

        self.structs.append(CStruct(typeName, structTypeName, members, typeinfo.elem.get('protect')))
    def check_two_call_count_output(self, param_name, param_elem, match):
        """Check a two-call-idiom command's CountOutput parameter."""
        param_type = getElemType(param_elem)
        if param_type != 'uint32_t':
            self.record_error('Two-call-idiom call has count parameter', param_name,
                              'with type', param_type, 'instead of uint32_t')
        type_elem = param_elem.find('type')
        assert(type_elem is not None)

        tail = type_elem.tail.strip()
        if '*' != tail:
            self.record_error('Two-call-idiom call has count parameter', param_name,
                              'that is not a pointer:', type_elem.text, type_elem.tail)

        optional = param_elem.get('optional')
        if optional is not None:
            self.record_error('Two-call-idiom call count parameter has "optional" attribute, when none should be present:',
                              optional)

        prefix = match.group('itemname')
        if prefix.endswith('s'):
            self.record_error('"Item name" part of count output parameter name appears to be plural:', prefix)
Example #6
0
    def genGroup(self, groupinfo, groupName, alias=None):
        OutputGenerator.genGroup(self, groupinfo, groupName, alias)

        if alias:
            return

        if getElemType(groupinfo.elem) == 'bitmask':
            bitmaskTypeName = getElemName(groupinfo.flagType.elem)

            bitmaskTuples = []
            for elem in groupinfo.elem.findall('enum'):
                (numVal, strVal) = self.enumToValue(elem, True)
                bitmaskTuples.append((getElemName(elem), strVal))

            self.bitmasks.append(CBitmask(bitmaskTypeName, bitmaskTuples))
        else:
            groupElem = groupinfo.elem

            expandName = re.sub(r'([0-9a-z_])([A-Z0-9][^A-Z0-9]?)', r'\1_\2',
                                groupName).upper()
            expandPrefix = expandName

            expandSuffix = ''
            expandSuffixMatch = re.search(r'[A-Z][A-Z]+$', groupName)
            if expandSuffixMatch:
                expandSuffix = '_' + expandSuffixMatch.group()
                # Strip off the suffix from the prefix
                expandPrefix = expandName.rsplit(expandSuffix, 1)[0]

            enumTuples = []
            for elem in groupElem.findall('enum'):
                (numVal, strVal) = self.enumToValue(elem, True)
                if numVal is None:
                    # then this is an alias or something
                    continue
                enumTuples.append((getElemName(elem), strVal))

            self.enums.append(
                CEnum(groupName, expandPrefix, expandSuffix, enumTuples))