ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
652 stars 269 forks source link

Mock generated is wrong when the name of the parameter contains size or length sub-string #476

Open parmi93 opened 1 month ago

parmi93 commented 1 month ago

read_interface.h:

#ifndef READ_INTERFACE_H
#define READ_INTERFACE_H
#include <stddef.h>

/**
 * @brief Allow to read from a file.
 *
 * @param[in,out] bytes_to_read Pointer to the destination indicating how many bytes at most should
 * be read, 0 means to read all bytes up to the end of the file.
 * On success, returns how many bytes were actually read and loaded in the **buffer.
 * On failure, the returned value is not defined.
 * @param[in] buff_size Indicates the size (in bytes) of the **buffer.
 * @param[in,out] buffer Pointer to the destination in which to load the data, if *buffer is NULL
 * then a new buffer is allocated.
 */
void read_interface(size_t *bytes_to_read, size_t buff_size, char **buffer);

#endif // READ_INTERFACE_H

read.h

#ifndef READ_H
#define READ_H
#include "../interfaces/read_interface.h"

void read(size_t *bytes_to_read, size_t buff_size, char **buffer);

#endif // READ_H

read.c

#include "read.h"

void read(size_t *bytes_to_read, size_t buff_size, char **buffer)
{
    read_interface(bytes_to_read, buff_size, buffer);
}

test_read.c

#include "read.h"
#include "mock_read_interface.h"
#include "unity.h"

void test_1()
{
    size_t bytes_to_read = 3;
    char *buffer         = NULL;

    read_interface_Expect(&bytes_to_read, 0, &buffer);

    read(&bytes_to_read, 0, &buffer);
}

mock_read_interface.c

/* AUTOGENERATED FILE. DO NOT EDIT. */
// ...
void CMockExpectParameters_read_interface(CMOCK_read_interface_CALL_INSTANCE* cmock_call_instance, size_t* bytes_to_read, int bytes_to_read_Depth, size_t buff_size, char** buffer, int buffer_Depth);
void CMockExpectParameters_read_interface(CMOCK_read_interface_CALL_INSTANCE* cmock_call_instance, size_t* bytes_to_read, int bytes_to_read_Depth, size_t buff_size, char** buffer, int buffer_Depth)
{
  cmock_call_instance->Expected_bytes_to_read = bytes_to_read;
  cmock_call_instance->Expected_bytes_to_read_Depth = bytes_to_read_Depth;
  cmock_call_instance->IgnoreArg_bytes_to_read = 0;
  cmock_call_instance->ReturnThruPtr_bytes_to_read_Used = 0;
  memcpy((void*)(&cmock_call_instance->Expected_buff_size), (void*)(&buff_size),
         sizeof(size_t[sizeof(buff_size) == sizeof(size_t) ? 1 : -1])); /* add size_t to :treat_as_array if this causes an error */
  cmock_call_instance->IgnoreArg_buff_size = 0;
  cmock_call_instance->Expected_buffer = buffer;
  cmock_call_instance->Expected_buffer_Depth = buffer_Depth;
  cmock_call_instance->IgnoreArg_buffer = 0;
  cmock_call_instance->ReturnThruPtr_buffer_Used = 0;
}

// ...

void read_interface_CMockExpect(UNITY_LINE_TYPE cmock_line, size_t* bytes_to_read, size_t buff_size, char** buffer)
{
  CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_interface_CALL_INSTANCE));
  CMOCK_read_interface_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_interface_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);
  memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));
  Mock.read_interface_CallInstance = CMock_Guts_MemChain(Mock.read_interface_CallInstance, cmock_guts_index);
  Mock.read_interface_IgnoreBool = (char)0;
  cmock_call_instance->LineNumber = cmock_line;
  cmock_call_instance->CallOrder = ++GlobalExpectCount;
  CMockExpectParameters_read_interface(cmock_call_instance, bytes_to_read, buff_size, buff_size, buffer, 1);
}
// ...

Ceedling Output:

[test_read.c]
  Test: test_1
  At line (10): "You Asked Me To Compare Nothing, Which Was Pointless.. Function read_interface Argument bytes_to_read. Function called with unexpected argument value."

The problem seems to be the CMockExpectParameters_read_interface(cmock_call_instance, bytes_to_read, buff_size, buff_size, buffer, 1); call where the argument buff_size is passed as bytes_to_read_Depth parameter instead of just 1, the right call should be CMockExpectParameters_read_interface(cmock_call_instance, bytes_to_read, 1, buff_size, buffer, 1);

I noticed that if I change the name of the buff_size parameter in foo the problem is solved, it seems that this problem occurs only when in the name of the parameter there is the sub-string size or length, so this works void read_interface(size_t *bytes_to_read, size_t foo, char **buffer);

I'm not sure but I think this behavior is due because of this functionality: https://github.com/ThrowTheSwitch/CMock/issues/189

How can I solve the problem without having to change the name of the parameter?

parmi93 commented 1 month ago

I temporarily solved the problem by adding this parameter in the project.yml file, but I think it is not the correct way to disable this functionality as array_size_name should be a regular expression.

:cmock:
  :array_size_name: 'disable'