#include "../../unity/unity.h" #include #include #include void setUp(void) { /* Setup code here, or leave empty */ } void tearDown(void) { /* Cleanup code here, or leave empty */ } /* Helper to allocate and zero a struct line */ static struct line* alloc_zeroed_line(void) { struct line* l = (struct line*)malloc(sizeof(struct line)); TEST_ASSERT_NOT_NULL(l); memset(l, 0, sizeof(*l)); return l; } void test_freeline_null_pointer_ok(void) { /* Should not crash or modify anything when given NULL */ freeline(NULL); /* If we got here, no crash; record a trivial assertion */ TEST_ASSERT_TRUE(1); } void test_freeline_frees_and_nulls_members(void) { struct line* l = alloc_zeroed_line(); /* Simulate populated fields and buffer */ l->nfields = 3; l->nfields_allocated = 3; l->fields = (struct field*)malloc(sizeof(struct field) * 3); TEST_ASSERT_NOT_NULL(l->fields); /* Field contents don't matter to freeline; avoid extra allocations */ for (int i = 0; i < 3; i++) { l->fields[i].beg = NULL; l->fields[i].len = 0; } l->buf.buffer = (char*)malloc(16); TEST_ASSERT_NOT_NULL(l->buf.buffer); memset(l->buf.buffer, 'X', 16); l->buf.length = 16; freeline(l); /* After freeline: pointers are NULLed; counters/length unchanged */ TEST_ASSERT_NULL(l->fields); TEST_ASSERT_NULL(l->buf.buffer); TEST_ASSERT_EQUAL_INT(3, (int)l->nfields); TEST_ASSERT_EQUAL_INT(3, (int)l->nfields_allocated); TEST_ASSERT_EQUAL_INT(16, (int)l->buf.length); free(l); } void test_freeline_idempotent_on_same_line(void) { struct line* l = alloc_zeroed_line(); l->fields = (struct field*)malloc(sizeof(struct field)); TEST_ASSERT_NOT_NULL(l->fields); l->nfields = 1; l->nfields_allocated = 1; l->buf.buffer = (char*)malloc(8); TEST_ASSERT_NOT_NULL(l->buf.buffer); memset(l->buf.buffer, 'Y', 8); l->buf.length = 8; /* First call frees and NULLs pointers */ freeline(l); TEST_ASSERT_NULL(l->fields); TEST_ASSERT_NULL(l->buf.buffer); /* Second call should be safe (free(NULL)) and remain NULL */ freeline(l); TEST_ASSERT_NULL(l->fields); TEST_ASSERT_NULL(l->buf.buffer); free(l); } void test_freeline_only_fields_allocated(void) { struct line* l = alloc_zeroed_line(); l->fields = (struct field*)malloc(sizeof(struct field) * 2); TEST_ASSERT_NOT_NULL(l->fields); l->nfields = 2; l->nfields_allocated = 2; /* Ensure buffer is NULL/non-allocated */ l->buf.buffer = NULL; l->buf.length = 5; /* length should remain unchanged */ freeline(l); TEST_ASSERT_NULL(l->fields); TEST_ASSERT_NULL(l->buf.buffer); TEST_ASSERT_EQUAL_INT(2, (int)l->nfields); TEST_ASSERT_EQUAL_INT(2, (int)l->nfields_allocated); TEST_ASSERT_EQUAL_INT(5, (int)l->buf.length); free(l); } void test_freeline_only_buffer_allocated(void) { struct line* l = alloc_zeroed_line(); l->fields = NULL; l->nfields = 0; l->nfields_allocated = 0; l->buf.buffer = (char*)malloc(32); TEST_ASSERT_NOT_NULL(l->buf.buffer); memset(l->buf.buffer, 'Z', 32); l->buf.length = 32; freeline(l); TEST_ASSERT_NULL(l->fields); TEST_ASSERT_NULL(l->buf.buffer); TEST_ASSERT_EQUAL_INT(0, (int)l->nfields); TEST_ASSERT_EQUAL_INT(0, (int)l->nfields_allocated); TEST_ASSERT_EQUAL_INT(32, (int)l->buf.length); free(l); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_freeline_null_pointer_ok); RUN_TEST(test_freeline_frees_and_nulls_members); RUN_TEST(test_freeline_idempotent_on_same_line); RUN_TEST(test_freeline_only_fields_allocated); RUN_TEST(test_freeline_only_buffer_allocated); return UNITY_END(); }