diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 9196ded..7bb78b5 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -852,6 +852,12 @@ BOOST_PYTHON_MODULE( pykd ) "Return method's type by name") .def( "method", TypeInfoAdapter::getMethodByIndex, "Return method's by index") + .def( "getNumberBaseClasses", TypeInfoAdapter::getBaseClassesCount, + "Return number of base classes" ) + .def( "baseClass", TypeInfoAdapter::getBaseClassByName, + "Return a base class's type by name" ) + .def( "baseClass", TypeInfoAdapter::getBaseClassByIndex, + "Return a base class's type by index" ) .def( "deref", TypeInfoAdapter::deref, "Return type of pointer" ) .def( "append", TypeInfoAdapter::appendField, diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp index 8ea60c9..44a9b8c 100644 --- a/pykd/pytypeinfo.cpp +++ b/pykd/pytypeinfo.cpp @@ -105,6 +105,31 @@ python::list TypeInfoAdapter::getFields( kdlib::TypeInfo &typeInfo ) /////////////////////////////////////////////////////////////////////////////// +kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name) +{ + { + AutoRestorePyState pystate; + + try { + return typeInfo.getElement(name); + } + catch (kdlib::TypeException&) + {} + + try { + return typeInfo.getMethod(name); + } + catch (kdlib::TypeException&) + {} + } + + std::wstringstream sstr; + sstr << L'\'' << typeInfo.getName() << L'\'' << L" type has no field " << L'\'' << name << L'\''; + throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); +} + +/////////////////////////////////////////////////////////////////////////////// + python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo) { std::list lst; @@ -132,7 +157,6 @@ python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo) return pylst; } - /////////////////////////////////////////////////////////////////////////////// python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args) diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index 8c7276b..55234e1 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -124,20 +124,7 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { return typeInfo.getElement(name); } - static kdlib::TypeInfoPtr getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name) - { - try - { - return getElementByName(typeInfo, name); - } - catch (kdlib::DbgException&) - { - std::wstringstream sstr; - sstr << L'\'' << typeInfo.getName() << L'\'' << L" type has no field " << L'\'' << name << L'\''; - throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); - } - } - + static kdlib::TypeInfoPtr getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name); static kdlib::TypeInfoPtr getElementByIndex( kdlib::TypeInfo &typeInfo, size_t index ) { @@ -163,6 +150,24 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { return typeInfo.getMethod(index); } + static size_t getBaseClassesCount(kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getBaseClassesCount(); + } + + static kdlib::TypeInfoPtr getBaseClassByName(kdlib::TypeInfo &typeInfo, const std::wstring& className) + { + AutoRestorePyState pystate; + return typeInfo.getBaseClass(className); + } + + static kdlib::TypeInfoPtr getBaseClassByIndex(kdlib::TypeInfo &typeInfo, size_t index) + { + AutoRestorePyState pystate; + return typeInfo.getBaseClass(index); + } + static kdlib::TypeInfoPtr ptrTo( kdlib::TypeInfo &typeInfo, size_t ptrSize = 0 ) { AutoRestorePyState pystate; diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 83c7836..7dbfcb3 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -333,4 +333,10 @@ class TypeInfoTest( unittest.TestCase ): def testGetMethod(self): self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").method("childMethod").name() ) + self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").childMethod.name() ) self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").method(1).name() ) + + def testGteBaseClass(self): + classChild = target.module.type("classChild") + self.assertEqual( ["classBase1", "classBase2"], [ classChild.baseClass(i).name() for i in xrange(classChild.getNumberBaseClasses()) ] ) +