mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-25 02:13:06 +00:00
type: move pretty print dereferencing into Type._pretty()
Instead of ProgramObject.__format__().
This commit is contained in:
parent
98a26ad610
commit
56166396ab
@ -14,9 +14,8 @@ import operator
|
||||
from typing import cast, Any, Callable, Iterable, Optional, Tuple, Union
|
||||
|
||||
from drgn.internal.corereader import CoreReader
|
||||
from drgn.internal.util import c_string
|
||||
from drgn.internal.variableindex import VariableIndex
|
||||
from drgn.type import ArrayType, CompoundType, IntType, PointerType, Type
|
||||
from drgn.type import ArrayType, CompoundType, PointerType, Type
|
||||
from drgn.typeindex import TypeIndex
|
||||
from drgn.typename import TypeName
|
||||
|
||||
@ -179,27 +178,8 @@ class ProgramObject:
|
||||
columns = int(format_spec[1:], 10)
|
||||
except ValueError:
|
||||
raise ValueError('Format specifier missing precision') from None
|
||||
string = self.type_._pretty(self.value_(), columns=columns)
|
||||
if (isinstance(self._real_type, PointerType) and
|
||||
isinstance(self._real_type.type, IntType) and
|
||||
self._real_type.type.name.endswith('char')):
|
||||
try:
|
||||
deref_string = c_string(self.string_())
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return f'{string} = {deref_string}'
|
||||
elif isinstance(self._real_type, PointerType):
|
||||
try:
|
||||
deref = self.__getitem__(0)
|
||||
deref_string = deref._real_type._pretty(
|
||||
deref.value_(), cast=False, columns=columns,
|
||||
one_line_columns=columns - len(string) - 4)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return f'*{string} = {deref_string}'
|
||||
return string
|
||||
return self.type_._pretty(self.value_(), columns=columns,
|
||||
reader=self.prog_._reader)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""
|
||||
|
107
drgn/type.py
107
drgn/type.py
@ -192,8 +192,9 @@ class Type:
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
"""
|
||||
Return a representation of the value returned from self._read() in C
|
||||
syntax, optionally with an explicit cast to the name of this type. A
|
||||
@ -225,8 +226,9 @@ class VoidType(Type):
|
||||
def _read(self, reader: CoreReader, address: int) -> Any:
|
||||
raise ValueError("can't read void")
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
raise ValueError("can't format void")
|
||||
|
||||
|
||||
@ -268,8 +270,9 @@ class ArithmeticType(Type):
|
||||
def is_arithmetic(self) -> bool:
|
||||
return True
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
parts = ['(', str(self.type_name()), ')', str(value)]
|
||||
return ''.join(parts)
|
||||
@ -355,8 +358,9 @@ class BoolType(IntType):
|
||||
except TypeError:
|
||||
raise TypeError(f'cannot convert to {self}') from None
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
parts = ['(', str(self.type_name()), ')', str(int(value))]
|
||||
return ''.join(parts)
|
||||
@ -491,8 +495,9 @@ class BitFieldType(Type):
|
||||
value -= (1 << self.bit_size)
|
||||
return value
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
parts = ['(', str(self.type.type_name()), ')', str(value)]
|
||||
return ''.join(parts)
|
||||
@ -589,8 +594,9 @@ class CompoundType(Type):
|
||||
for name, (member_offset, type_thunk) in self._members_by_name.items()
|
||||
])
|
||||
|
||||
def _pretty(self, value: Dict, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if value.keys() != self._members_by_name.keys():
|
||||
raise ValueError('value members do not match type members')
|
||||
if cast and self.name:
|
||||
@ -835,8 +841,9 @@ class EnumType(Type):
|
||||
except ValueError:
|
||||
return value
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
parts = ['(', str(self.type_name()), ')']
|
||||
else:
|
||||
@ -944,20 +951,24 @@ class TypedefType(Type):
|
||||
def _read(self, reader: CoreReader, address: int) -> Any:
|
||||
return self.type._read(reader, address)
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
if one_line_columns is None:
|
||||
one_line_columns = columns
|
||||
cast_str = str(self.type_name())
|
||||
pretty = self.type._pretty(
|
||||
value, cast=False, columns=columns,
|
||||
one_line_columns=one_line_columns - len(cast_str) - 2)
|
||||
one_line_columns=one_line_columns - len(cast_str) - 2,
|
||||
reader=reader,
|
||||
)
|
||||
parts = ['(', cast_str, ')', pretty]
|
||||
return ''.join(parts)
|
||||
else:
|
||||
return self.type._pretty(value, cast=False, columns=columns,
|
||||
one_line_columns=one_line_columns)
|
||||
one_line_columns=one_line_columns,
|
||||
reader=reader)
|
||||
|
||||
def _convert(self, value: Any) -> Any:
|
||||
return self.type._convert(value)
|
||||
@ -1011,13 +1022,37 @@ class PointerType(Type):
|
||||
def is_pointer_operand(self) -> bool:
|
||||
return True
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if cast:
|
||||
parts = ['(', str(self.type_name()), ')', hex(value)]
|
||||
return ''.join(parts)
|
||||
else:
|
||||
return hex(value)
|
||||
parts = [hex(value)]
|
||||
if reader is not None:
|
||||
if (isinstance(self.type, IntType) and
|
||||
self.type.name.endswith('char')):
|
||||
try:
|
||||
deref_string = c_string(reader.read_c_string(value))
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
parts.append(' = ')
|
||||
parts.append(deref_string)
|
||||
else:
|
||||
try:
|
||||
deref_string = self.type._pretty(
|
||||
self.type._read(reader, value), cast=False,
|
||||
columns=columns,
|
||||
one_line_columns=columns - sum(len(part) for part in parts) - 4,
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
parts.insert(0, '*')
|
||||
parts.append(' = ')
|
||||
parts.append(deref_string)
|
||||
return ''.join(parts)
|
||||
|
||||
def _convert(self, value: Any) -> int:
|
||||
try:
|
||||
@ -1067,15 +1102,6 @@ class ArrayType(Type):
|
||||
raise ValueError("can't get size of incomplete array type")
|
||||
return self.size * self.type.sizeof()
|
||||
|
||||
def _read(self, reader: CoreReader, address: int) -> List:
|
||||
if not self.size:
|
||||
return []
|
||||
element_size = self.type.sizeof()
|
||||
return [
|
||||
self.type._read(reader, address + i * element_size)
|
||||
for i in range(self.size)
|
||||
]
|
||||
|
||||
def unqualified(self) -> 'ArrayType':
|
||||
return self
|
||||
|
||||
@ -1085,6 +1111,15 @@ class ArrayType(Type):
|
||||
def is_pointer_operand(self) -> bool:
|
||||
return True
|
||||
|
||||
def _read(self, reader: CoreReader, address: int) -> List:
|
||||
if not self.size:
|
||||
return []
|
||||
element_size = self.type.sizeof()
|
||||
return [
|
||||
self.type._read(reader, address + i * element_size)
|
||||
for i in range(self.size)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _is_zero_element(element: Any) -> bool:
|
||||
if isinstance(element, list):
|
||||
@ -1094,8 +1129,9 @@ class ArrayType(Type):
|
||||
else:
|
||||
return not element
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
if one_line_columns is None:
|
||||
one_line_columns = columns
|
||||
if (self.size or 0) != len(value):
|
||||
@ -1242,6 +1278,7 @@ class FunctionType(Type):
|
||||
def _read(self, reader: CoreReader, address: int) -> Dict:
|
||||
raise ValueError("can't read function")
|
||||
|
||||
def _pretty(self, value: Any, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None) -> str:
|
||||
def _pretty(self, value: Any, *, cast: bool = True, columns: int = 0,
|
||||
one_line_columns: Optional[int] = None,
|
||||
reader: Optional[CoreReader] = None) -> str:
|
||||
raise ValueError("can't format function")
|
||||
|
Loading…
Reference in New Issue
Block a user