Stubs for variadic functions

jfalterjfalter Posts: 2

Recently I had to stub out a Linux ioctl function for testing. I found that the stub doesn't pass the variadic arguments to the callback function. In order to pass the arguments I made a quick hack, and hijacked the __return pointer from within the auto-generated stub code to be able to see the arguments as shown below. Is there a cleaner/proper way of doing this?

extern "C" int ioctl (int __fd, unsigned long __request, ...)  throw();
extern "C" int CppTest_Stub_ioctl (int __fd, unsigned long __request, ...)  throw()
{
    struct {
        int __return;
        va_list vl;
    } va_bipass;

    va_bipass.__return = 0;
    va_start(va_bipass.vl, __request);

    /**
     * This section enables Dynamic Stub Configuration with Stub Callbacks.
     *
     * IMPORTANT: THIS COMMENT BLOCK SHOULD NOT BE DELETED OR MODIFIED
     *
     * 1. Define stub callback function in test suite file - use the following signature:
     *     void CppTest_StubCallback_SomeName(CppTest_StubCallInfo* stubCallInfo, int* __return, int __fd, unsigned long __request)
     *
     * 2. Register stub callback in test case function - use the following code:
     *     CPPTEST_REGISTER_STUB_CALLBACK("ioctl", &CppTest_StubCallback_SomeName);
     */

    CPPTEST_CALL_STUB_CALLBACK("ioctl", &va_bipass.__return, __fd, __request);
    va_end(va_bipass.vl);

    return va_bipass.__return;
}

Comments

  • piotrpiotr Posts: 27

    There's no significantly better way of doing it (with callbacks).
    I assume that in the callback you would use it like this:

    va_list vl = * ((va_list*) (__return + 1)); // retrieve va_bypass.vl (see stub definition)
    int va_1 = va_arg(vl, int);
    int va_2 = va_arg(vl, int);
    int va_3 = va_arg(vl, int);
    
    CPPTEST_ASSERT_INTEGER_EQUAL(10, va_1);
    CPPTEST_ASSERT_INTEGER_EQUAL(11, va_2);
    CPPTEST_ASSERT_INTEGER_EQUAL(12, va_3);
    

    We are considering making the signature of the callback function customizable (so you could add additional "va_list" to it etc.)

Sign In or Register to comment.