コード例 #1
0
    def check_two_call_command(self, name, info, params):
        """Check a two-call-idiom command."""
        named_params = [(getElemName(p), p) for p in params]

        # Find the three important parameters
        capacity_input_param_name = None
        capacity_input_param_match = None
        count_output_param_name = None
        count_output_param_match = None
        array_param_name = None
        for param_name, param_elem in named_params:
            match = CAPACITY_INPUT_RE.match(param_name)
            if match:
                capacity_input_param_name = param_name
                capacity_input_param_match = match
                self.check_two_call_capacity_input(param_name, param_elem, match)
                continue
            match = COUNT_OUTPUT_RE.match(param_name)
            if match:
                count_output_param_name = param_name
                count_output_param_match = match
                self.check_two_call_count_output(param_name, param_elem, match)
                continue

            # Try detecting the output array using its length field
            if capacity_input_param_name:
                length = LengthEntry.parse_len_from_param(param_elem)
                if length and length[0].other_param_name == capacity_input_param_name:
                    array_param_name = param_name

        if not capacity_input_param_name:
            self.record_error('Apparent two-call-idiom call missing a *CapacityInput parameter')

        if not count_output_param_name:
            self.record_error('Apparent two-call-idiom call missing a *CountOutput parameter')

        if not array_param_name:
            self.record_error('Apparent two-call-idiom call missing an array output parameter')

        if not capacity_input_param_name or \
                not count_output_param_name or \
                not array_param_name:
            # If we're missing at least one, stop checking two-call stuff here.
            return

        input_prefix = capacity_input_param_match.group('itemname')
        output_prefix = count_output_param_match.group('itemname')
        if input_prefix != output_prefix:
            self.record_error('Two-call-idiom call has "item name" prefixes for input and output names that mismatch:',
                              input_prefix, output_prefix)

        # If not a "buffer", pluralize the item name for the array name.
        if input_prefix == TWO_CALL_STRING_NAME and output_prefix == TWO_CALL_STRING_NAME:
            expected_array_name = TWO_CALL_STRING_NAME
        else:
            expected_array_name = pluralize(input_prefix)

        if expected_array_name != array_param_name:
            self.record_error('Two-call-idiom call has array parameter with unexpected name: expected',
                              expected_array_name, 'got', array_param_name)
コード例 #2
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"')