From 03f4396227d0fe2cd48fb717a6f916ebddcbe58f Mon Sep 17 00:00:00 2001 From: jf-home Date: Fri, 30 Aug 2024 00:49:50 +0800 Subject: [PATCH] =?UTF-8?q?stack=E6=B7=BB=E5=8A=A0=E5=8D=95=E4=BE=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/unicstl-unity/src/unity_config.h | 2 +- include/common.h | 2 +- include/queue.h | 7 +- include/stack.h | 7 +- src/queue.c | 106 ++++---- src/stack.c | 110 +++++---- test/test.c | 2 +- test/test_stack.c | 279 ++++++++++++++++++++++ 8 files changed, 406 insertions(+), 109 deletions(-) diff --git a/3rdparty/unicstl-unity/src/unity_config.h b/3rdparty/unicstl-unity/src/unity_config.h index 6d5e8c8..4ed416d 100644 --- a/3rdparty/unicstl-unity/src/unity_config.h +++ b/3rdparty/unicstl-unity/src/unity_config.h @@ -2,7 +2,7 @@ #ifndef _UNITY_CONFIG_H_ #define _UNITY_CONFIG_H_ -// #define UNITY_OUTPUT_COLOR 1 +#define UNITY_OUTPUT_COLOR 1 #define UNITY_USE_FLUSH_STDOUT 1 #define UNITY_INCLUDE_PRINT_FORMATTED 1 // support TEST_PRINTF diff --git a/include/common.h b/include/common.h index c8db42d..ef375bd 100644 --- a/include/common.h +++ b/include/common.h @@ -11,7 +11,7 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -#define NDEBUG 1 +// #define NDEBUG 1 #include #include diff --git a/include/queue.h b/include/queue.h index 73b0416..00a28bc 100644 --- a/include/queue.h +++ b/include/queue.h @@ -39,13 +39,14 @@ struct _queue bool (*back)(struct _queue* self, void* obj); bool (*front)(struct _queue* self, void* obj); - bool (*clear)(struct _queue* self); + // base bool (*empty)(struct _queue* self); bool (*full)(struct _queue* self); uint32_t (*size)(struct _queue* self); uint32_t (*capacity)(struct _queue* self); - - // clear and free node pointer + + // clear and free node + bool (*clear)(struct _queue* self); void (*destory)(struct _queue* self); // print diff --git a/include/stack.h b/include/stack.h index 4ae173e..bfeaf6f 100644 --- a/include/stack.h +++ b/include/stack.h @@ -34,10 +34,11 @@ struct _stack bool (*pop)(struct _stack* self, void* obj); // base - uint32_t(*size)(struct _stack* self); bool (*empty)(struct _stack* self); - - // others + uint32_t (*size)(struct _stack* self); + uint32_t (*capacity)(struct _stack* self); + + // clear and free node bool (*clear)(struct _stack* self); void (*destory)(struct _stack* self); diff --git a/src/queue.c b/src/queue.c index 6ec6056..ec87a2f 100644 --- a/src/queue.c +++ b/src/queue.c @@ -117,6 +117,11 @@ static bool queue_front(struct _queue* self, void* obj) static bool queue_clear(struct _queue* self) { assert(self != NULL); + if(self->empty(self)) + { + return true; + } + struct _queue_node* node = self->_front; struct _queue_node* next = NULL; while (node) @@ -301,97 +306,97 @@ static void queue2_print(struct _queue* self) } } -bool queue_init(struct _queue * queue, uint32_t obj_size) +bool queue_init(struct _queue * self, uint32_t obj_size) { - assert(queue != NULL); + assert(self != NULL); assert(obj_size > 0); - if(queue == NULL || obj_size == 0) + if(self == NULL || obj_size == 0) { return false; } // attribute init - queue->_size = 0; - queue->_obj_size = obj_size; - queue->_capacity = UINT32_MAX; - queue->_ratio = 1; + self->_size = 0; + self->_obj_size = obj_size; + self->_capacity = UINT32_MAX; + self->_ratio = 1; // function init - queue->push = queue_push; - queue->pop = queue_pop; + self->push = queue_push; + self->pop = queue_pop; - queue->back = queue_back; - queue->front = queue_front; + self->back = queue_back; + self->front = queue_front; - queue->clear = queue_clear; - queue->empty = queue_empty; - queue->full = queue_full; - queue->size = queue_size; - queue->capacity = queue_capacity; + self->clear = queue_clear; + self->empty = queue_empty; + self->full = queue_full; + self->size = queue_size; + self->capacity = queue_capacity; - queue->destory = queue_destory; - queue->print = queue_print; + self->destory = queue_destory; + self->print = queue_print; // init front & back - queue->_front = NULL; - queue->_back = NULL; + self->_front = NULL; + self->_back = NULL; return true; } -bool queue_init2(struct _queue * queue, uint32_t obj_size, uint32_t capacity) +bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capacity) { - assert(queue != NULL); + assert(self != NULL); assert(obj_size > 0); assert(capacity > 0); - if(queue == NULL || obj_size == 0 || capacity == 0) + if(self == NULL || obj_size == 0 || capacity == 0) { return false; } // attribute init - queue->_size = 0; - queue->_obj_size = obj_size; - queue->_capacity = capacity; - queue->_ratio = 2; + self->_size = 0; + self->_obj_size = obj_size; + self->_capacity = capacity; + self->_ratio = 2; // function init - queue->push = queue2_push; - queue->pop = queue2_pop; + self->push = queue2_push; + self->pop = queue2_pop; - queue->back = queue2_back; - queue->front = queue2_front; + self->back = queue2_back; + self->front = queue2_front; - queue->clear = queue2_clear; - queue->empty = queue_empty; - queue->full = queue_full; - queue->size = queue_size; - queue->capacity = queue_capacity; + self->clear = queue2_clear; + self->empty = queue_empty; + self->full = queue_full; + self->size = queue_size; + self->capacity = queue_capacity; - queue->destory = queue2_destory; - queue->print = queue2_print; + self->destory = queue2_destory; + self->print = queue2_print; // init front & back - queue->_front = (struct _queue_node *)malloc(sizeof(struct _queue_node)); - if(queue->_front == NULL) + self->_front = (struct _queue_node *)malloc(sizeof(struct _queue_node)); + if(self->_front == NULL) { goto done; } - queue->_back = queue->_front; + self->_back = self->_front; - // use queue->_front->obj as obj_array - // queue->_front->obj = calloc(queue->_capacity, queue->_obj_size); - queue->_front->obj = malloc(queue->_capacity * queue->_obj_size); - if(queue->_front->obj == NULL) + // use self->_front->obj as obj_array + // self->_front->obj = calloc(self->_capacity, self->_obj_size); + self->_front->obj = malloc(self->_capacity * self->_obj_size); + if(self->_front->obj == NULL) { goto done1; } - queue->_index_front = 0; - queue->_index_back = 0; + self->_index_front = 0; + self->_index_back = 0; return true; done1: - free(queue->_front); + free(self->_front); done: return false; } @@ -403,10 +408,7 @@ queue_t queue_new(void) void queue_free(queue_t* queue) { - // assert(queue != NULL); - // assert(*queue != NULL); - // assert((*queue)->destory != NULL); - + assert(queue != NULL); if(queue != NULL && *queue != NULL) { if((*queue)->destory != NULL) diff --git a/src/stack.c b/src/stack.c index c8294ac..2e04e00 100644 --- a/src/stack.c +++ b/src/stack.c @@ -25,9 +25,7 @@ static uint32_t stack_size(struct _stack* self) static bool stack_empty(struct _stack* self) { assert(self != NULL); - // assert(self->_head != NULL); - // return self->_head->next == NULL ? true : false; - return !stack_size(self); + return stack_size(self) == 0; } static bool stack_peek(struct _stack* self, void* obj) @@ -105,10 +103,9 @@ static bool stack_pop(struct _stack* self, void* obj) static bool stack_clear(struct _stack* self) { assert(self != NULL); - if (self->empty(self)) { - return false; + return true; } struct _stack_node* node = self->_head->next; @@ -149,42 +146,6 @@ static void stack_print(struct _stack* self) } } -bool stack_init(struct _stack* self, uint32_t obj_size) -{ - assert(self != NULL); - - // 1. set attr - self->_obj_size = obj_size; - self->_size = 0; - // self->_capacity = 64; // ÎÞЧ - // self->_ratio = 2; // ÎÞЧ - - // 2. set function - // kernel - self->peek = stack_peek; - self->pop = stack_pop; - self->push = stack_push; - - // others - self->clear = stack_clear; - self->empty = stack_empty; - self->size = stack_size; - self->destory = stack_destory; - self->print = stack_print; - - // 3. set node - self->_head = (struct _stack_node *)malloc(sizeof(struct _stack_node)); - if (self->_head == NULL) - { - return false; - } - self->_head->obj = NULL; - self->_head->next = NULL; - - return true; -} - - static bool stack2_peek(struct _stack* self, void* obj) { assert(self != NULL); @@ -208,9 +169,9 @@ static bool stack2_push(struct _stack* self, void* obj) assert(self->_head != NULL); assert(obj != NULL); - if (self->size(self) == self->_capacity) + if (self->size(self) == self->capacity(self)) { - void* obj_new = (void*)realloc(self->_head->obj, self->_capacity * self->_obj_size * self->_ratio); + void* obj_new = (void*)realloc(self->_head->obj, self->capacity(self) * self->_obj_size * self->_ratio); if (obj_new == NULL) { return false; @@ -281,6 +242,51 @@ static void stack2_print(struct _stack* self) } } + +bool stack_init(struct _stack* self, uint32_t obj_size) +{ + assert(self != NULL); + assert(obj_size != 0); + if(self == NULL || obj_size == 0) + { + return false; + } + + // 1. set attr + self->_obj_size = obj_size; + self->_size = 0; + self->_capacity = UINT32_MAX; + self->_ratio = 1; + + // 2. set function + // kernel + self->peek = stack_peek; + self->pop = stack_pop; + self->push = stack_push; + + // base + self->empty = stack_empty; + self->size = stack_size; + self->capacity = stack_capacity; + + // clear and free node + self->clear = stack_clear; + self->destory = stack_destory; + // print + self->print = stack_print; + + // 3. set node + self->_head = (struct _stack_node *)malloc(sizeof(struct _stack_node)); + if (self->_head == NULL) + { + return false; + } + self->_head->obj = NULL; + self->_head->next = NULL; + + return true; +} + bool stack_init2(struct _stack* self, uint32_t obj_size, uint32_t capacity) { assert(self != NULL); @@ -298,10 +304,14 @@ bool stack_init2(struct _stack* self, uint32_t obj_size, uint32_t capacity) self->push = stack2_push; // others - self->clear = stack_clear; self->empty = stack_empty; self->size = stack_size; + self->capacity = stack_capacity; + + // clear and free node + self->clear = stack_clear; self->destory = stack2_destory; + // print self->print = stack2_print; // 3. set node @@ -324,15 +334,19 @@ bool stack_init2(struct _stack* self, uint32_t obj_size, uint32_t capacity) stack_t stack_new(void) { - return (struct _stack*)malloc(sizeof(struct _stack)); + return (struct _stack*)calloc(1, sizeof(struct _stack)); } void stack_free(stack_t *stack) { - if(*stack) + assert(stack != NULL); + if(stack != NULL && *stack != NULL) { - (*stack)->destory(*stack); + if((*stack)->destory != NULL) + { + (*stack)->destory(*stack); + } free(*stack); + *stack = NULL; } - *stack = NULL; } diff --git a/test/test.c b/test/test.c index d018b4d..d3f6edf 100644 --- a/test/test.c +++ b/test/test.c @@ -73,8 +73,8 @@ int main(int argc, char const *argv[]) printf("----- Unicstl Unit Test -----\n"); UNITY_BEGIN(); - // test_stack(); test_queue(); + test_stack(); return UNITY_END(); } diff --git a/test/test_stack.c b/test/test_stack.c index 418360c..808cf8a 100644 --- a/test/test_stack.c +++ b/test/test_stack.c @@ -10,6 +10,257 @@ */ #include "test.h" + +static void test_stack_init(void) +{ + struct _stack stack; + + // ------------------------------ +#ifdef NDEBUG + TEST_ASSERT_FALSE(stack_init(NULL, sizeof(int))); + TEST_ASSERT_FALSE(stack_init(&stack, 0)); +#endif + TEST_ASSERT_TRUE(stack_init(&stack, sizeof(int))); + stack.destory(&stack); + + // ------------------------------ +#ifdef NDEBUG + TEST_ASSERT_FALSE(stack_init2(NULL, sizeof(int), 1)); + TEST_ASSERT_FALSE(stack_init2(&stack, 0, 1)); + TEST_ASSERT_FALSE(stack_init2(&stack, sizeof(int), 0)); +#endif + TEST_ASSERT_TRUE(stack_init2(&stack, sizeof(int), 1)); + stack.destory(&stack); +} + +static void test_stack_new(void) +{ + stack_t stack = NULL; + stack = stack_new(); + stack_free(&stack); + + // ------------------------------ + stack = stack_new(); + TEST_ASSERT_NOT_NULL(stack); + +#ifdef NDEBUG + TEST_ASSERT_FALSE(stack_init(NULL, sizeof(int))); + TEST_ASSERT_FALSE(stack_init(stack, 0)); +#endif + TEST_ASSERT_TRUE(stack_init(stack, sizeof(int))); + stack_free(&stack); + + // ------------------------------ + stack = stack_new(); + TEST_ASSERT_NOT_NULL(stack); + +#ifdef NDEBUG + TEST_ASSERT_FALSE(stack_init2(NULL, sizeof(int), 1)); + TEST_ASSERT_FALSE(stack_init2(stack, 0, 1)); + TEST_ASSERT_FALSE(stack_init2(stack, sizeof(int), 0)); +#endif + TEST_ASSERT_TRUE(stack_init2(stack, sizeof(int), 1)); + stack_free(&stack); + + TEST_ASSERT_NULL(stack); + stack_free(&stack); // stack_free(NULL); +} + +static void test_stack_push(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + stack_t stack = NULL; + + // ------------------------------ + stack = stack_new(); + stack_init(stack, sizeof(int)); + TEST_ASSERT_TRUE(stack->empty(stack)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(stack->empty(stack)); + } + stack_free(&stack); + + // ------------------------------ + stack = stack_new(); + stack_init2(stack, sizeof(int), len); + TEST_ASSERT_TRUE(stack->empty(stack)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(stack->empty(stack)); + } + stack_free(&stack); + + // ------------------------------ + // if capacity is less than data len + stack = stack_new(); + stack_init2(stack, sizeof(int), len - 2); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + } + stack_free(&stack); +} + +static void test_stack_pop(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + stack_t stack = NULL; + + // ------------------------------ + stack = stack_new(); + stack_init(stack, sizeof(int)); + for(i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + + TEST_ASSERT_TRUE(stack->pop(stack, &temp)); + + if (!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + } + } + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + stack_free(&stack); + + // ------------------------------ + stack = stack_new(); + stack_init2(stack, sizeof(int), len); + for(i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + + TEST_ASSERT_TRUE(stack->pop(stack, &temp)); + + if (!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + } + } + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + stack_free(&stack); + + // ------------------------------ + // if capacity is less than data len + stack = stack_new(); + stack_init2(stack, sizeof(int), len - 2); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + } + uint32_t capacity = stack->capacity(stack); + for (i = 0; i < len; i++) + { + if (!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->pop(stack, &temp)); + } + else + { + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + } + + if (!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + } + } + stack_free(&stack); +} + +static void test_stack_clear(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + stack_t stack = NULL; + + // ------------------------------ + stack = stack_new(); + stack_init(stack, sizeof(int)); + for(i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + TEST_ASSERT_TRUE(stack->clear(stack)); + for(i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + TEST_ASSERT_FALSE(stack->empty(stack)); + TEST_ASSERT_TRUE(stack->clear(stack)); + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_TRUE(stack->clear(stack)); + stack_free(&stack); + + // ------------------------------ + stack = stack_new(); + stack_init2(stack, sizeof(int), len); + TEST_ASSERT_TRUE(stack->clear(stack)); + for(i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + TEST_ASSERT_FALSE(stack->empty(stack)); + TEST_ASSERT_TRUE(stack->clear(stack)); + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_TRUE(stack->clear(stack)); + stack_free(&stack); +} + static void test_stack_num(void) { uint32_t i = 0; @@ -46,7 +297,35 @@ static void test_stack_num(void) TEST_ASSERT_NULL(stack); } +static void test_stack_struct(void) +{ + +} + + +static void test_stack2_num(void) +{ + +} + +static void test_stack2_struct(void) +{ + +} + void test_stack(void) { RUN_TEST(test_stack_num); + + RUN_TEST(test_stack_init); + RUN_TEST(test_stack_new); + RUN_TEST(test_stack_push); + RUN_TEST(test_stack_pop); + RUN_TEST(test_stack_clear); + + RUN_TEST(test_stack_num); + RUN_TEST(test_stack_struct); + + RUN_TEST(test_stack2_num); + RUN_TEST(test_stack2_struct); }