Submit and vote on feature ideas.

Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

Stubs for variadic functions

Options
jfalter
jfalter 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

  • piotr
    piotr Posts: 36
    Options

    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.)