/* * mockme.h * * Created on: Nov 25, 2019 * Author: abody */ #ifndef PLATFORM_MOCKME_H_ #define PLATFORM_MOCKME_H_ //#define TOSTR(x) #x #ifdef __cplusplus #define DECLARE_MOCK(F) \ extern decltype(F) F ## __, *test_ ## F #else #define DECLARE_MOCK(F) \ extern typeof(F) F ## __, *test_ ## F #endif #define MOCKABLE(F) __attribute__((section(\ ".bss\n\t"\ ".globl test_" #F "\n\t"\ ".align 4\n\t"\ ".type test_" #F ", @object\n\t"\ ".size test_" #F ", 4\n"\ "test_" #F ":\n\t"\ ".zero 4\n\t"\ ".text\n\t"\ ".p2align 4,,15\n\t"\ ".globl " #F "\n\t"\ ".type " #F ", @function\n"\ #F ":\n\t"\ ".cfi_startproc\n\t"\ "push %edx\n\t"\ "push %edx\n\t"\ "push %eax\n\t"\ "movl test_" #F ", %eax\n\t"\ "leal " #F "__, %edx\n\t"\ "test %eax, %eax\n\t"\ "cmove %edx, %eax\n\t"\ "mov %eax, 8(%esp)\n\t"\ "pop %eax\n\t"\ "pop %edx\n\t"\ "ret\n\t"\ ".cfi_endproc\n\t"\ ".size " #F ", .-" #F "\n\t"\ ".section .text"))) F ## __ #define DEFINE_MOCK_RET(rettype, fn, decor, ...) \ static int fn ## _ ## decor ## _callcount; \ static rettype fn ## _ ## decor ## _retval; \ static rettype fn ## _ ## decor(__VA_ARGS__) { \ ++fn ## _ ## decor ## _callcount; #define DEFINE_MOCK(fn, decor, ...) \ static int fn ## _ ## decor ## _callcount; \ static void fn ## _ ## decor(__VA_ARGS__) { \ ++fn ## _ ## decor ## _callcount; #define RETURN_MOCK(fn, decor, ret) \ fn##_##decor##_retval = ret; \ return ret; } #define RETURN_MOCK_PREDEF(fn, decor) \ return fn##_##decor##_retval; } #define LEAVE_MOCK } #define DEFINE_MOCK_VAR(type, fn, decor, varname) type fn##_##decor##_##varname #define MOCK_STORE(fn, decor, varname, value) fn##_##decor##_##varname = value #define MOCK_VAR(fn, decor, varname) fn##_##decor##_##varname #define MOCK_CALLCOUNT(fn, decor) fn ## _ ## decor ## _callcount #ifdef __cplusplus namespace mockme { template class mockguard { T* m_guarded; public: mockguard(T* guarded, T testFunc) : m_guarded(guarded) { *m_guarded = testFunc; } ~mockguard() { *m_guarded = nullptr; } }; } // namespace mockme #define ACTIVATE_MOCK(fn, decor) \ fn ## _ ## decor ## _callcount = 0; \ mockme::mockguard fn ## _ ## decor ## _mockguard(&test_ ## fn, fn ## _ ## decor) #define ACTIVATE_MOCK_RV(fn, decor, ret) \ fn##_##decor##_callcount = 0; \ fn##_##decor##_retval = ret; \ mockme::mockguard fn##_##decor##_mockguard(&test_ ## fn, fn##_##decor) #endif // __cplusplus #endif /* PLATFORM_MOCKME_H_ */