Added linked_list_search API. Refactored linked list implementation and testing (now much better).
This commit is contained in:
parent
d6f2342d05
commit
13843b16bc
|
@ -1,5 +1,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <printf.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "linked_list.h"
|
||||
|
||||
typedef struct
|
||||
|
@ -8,42 +9,94 @@ typedef struct
|
|||
int val;
|
||||
} my_list;
|
||||
|
||||
void validate_list(linked_list_t* list)
|
||||
|
||||
bool validate_list(linked_list_t* list)
|
||||
{
|
||||
int good = 0;
|
||||
if(list->head == NULL)
|
||||
good += list->tail == NULL;
|
||||
if(list->tail == NULL)
|
||||
good += list->head == NULL;
|
||||
bool result = true;
|
||||
// list_head_test
|
||||
if(list->head != NULL)
|
||||
good += list->head->prev == NULL;
|
||||
{
|
||||
result = result && (list->head->prev == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result && (list->tail == NULL);
|
||||
}
|
||||
|
||||
if(list->tail != NULL)
|
||||
good += list->tail->next == NULL;
|
||||
printf(good == 2 ? " good" : " bad");
|
||||
{
|
||||
result = result && (list->tail->next == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result && (list->head == NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_validate(linked_list_t *list)
|
||||
|
||||
bool assert_list(linked_list_t* list, int val[], int size)
|
||||
{
|
||||
my_list* node = (my_list*) linked_list_first(list);
|
||||
while(node != NULL)
|
||||
linked_list_node_t* node = linked_list_first(list);
|
||||
unsigned int i = 0;
|
||||
|
||||
if(!validate_list(list))
|
||||
return false;
|
||||
|
||||
while(node != NULL && i < size)
|
||||
{
|
||||
printf("%d", node->val);
|
||||
node = (my_list*) linked_list_next((linked_list_node_t *) node);
|
||||
my_list* enode = OBTAIN_STRUCT_ADDR(node, lnode, my_list);
|
||||
if(enode->val != val[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
node = linked_list_next(node);
|
||||
}
|
||||
|
||||
printf("======");
|
||||
node = (my_list*) linked_list_last(list);
|
||||
while(node != NULL)
|
||||
if(i != size)
|
||||
{
|
||||
printf("%d", node->val);
|
||||
node = (my_list*) linked_list_prev((linked_list_node_t *) node);
|
||||
return false;
|
||||
}
|
||||
|
||||
validate_list(list);
|
||||
printf("\n");
|
||||
return;
|
||||
node = linked_list_last(list);
|
||||
while(node != NULL && i >= 0)
|
||||
{
|
||||
my_list* enode = OBTAIN_STRUCT_ADDR(node, lnode, my_list);
|
||||
if(enode->val != val[i-1])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
i--;
|
||||
node = linked_list_prev(node);
|
||||
}
|
||||
|
||||
return i == 0;
|
||||
}
|
||||
|
||||
//void print_validate(linked_list_t *list)
|
||||
//{
|
||||
// my_list* node = (my_list*) linked_list_first(list);
|
||||
// while(node != NULL)
|
||||
// {
|
||||
// printf("%d", node->val);
|
||||
// node = (my_list*) linked_list_next((linked_list_node_t *) node);
|
||||
// }
|
||||
//
|
||||
// printf("======");
|
||||
// node = (my_list*) linked_list_last(list);
|
||||
// while(node != NULL)
|
||||
// {
|
||||
// printf("%d", node->val);
|
||||
// node = (my_list*) linked_list_prev((linked_list_node_t *) node);
|
||||
// }
|
||||
//
|
||||
// validate_list(list);
|
||||
// printf("\n");
|
||||
// return;
|
||||
//}
|
||||
|
||||
void insert_val(linked_list_t* list, int index, int val)
|
||||
{
|
||||
my_list *a = (my_list*)malloc(sizeof(my_list));
|
||||
|
@ -76,7 +129,8 @@ void insert_test_beginning()
|
|||
insert_val(&list, 0, 3);
|
||||
|
||||
// 3210==0123
|
||||
print_validate(&list);
|
||||
int val[4] = {3,2,1,0};
|
||||
printf("insert_test_beginning %s\n",assert_list(&list, val, 4) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void insert_test_middle()
|
||||
|
@ -92,8 +146,8 @@ void insert_test_middle()
|
|||
insert_val(&list, 1, 5);
|
||||
insert_val(&list, 2, 6);
|
||||
|
||||
// 256410=====014652
|
||||
print_validate(&list);
|
||||
int val[] = {2,5,6,4,1,0};
|
||||
printf("insert_test_middle %s\n",assert_list(&list, val, 6) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void insert_test_end()
|
||||
|
@ -106,8 +160,8 @@ void insert_test_end()
|
|||
insert_val(&list, 2, 2);
|
||||
insert_val(&list, 3, 3);
|
||||
|
||||
// 0123=====3210
|
||||
print_validate(&list);
|
||||
int val[] = {0,1,2,3};
|
||||
printf("insert_test_end %s\n",assert_list(&list, val, 4) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void insert_test_invalid()
|
||||
|
@ -135,8 +189,8 @@ void insert_test_invalid()
|
|||
linked_list_insert_ref(NULL, list.head, list.tail);
|
||||
linked_list_insert_ref(&list, list.head, NULL);
|
||||
|
||||
// 0123=====3210
|
||||
print_validate(&list);
|
||||
int val[] = {0,1,2,3};
|
||||
printf("insert_test_invalid %s\n",assert_list(&list, val, 4) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,7 +207,8 @@ void remove_test_beginning()
|
|||
linked_list_remove_idx(&list, 0);
|
||||
|
||||
// 10==01
|
||||
print_validate(&list);
|
||||
int val[] = {1,0};
|
||||
printf("remove_test_beginning %s\n",assert_list(&list, val, 2) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void remove_test_middle()
|
||||
|
@ -173,7 +228,8 @@ void remove_test_middle()
|
|||
linked_list_remove_idx(&list, 2);
|
||||
|
||||
// 5310=====0135
|
||||
print_validate(&list);
|
||||
int val[] = {5,3,1,0};
|
||||
printf("remove_test_middle %s\n",assert_list(&list, val, 4) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void remove_test_end()
|
||||
|
@ -189,17 +245,16 @@ void remove_test_end()
|
|||
linked_list_remove_idx(&list, 3);
|
||||
linked_list_remove_idx(&list, 2);
|
||||
|
||||
// 01=====10
|
||||
print_validate(&list);
|
||||
int val[] = {0,1};
|
||||
printf("remove_test_all %s\n",assert_list(&list, val, 2) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void remove_test_all()
|
||||
{
|
||||
bool result = true;
|
||||
linked_list_t list;
|
||||
linked_list_init(&list);
|
||||
|
||||
printf("remove all:");
|
||||
|
||||
insert_val(&list, 0, 0);
|
||||
insert_val(&list, 1, 1);
|
||||
insert_val(&list, 2, 2);
|
||||
|
@ -210,8 +265,7 @@ void remove_test_all()
|
|||
linked_list_remove_idx(&list, 0);
|
||||
linked_list_remove_idx(&list, 0);
|
||||
|
||||
printf(linked_list_size(&list) == 0 ? " YEAH" : " NO");
|
||||
validate_list(&list);
|
||||
result = result && assert_list(&list, NULL, 0);
|
||||
|
||||
insert_val(&list, 0, 0);
|
||||
insert_val(&list, 1, 1);
|
||||
|
@ -223,8 +277,7 @@ void remove_test_all()
|
|||
linked_list_remove_idx(&list, 1);
|
||||
linked_list_remove_idx(&list, 0);
|
||||
|
||||
printf(linked_list_size(&list) == 0 ? " YEAH" : " NO");
|
||||
validate_list(&list);
|
||||
result = result && assert_list(&list, NULL, 0);
|
||||
|
||||
insert_val(&list, 0, 0);
|
||||
insert_val(&list, 1, 1);
|
||||
|
@ -236,10 +289,9 @@ void remove_test_all()
|
|||
linked_list_remove_idx(&list, 1);
|
||||
linked_list_remove_idx(&list, 0);
|
||||
|
||||
printf(linked_list_size(&list) == 0 ? " YEAH" : " NO");
|
||||
validate_list(&list);
|
||||
result = result && assert_list(&list, NULL, 0);
|
||||
|
||||
printf("\n");
|
||||
printf("remove_test_end %s\n",result ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void remove_test_invalid()
|
||||
|
@ -268,11 +320,13 @@ void remove_test_invalid()
|
|||
linked_list_remove_ref(&list, NULL);
|
||||
|
||||
// 0123=====3210
|
||||
print_validate(&list);
|
||||
int val[] = {0,1,2,3};
|
||||
printf("remove_test_invalid %s\n",assert_list(&list, val, 4) ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void size_test()
|
||||
{
|
||||
bool result = true;
|
||||
linked_list_t list;
|
||||
linked_list_init(&list);
|
||||
linked_list_t list2;
|
||||
|
@ -283,13 +337,15 @@ void size_test()
|
|||
insert_val(&list, 2, 2);
|
||||
insert_val(&list, 3, 3);
|
||||
|
||||
printf((linked_list_size(&list) == 4 && linked_list_size(&list2) == 0 && linked_list_size(NULL) == -1) ? "size: okay" : "size: oops");
|
||||
validate_list(&list);
|
||||
printf("\n");
|
||||
result = result && (linked_list_size(&list) == 4 && linked_list_size(&list2) == 0 && linked_list_size(NULL) == -1);
|
||||
int val[] = {0,1,2,3};
|
||||
result = result && assert_list(&list, val, 4);
|
||||
printf("size_test %s\n", result ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void push_pop_front_test()
|
||||
{
|
||||
bool result = true;
|
||||
linked_list_t list;
|
||||
linked_list_init(&list);
|
||||
|
||||
|
@ -299,23 +355,25 @@ void push_pop_front_test()
|
|||
push_front_val(&list, 4);
|
||||
|
||||
//4321==1234
|
||||
print_validate(&list);
|
||||
int val1[] = {4,3,2,1};
|
||||
result = result && assert_list(&list, val1, 4);
|
||||
|
||||
linked_list_pop_front(&list);
|
||||
//321==123
|
||||
print_validate(&list);
|
||||
int val2[] = {3,2,1};
|
||||
result = result && assert_list(&list, val2, 3);
|
||||
|
||||
linked_list_pop_front(&list);
|
||||
linked_list_pop_front(&list);
|
||||
linked_list_pop_front(&list);
|
||||
|
||||
printf((linked_list_size(&list) == 0 )? " YEAH" : " NO");
|
||||
validate_list(&list);
|
||||
printf("\n");
|
||||
result = result && assert_list(&list, NULL, 0);
|
||||
printf("push_pop_front_test %s\n", result ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
void push_pop_back_test()
|
||||
{
|
||||
bool result = true;
|
||||
linked_list_t list;
|
||||
linked_list_init(&list);
|
||||
|
||||
|
@ -325,19 +383,56 @@ void push_pop_back_test()
|
|||
push_back_val(&list, 4);
|
||||
|
||||
//1234==4321
|
||||
print_validate(&list);
|
||||
int val1[] = {1,2,3,4};
|
||||
result = result && assert_list(&list, val1, 4);
|
||||
|
||||
linked_list_pop_back(&list);
|
||||
//123==321
|
||||
print_validate(&list);
|
||||
int val2[] = {1,2,3};
|
||||
result = result && assert_list(&list, val2, 3);
|
||||
|
||||
linked_list_pop_back(&list);
|
||||
linked_list_pop_back(&list);
|
||||
linked_list_pop_back(&list);
|
||||
|
||||
printf((linked_list_size(&list) == 0 )? " YEAH" : " NO");
|
||||
validate_list(&list);
|
||||
printf("\n");
|
||||
result = result && assert_list(&list, NULL, 0);
|
||||
printf("push_pop_back_test %s\n", result ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
bool equals(linked_list_node_t* a, linked_list_node_t* b)
|
||||
{
|
||||
return (int)a == OBTAIN_STRUCT_ADDR(b, lnode, my_list)->val;
|
||||
}
|
||||
|
||||
void search_test()
|
||||
{
|
||||
bool result = true;
|
||||
linked_list_t list;
|
||||
linked_list_init(&list);
|
||||
|
||||
push_back_val(&list, 1);
|
||||
push_back_val(&list, 2);
|
||||
push_back_val(&list, 3);
|
||||
push_back_val(&list, 4);
|
||||
|
||||
int val1[] = {1,2,3,4};
|
||||
result = result && assert_list(&list, val1, 4);
|
||||
|
||||
result = result && (linked_list_search(&list, 4 ,equals) == 3);
|
||||
result = result && (linked_list_search(&list, 3 ,equals) == 2);
|
||||
result = result && (linked_list_search(&list, 2 ,equals) == 1);
|
||||
result = result && (linked_list_search(&list, 1 ,equals) == 0);
|
||||
|
||||
result = result && (linked_list_search(&list, NULL ,equals) == -1);
|
||||
result = result && (linked_list_search(NULL, 1 ,equals) == -1);
|
||||
|
||||
linked_list_node_t* node = linked_list_get(&list, 1);
|
||||
result = result && (linked_list_search(&list, node , NULL) == 1);
|
||||
|
||||
|
||||
result = result && assert_list(&list, val1, 4);
|
||||
|
||||
printf("search_test %s\n", result ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
|
||||
|
@ -360,6 +455,8 @@ int main(void)
|
|||
push_pop_front_test();
|
||||
push_pop_back_test();
|
||||
|
||||
search_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
3210======0123 good
|
||||
256410======014652 good
|
||||
0123======3210 good
|
||||
0123======3210 good
|
||||
10======01 good
|
||||
5310======0135 good
|
||||
01======10 good
|
||||
0123======3210 good
|
||||
size: okay good
|
||||
remove all: YEAH good YEAH good YEAH good
|
||||
4321======1234 good
|
||||
321======123 good
|
||||
YEAH good
|
||||
1234======4321 good
|
||||
123======321 good
|
||||
YEAH good
|
|
@ -10,6 +10,69 @@ static void SAPI _init_linked_list_node(linked_list_node_t *node)
|
|||
return;
|
||||
}
|
||||
|
||||
static void SAPI _append_node(linked_list_node_t *target, linked_list_node_t *node)
|
||||
{
|
||||
if(target == NULL || node == NULL)
|
||||
return;
|
||||
|
||||
linked_list_node_t* next = target->next;
|
||||
// update the next node
|
||||
if(next != NULL)
|
||||
{
|
||||
next->prev = node;
|
||||
}
|
||||
|
||||
// update the target node
|
||||
target->next = node;
|
||||
|
||||
// update the node itself
|
||||
node->prev = target;
|
||||
node->next = next;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// link target with node, suppose target is in the current list
|
||||
static void SAPI _prepend_node(linked_list_node_t *target, linked_list_node_t *node)
|
||||
{
|
||||
if(target == NULL || node == NULL)
|
||||
return;
|
||||
|
||||
linked_list_node_t* prev = target->prev;
|
||||
// update the prev node
|
||||
if(prev != NULL)
|
||||
{
|
||||
prev->next = node;
|
||||
}
|
||||
|
||||
// update the target node
|
||||
target->prev = node;
|
||||
|
||||
// update the node itself
|
||||
node->next = target;
|
||||
node->prev = prev;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void SAPI _unlink_node(linked_list_node_t* node)
|
||||
{
|
||||
if(node == NULL)
|
||||
return;
|
||||
|
||||
if(node->prev != NULL)
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
|
||||
if(node->next != NULL)
|
||||
{
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void SAPI linked_list_init(linked_list_t *list)
|
||||
{
|
||||
if (list != NULL)
|
||||
|
@ -20,14 +83,14 @@ void SAPI linked_list_init(linked_list_t *list)
|
|||
return;
|
||||
}
|
||||
|
||||
int SAPI linked_list_size(linked_list_t *list)
|
||||
int32_t SAPI linked_list_size(linked_list_t *list)
|
||||
{
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
if (list->head == NULL)
|
||||
return 0;
|
||||
|
||||
int size = 1;
|
||||
int32_t size = 1;
|
||||
linked_list_node_t *cur_node = list->head;
|
||||
linked_list_node_t *tail = list->tail;
|
||||
while ((cur_node != tail) && ((cur_node = cur_node->next) != NULL))
|
||||
|
@ -85,47 +148,34 @@ void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_node_t *prev_n
|
|||
if (prev_node == NULL)
|
||||
{
|
||||
// if prev_node is NULL, then we are inserting to the head
|
||||
if (list->head == NULL)
|
||||
|
||||
// linked node with list->head
|
||||
_prepend_node(list->head, node);
|
||||
|
||||
if (list->tail == NULL)
|
||||
{
|
||||
// if the list is empty
|
||||
list->head = node;
|
||||
// if the list is empty, we assign list->tail to node too
|
||||
list->tail = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not empty
|
||||
linked_list_node_t *cur_node = list->head;
|
||||
node->next = cur_node;
|
||||
node->prev = cur_node->prev;
|
||||
cur_node->prev = node;
|
||||
list->head = node;
|
||||
}
|
||||
|
||||
list->head = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if prev_node is not NULL, we are inserting to the middle or the end
|
||||
if (prev_node->next != NULL)
|
||||
{
|
||||
// if not the end
|
||||
linked_list_node_t *next_node = prev_node->next;
|
||||
|
||||
// add to the chain
|
||||
next_node->prev = node;
|
||||
prev_node->next = node;
|
||||
node->prev = prev_node;
|
||||
node->next = next_node;
|
||||
}
|
||||
else
|
||||
// linked node with the prev_node
|
||||
_append_node(prev_node, node);
|
||||
|
||||
if (node->next == NULL)
|
||||
{
|
||||
// we are inserting at the end of the list
|
||||
prev_node->next = node;
|
||||
node->prev = prev_node;
|
||||
// if it's the end
|
||||
list->tail = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SAPI linked_list_insert_idx(linked_list_t *list, int index, linked_list_node_t *node)
|
||||
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_node_t *node)
|
||||
{
|
||||
if (list == NULL || index < 0 || node == NULL)
|
||||
return;
|
||||
|
@ -147,7 +197,7 @@ void SAPI linked_list_insert_idx(linked_list_t *list, int index, linked_list_nod
|
|||
return;
|
||||
}
|
||||
|
||||
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int index)
|
||||
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index)
|
||||
{
|
||||
if (list == NULL || index < 0)
|
||||
return NULL;
|
||||
|
@ -164,36 +214,16 @@ linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list
|
|||
if (list == NULL || node == NULL)
|
||||
return NULL;
|
||||
|
||||
if (node->next == NULL && node->prev == NULL)
|
||||
_unlink_node(node);
|
||||
|
||||
if(node->next == NULL)
|
||||
{
|
||||
// the only node
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->tail = node->prev;
|
||||
}
|
||||
|
||||
if (node->next != NULL)
|
||||
if(node->prev == NULL)
|
||||
{
|
||||
// there is something after node
|
||||
linked_list_node_t *next_node = node->next;
|
||||
next_node->prev = node->prev;
|
||||
|
||||
if (node->prev == NULL)
|
||||
{
|
||||
// first element
|
||||
list->head = next_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (node->prev != NULL)
|
||||
{
|
||||
// there is something before the node
|
||||
linked_list_node_t *prev_node = node->prev;
|
||||
prev_node->next = node->next;
|
||||
if (node->next == NULL)
|
||||
{
|
||||
// last element
|
||||
list->tail = prev_node;
|
||||
}
|
||||
list->head = node->next;
|
||||
}
|
||||
|
||||
_init_linked_list_node(node);
|
||||
|
@ -201,7 +231,7 @@ linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list
|
|||
return node;
|
||||
}
|
||||
|
||||
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int index)
|
||||
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int32_t index)
|
||||
{
|
||||
if (list == NULL || index < 0 || list->head == NULL)
|
||||
return NULL;
|
||||
|
@ -248,6 +278,37 @@ linked_list_node_t *SAPI linked_list_last(linked_list_t *list)
|
|||
return result;
|
||||
}
|
||||
|
||||
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_node_t *target, bool (*equals)(linked_list_node_t *, linked_list_node_t *))
|
||||
{
|
||||
if(list == NULL || target == NULL)
|
||||
return -1;
|
||||
int32_t result = 0;
|
||||
linked_list_node_t* node = linked_list_first(list);
|
||||
while(node != NULL)
|
||||
{
|
||||
if(equals !=NULL)
|
||||
{
|
||||
if (equals(target, node))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(target->next == node->next && target->prev == node->prev)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result++;
|
||||
node = linked_list_next(node);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,15 +27,15 @@ linked_list_node_t *SAPI linked_list_pop_front(linked_list_t *list);
|
|||
|
||||
linked_list_node_t *SAPI linked_list_pop_back(linked_list_t *list);
|
||||
|
||||
void SAPI linked_list_insert_idx(linked_list_t *list, int index, linked_list_node_t *node);
|
||||
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_node_t *node);
|
||||
|
||||
void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_node_t *prev_node, linked_list_node_t *node);
|
||||
|
||||
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int index);
|
||||
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index);
|
||||
|
||||
linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list_node_t *node);
|
||||
|
||||
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int index);
|
||||
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int32_t index);
|
||||
|
||||
linked_list_node_t *SAPI linked_list_next(linked_list_node_t *node);
|
||||
|
||||
|
@ -45,4 +45,8 @@ linked_list_node_t *SAPI linked_list_first(linked_list_t *list);
|
|||
|
||||
linked_list_node_t *SAPI linked_list_last(linked_list_t *list);
|
||||
|
||||
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_node_t* target, bool (*equals)(linked_list_node_t*, linked_list_node_t*));
|
||||
|
||||
#define OBTAIN_STRUCT_ADDR(member_addr, member_name, struct_name) ((struct_name*)((char*)(member_addr)-(char*)(&(((struct_name*)0)->member_name))))
|
||||
|
||||
#endif
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include "type.h"
|
||||
|
||||
#define SAPI __attribute__((sysv_abi))
|
||||
|
@ -48,6 +49,6 @@ static inline uint32_t seg_selector(uint32_t index, uint32_t rpl)
|
|||
return (index << 3) + rpl;
|
||||
}
|
||||
|
||||
#define OBTAIN_STRUCT_ADDR(member_addr, member_name, struct_name) ((struct_name*)((char*)(member_addr)-(uint64_t)(&(((struct_name*)0)->member_name))))
|
||||
#define OBTAIN_STRUCT_ADDR(member_addr, member_name, struct_name) ((struct_name*)((void*)(member_addr)-(void*)(&(((struct_name*)0)->member_name))))
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue