From 0c6d91692d658902402b6b27b702676d5111761c Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 6 Feb 2013 08:01:54 +0000 Subject: [PATCH] [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 --- pykd/typedvar.cpp | 2 +- pykd/typeinfo.cpp | 47 ++++++++++++++++++++++ pykd/typeinfo.h | 11 ++++-- pykd/udtutils.cpp | 23 ----------- pykd/udtutils.h | 85 ---------------------------------------- test/scripts/pykdtest.py | 5 --- test/scripts/typedvar.py | 4 ++ 7 files changed, 60 insertions(+), 117 deletions(-) diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index fe059ea..a12fbb3 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -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; diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index df6f253..6984ef6 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -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 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 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; diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 21a695f..9878b20 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -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(); diff --git a/pykd/udtutils.cpp b/pykd/udtutils.cpp index 95e1725..90d61e9 100644 --- a/pykd/udtutils.cpp +++ b/pykd/udtutils.cpp @@ -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 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); diff --git a/pykd/udtutils.h b/pykd/udtutils.h index 024beb9..a33a4d5 100644 --- a/pykd/udtutils.h +++ b/pykd/udtutils.h @@ -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 diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 830857d..db9fa98 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -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(">") -# \ No newline at end of file diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index aff7278..bf6ae9a 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -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 ) )