mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 19:53:22 +08:00
[0.2.x] added : typedVarList can get nested field name ( "field.next" ) ( once again )
git-svn-id: https://pykd.svn.codeplex.com/svn@82565 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
386c120795
commit
0c6d91692d
@ -586,7 +586,7 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
|
|||||||
|
|
||||||
ULONG64 entryAddress = 0;
|
ULONG64 entryAddress = 0;
|
||||||
|
|
||||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
TypeInfoPtr fieldTypeInfo = typeInfo->getFieldRecursive( listEntryName );
|
||||||
|
|
||||||
ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord;
|
ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord;
|
||||||
|
|
||||||
|
@ -623,6 +623,53 @@ TypeInfoPtr TypeInfo::arrayOf( ULONG count )
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG UdtTypeInfoBase::getFieldOffsetByNameRecursive( const std::string &fieldName )
|
||||||
|
{
|
||||||
|
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
|
||||||
|
typedef boost::char_separator<char> CharSep;
|
||||||
|
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
|
||||||
|
if (tokenizer.begin() == tokenizer.end())
|
||||||
|
throw TypeException( getName(), fieldName + ": invalid field name");
|
||||||
|
|
||||||
|
ULONG fieldOffset = 0;
|
||||||
|
|
||||||
|
TypeInfoPtr typeInfo = shared_from_this();
|
||||||
|
|
||||||
|
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
|
||||||
|
for (; it != tokenizer.end(); ++it)
|
||||||
|
{
|
||||||
|
const std::string &name = *it;
|
||||||
|
fieldOffset += typeInfo->getFieldOffsetByNameNotRecursively(name);
|
||||||
|
typeInfo = typeInfo->getField(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypeInfoPtr UdtTypeInfoBase::getFieldRecursive(const std::string &fieldName )
|
||||||
|
{
|
||||||
|
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
|
||||||
|
typedef boost::char_separator<char> CharSep;
|
||||||
|
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
|
||||||
|
if (tokenizer.begin() == tokenizer.end())
|
||||||
|
throw TypeException( getName(), fieldName + ": invalid field name");
|
||||||
|
|
||||||
|
TypeInfoPtr typeInfo = shared_from_this();
|
||||||
|
|
||||||
|
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
|
||||||
|
for (; it != tokenizer.end(); ++it)
|
||||||
|
{
|
||||||
|
const std::string &name = *it;
|
||||||
|
typeInfo = typeInfo->getField(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string UdtTypeInfoBase::print()
|
std::string UdtTypeInfoBase::print()
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
|
@ -74,6 +74,10 @@ public:
|
|||||||
throw TypeException( getName(), "type is not a struct" );
|
throw TypeException( getName(), "type is not a struct" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual TypeInfoPtr getFieldRecursive(const std::string &fieldName ) {
|
||||||
|
throw TypeException( getName(), "type is not a struct" );
|
||||||
|
}
|
||||||
|
|
||||||
virtual TypeInfoPtr getFieldByIndex( ULONG index ) {
|
virtual TypeInfoPtr getFieldByIndex( ULONG index ) {
|
||||||
throw TypeException( getName(), "type is not a struct" );
|
throw TypeException( getName(), "type is not a struct" );
|
||||||
}
|
}
|
||||||
@ -85,6 +89,7 @@ public:
|
|||||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
||||||
throw TypeException( getName(), "type is not a struct" );
|
throw TypeException( getName(), "type is not a struct" );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||||
throw TypeException( getName(), "type is not a struct" );
|
throw TypeException( getName(), "type is not a struct" );
|
||||||
}
|
}
|
||||||
@ -333,9 +338,9 @@ protected:
|
|||||||
return lookupField(index)->getName();
|
return lookupField(index)->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName );
|
||||||
return getFieldOffsetRecursive( shared_from_this(), fieldName );
|
|
||||||
}
|
virtual TypeInfoPtr getFieldRecursive(const std::string &fieldName );
|
||||||
|
|
||||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||||
return lookupField(fieldName)->getOffset();
|
return lookupField(fieldName)->getOffset();
|
||||||
|
@ -61,29 +61,6 @@ UdtFieldPtr &FieldCollection::lookup(const std::string &name)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName)
|
|
||||||
{
|
|
||||||
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
|
|
||||||
typedef boost::char_separator<char> CharSep;
|
|
||||||
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
|
|
||||||
if (tokenizer.begin() == tokenizer.end())
|
|
||||||
throw TypeException(typeInfo->getName(), fieldName + ": invalid field name");
|
|
||||||
|
|
||||||
ULONG fieldOffset = 0;
|
|
||||||
|
|
||||||
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
|
|
||||||
for (; it != tokenizer.end(); ++it)
|
|
||||||
{
|
|
||||||
const std::string &name = *it;
|
|
||||||
fieldOffset += typeInfo->getFieldOffsetByNameNotRecursively(name);
|
|
||||||
typeInfo = typeInfo->getField(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fieldOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypeInfoPtr SymbolUdtField::getTypeInfo()
|
TypeInfoPtr SymbolUdtField::getTypeInfo()
|
||||||
{
|
{
|
||||||
return TypeInfo::getTypeInfo(m_symbol);
|
return TypeInfo::getTypeInfo(m_symbol);
|
||||||
|
@ -183,89 +183,4 @@ private:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//namespace UdtUtils {
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//struct Field {
|
|
||||||
//
|
|
||||||
// Field( ULONG offset, const std::string &name, SymbolPtr &symbol, SymbolPtr &baseVirtClass = SymbolPtr(),
|
|
||||||
// ULONG virtualBasePtr = 0, ULONG virtualDispIndex = 0, ULONG virtualDispSize = 0 ) :
|
|
||||||
// m_offset(offset),
|
|
||||||
// m_name(name),
|
|
||||||
// m_symbol(symbol),
|
|
||||||
// m_baseVirtClass( baseVirtClass ),
|
|
||||||
// m_virtualBasePtr( virtualBasePtr ),
|
|
||||||
// m_virtualDispIndex( virtualDispIndex ),
|
|
||||||
// m_virtualDispSize( virtualDispSize )
|
|
||||||
// {}
|
|
||||||
//
|
|
||||||
// bool operator ==(const std::string &name) const {
|
|
||||||
// return m_name == name;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG m_offset;
|
|
||||||
// std::string m_name;
|
|
||||||
// SymbolPtr m_symbol;
|
|
||||||
// SymbolPtr m_baseVirtClass;
|
|
||||||
// ULONG m_virtualBasePtr;
|
|
||||||
// ULONG m_virtualDispIndex;
|
|
||||||
// ULONG m_virtualDispSize;
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//class FieldCollection : public std::vector< Field > {
|
|
||||||
// typedef std::vector< Field > Base;
|
|
||||||
//public:
|
|
||||||
// FieldCollection(const std::string &baseTypeName) : m_baseTypeName(baseTypeName)
|
|
||||||
// {}
|
|
||||||
//
|
|
||||||
// const Field &lookup(ULONG index) const;
|
|
||||||
// const Field &lookup(const std::string &name) const;
|
|
||||||
//
|
|
||||||
// Field &lookup(ULONG index);
|
|
||||||
// Field &lookup(const std::string &name);
|
|
||||||
//
|
|
||||||
// const std::string &getName() const {
|
|
||||||
// return m_baseTypeName;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
// std::string m_baseTypeName;
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//} // namespace UdtUtils
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
} // namespace pykd
|
} // namespace pykd
|
||||||
|
@ -68,10 +68,5 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
target.appPath = sys.argv[1]
|
target.appPath = sys.argv[1]
|
||||||
target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
|
target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
|
||||||
#print "Test module: %s" % target.appPath
|
|
||||||
|
|
||||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
||||||
#unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("customtypestest.CustomTypesTest.testPtrToCustomType") )
|
|
||||||
|
|
||||||
raw_input(">")
|
|
||||||
#
|
|
@ -151,6 +151,10 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
|
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" )
|
||||||
|
self.assertEqual( 3, len( tvl ) )
|
||||||
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" )
|
tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
||||||
|
Loading…
Reference in New Issue
Block a user