Exemple #1
0
    def caller(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
        """
        This method will dispatch to the appropriate instance function
        based on the type of the input we receive.
        """

        out_type = None
        if self.output_type is not None:
            out_type = target.get_type(self.output_type)
        baked = dict()
        for (_, method) in inspect.getmembers(self, inspect.ismethod):
            if not hasattr(method, "input_typename_handled"):
                continue
            baked[type_canonicalize_name(
                method.input_typename_handled)] = method

        if self.isfirst:
            assert not objs
            yield from self.no_input()
            return

        for i in objs:
            obj_type_name = type_canonical_name(i.type_)

            # try subclass-specified input types first, so that they can
            # override any other behavior
            if obj_type_name in baked:
                yield from baked[obj_type_name](i)
                continue

            # try passthrough of output type
            # note, this may also be handled by subclass-specified input types
            if obj_type_name == type_canonical_name(out_type):
                yield i
                continue

            # try walkers
            if out_type is not None:
                try:
                    # pylint: disable=protected-access
                    for obj in Walk()._call([i]):
                        yield drgn.cast(out_type, obj)
                    continue
                except CommandError:
                    pass

            # error
            raise CommandError(
                self.name, 'no handler for input of type {}'.format(i.type_))
Exemple #2
0
 def check_input_type(self,
                      objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
     """
     This function acts as a generator, checking that each passed object
     matches the input type for the command
     """
     assert self.input_type is not None
     type_name = type_canonicalize_name(self.input_type)
     for obj in objs:
         if type_canonical_name(obj.type_) != type_name:
             raise CommandError(
                 self.name,
                 f'expected input of type {self.input_type}, but received '
                 f'type {obj.type_}')
         yield obj
Exemple #3
0
    def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
        """
        This function will call walk() on each input object, verifying
        the types as we go.
        """
        assert self.input_type is not None
        expected_type = type_canonicalize_name(self.input_type)
        for obj in objs:
            if type_canonical_name(obj.type_) != expected_type:
                raise CommandError(
                    self.name,
                    'expected input of type {}, but received {}'.format(
                        expected_type, type_canonical_name(obj.type_)))

            yield from self.walk(obj)
Exemple #4
0
    def _call(  # type: ignore[return]
            self,
            objs: Iterable[drgn.Object]) -> Optional[Iterable[drgn.Object]]:
        """
        This function will call pretty_print() on each input object,
        verifying the types as we go.
        """

        assert self.input_type is not None
        type_name = type_canonicalize_name(self.input_type)
        for obj in objs:
            if type_canonical_name(obj.type_) != type_name:
                raise CommandError(
                    self.name,
                    f'exepected input of type {self.input_type}, but received '
                    f'type {obj.type_}')

            self.pretty_print([obj])
Exemple #5
0
    def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
        baked = {
            type_canonicalize_name(type_): class_
            for type_, class_ in Walker.allWalkers.items()
        }
        has_input = False
        for i in objs:
            has_input = True
            this_type_name = type_canonical_name(i.type_)
            if this_type_name not in baked:
                raise CommandError(self.name, Walk._help_message(i.type_))

            yield from baked[this_type_name]().walk(i)

        # If we got no input and we're the last thing in the pipeline, we're
        # probably the first thing in the pipeline. Print out the available
        # walkers.
        if not has_input and self.islast:
            print(Walk._help_message())