mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +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;
|
||||
|
||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
||||
TypeInfoPtr fieldTypeInfo = typeInfo->getFieldRecursive( listEntryName );
|
||||
|
||||
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::stringstream sstr;
|
||||
|
@ -74,6 +74,10 @@ public:
|
||||
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 ) {
|
||||
throw TypeException( getName(), "type is not a struct" );
|
||||
}
|
||||
@ -85,6 +89,7 @@ public:
|
||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
||||
throw TypeException( getName(), "type is not a struct" );
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||
throw TypeException( getName(), "type is not a struct" );
|
||||
}
|
||||
@ -333,9 +338,9 @@ protected:
|
||||
return lookupField(index)->getName();
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
||||
return getFieldOffsetRecursive( shared_from_this(), fieldName );
|
||||
}
|
||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName );
|
||||
|
||||
virtual TypeInfoPtr getFieldRecursive(const std::string &fieldName );
|
||||
|
||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||
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()
|
||||
{
|
||||
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
|
||||
|
@ -68,10 +68,5 @@ if __name__ == "__main__":
|
||||
|
||||
target.appPath = sys.argv[1]
|
||||
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("customtypestest.CustomTypesTest.testPtrToCustomType") )
|
||||
|
||||
raw_input(">")
|
||||
#
|
@ -150,6 +150,10 @@ class TypedVarTest( unittest.TestCase ):
|
||||
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
|
||||
self.assertEqual( 3, len( 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" )
|
||||
self.assertEqual( 3, len( tvl ) )
|
||||
|
Loading…
Reference in New Issue
Block a user