Fixing global mock deletion support.

This commit is contained in:
sergiotarxz 2022-08-02 11:13:23 +02:00
parent 8493c34291
commit 9368209522
6 changed files with 46 additions and 30 deletions

View File

@ -1,3 +0,0 @@
#include "elfspy/Fake.h"
std::vector<spy::FakeI *> spy::fake_list;

13
Hook.cpp Normal file
View File

@ -0,0 +1,13 @@
#include <elfspy/Hook.h>
std::vector<spy::IHook *> spy::hook_list;
void spy::delete_mocks (void) {
while (spy::hook_list.size () != 0) {
auto index = spy::hook_list.size () - 1;
auto element = spy::hook_list[index];
spy::hook_list.erase (spy::hook_list.begin() + index);
delete element;
}
}

View File

@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <iostream>
namespace spy namespace spy
{ {
@ -18,20 +19,9 @@ namespace spy
* destructor uninstalls it * destructor uninstalls it
*/ */
class FakeI {
};
extern std::vector<FakeI *> fake_list;
void delete_mocks (void) {
while (fake_list.size () != 0) {
auto index = fake_list.size () - 1;
auto element = fake_list[index];
fake_list.erase (fake_list.begin() + index);
delete element;
}
}
template <typename H, typename ReturnType, typename... ArgTypes> template <typename H, typename ReturnType, typename... ArgTypes>
class Fake : FakeI class Fake
{ {
public: public:
Fake(H& hook, ReturnType (*func)(ArgTypes...)); Fake(H& hook, ReturnType (*func)(ArgTypes...));
@ -43,27 +33,30 @@ private:
}; };
template <typename H, typename ReturnType, typename... ArgTypes> template <typename H, typename ReturnType, typename... ArgTypes>
inline Fake<H, ReturnType, ArgTypes...>:: Fake<H, ReturnType, ArgTypes...>::
Fake(H& hook, ReturnType (*func)(ArgTypes...)) Fake(H& hook, ReturnType (*func)(ArgTypes...))
:hook_(hook) :hook_(hook)
{ {
func_ = hook_.patch(func); func_ = hook_.patch(func);
} }
/*
template <typename H, typename ReturnType, typename... ArgTypes> template <typename H, typename ReturnType, typename... ArgTypes>
inline Fake<H, ReturnType, ArgTypes...>::~Fake() Fake<H, ReturnType, ArgTypes...>::~Fake()
{ {
std::cout << "Fake" << std::endl;
hook_.patch(func_); hook_.patch(func_);
} }
template <typename H, typename ReturnType, typename... ArgTypes> template <typename H, typename ReturnType, typename... ArgTypes>
inline auto new_fake(H& hook, ReturnType (*patch)(ArgTypes...)) Fake<H, ReturnType, ArgTypes...>* new_fake(H& hook, ReturnType (*patch)(ArgTypes...))
-> Fake<H, ReturnType, ArgTypes...>*
{ {
auto instance = std::make_shared<Fake<H, ReturnType, ArgTypes...>>(hook, patch); std::cout << "hola" << std::endl;
auto instance = new Fake<H, ReturnType, ArgTypes...>(hook, patch);
fake_list.push_back (instance); fake_list.push_back (instance);
return instance; return instance;
} }
*/
} // namespace elfspy } // namespace elfspy

View File

@ -7,6 +7,9 @@
#include "elfspy/MethodInfo.h" #include "elfspy/MethodInfo.h"
#include "elfspy/Thunk.h" #include "elfspy/Thunk.h"
#include <iostream>
#include <vector>
namespace spy namespace spy
{ {
@ -20,6 +23,19 @@ namespace spy
* are functions where the first type in Args... is the class type. * are functions where the first type in Args... is the class type.
*/ */
class IHook {
public:
virtual ~IHook() {
std::cout << "HookI" << std::endl;
}
};
extern std::vector<IHook *> hook_list;
void delete_mocks (void);
template <typename CRTP, typename ReturnType, typename... ArgTypes> template <typename CRTP, typename ReturnType, typename... ArgTypes>
class Hook : public HookImpl<CRTP, ReturnType, ArgTypes...> class Hook : public HookImpl<CRTP, ReturnType, ArgTypes...>
{ {

View File

@ -1,10 +1,12 @@
#ifndef ELFSPY_LAMBDA_H #ifndef ELFSPY_LAMBDA_H
#define ELFSPY_LAMBDA_H #define ELFSPY_LAMBDA_H
#include <elfspy/Hook.h>
#include <utility> #include <utility>
namespace spy namespace spy
{ {
extern std::vector<IHook *> hook_list;
/** /**
* @namespace spy * @namespace spy
@ -16,7 +18,7 @@ namespace spy
*/ */
template <typename H, typename L, typename ReturnType, typename... ArgTypes> template <typename H, typename L, typename ReturnType, typename... ArgTypes>
class Lambda class Lambda : public IHook
{ {
public: public:
Lambda(H& hook, L& lambda); Lambda(H& hook, L& lambda);
@ -56,20 +58,15 @@ ReturnType Lambda<H, L, ReturnType, ArgTypes...>::function(ArgTypes... argtypes)
return instance_->lambda_(std::forward<ArgTypes>(argtypes)...); return instance_->lambda_(std::forward<ArgTypes>(argtypes)...);
} }
template <typename H, typename L>
inline auto fake(H& hook, L& lambda)
-> typename H::template Export<Lambda, H, L, typename H::Result>::Type
{
return { hook, lambda };
}
template <typename H, typename L> template <typename H, typename L>
inline auto new_fake(H& hook, L& lambda) inline auto new_fake(H& hook, L& lambda)
-> typename H::template Export<Lambda, H, L, typename H::Result>::Type* -> typename H::template Export<Lambda, H, L, typename H::Result>::Type*
{ {
using Install = using Install =
typename H::template Export<Lambda, H, L, typename H::Result>::Type; typename H::template Export<Lambda, H, L, typename H::Result>::Type;
return new Install(hook, lambda); auto instance = new Install(hook, lambda);
hook_list.push_back (instance);
return instance;
} }
} // namespace elfspy } // namespace elfspy

View File

@ -3,6 +3,7 @@ pkg = import('pkgconfig')
sources = [ sources = [
'Call.cpp', 'Call.cpp',
'Hook.cpp',
'Report.cpp', 'Report.cpp',
'ELFInfo.cpp', 'ELFInfo.cpp',
'SPY.cpp', 'SPY.cpp',
@ -11,7 +12,6 @@ sources = [
'GOTEntry.cpp', 'GOTEntry.cpp',
'Fail.cpp', 'Fail.cpp',
'MFile.cpp', 'MFile.cpp',
'Fake.cpp',
] ]
headers = [ headers = [