289 lines
7.2 KiB
C
289 lines
7.2 KiB
C
/*----------------------------------------------------------------------------
|
|
* Copyright (c) TJD Technologies Co., Ltd. 2020. All rights reserved.
|
|
*
|
|
* Description: sys_slist.h
|
|
*
|
|
* Author: saimen
|
|
*
|
|
* Create: 2024-4-24
|
|
*--------------------------------------------------------------------------*/
|
|
//lib
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
//user
|
|
#include "sys_slist.h"
|
|
|
|
/**********************************************************************************************************************
|
|
* PUBLIC FUNCTIONS
|
|
*/
|
|
void tjd_sys_slist_create(tjd_sys_slist_t *list)
|
|
{
|
|
list->next = NULL;
|
|
}
|
|
|
|
void tjd_sys_slist_destroy(tjd_sys_slist_t *list, slist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL)
|
|
return;
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
prev_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
prev_item->next = NULL;
|
|
if (free_handle) {
|
|
(*free_handle)(prev_item, cntx);
|
|
}
|
|
}
|
|
list->next = NULL;
|
|
}
|
|
|
|
void tjd_sys_slist_item_init(tjd_sys_slist_item_t *item)
|
|
{
|
|
item->next = NULL;
|
|
}
|
|
|
|
void tjd_sys_slist_append(tjd_sys_slist_t *list, tjd_sys_slist_item_t *item)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (item == NULL || list == NULL || list == item) {
|
|
return;
|
|
}
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item != NULL) {
|
|
prev_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
}
|
|
prev_item->next = item;
|
|
}
|
|
|
|
void tjd_sys_slist_prepend(tjd_sys_slist_t *list, tjd_sys_slist_item_t *item)
|
|
{
|
|
if (item == NULL || list == NULL || list == item) {
|
|
return;
|
|
}
|
|
|
|
item->next = list->next;
|
|
list->next = item;
|
|
}
|
|
|
|
void *tjd_sys_slist_first(tjd_sys_slist_t *list)
|
|
{
|
|
if (list == NULL)
|
|
return NULL;
|
|
|
|
return list->next;
|
|
}
|
|
|
|
void *tjd_sys_slist_last(tjd_sys_slist_t *list)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item != NULL) {
|
|
prev_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
}
|
|
if (prev_item && prev_item != list) {
|
|
return prev_item;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
uint32_t tjd_sys_slist_size(tjd_sys_slist_t *list)
|
|
{
|
|
uint32_t ret = 0;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL)
|
|
return ret;
|
|
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
ret++;
|
|
cur_item = cur_item->next;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void tjd_sys_slist_sort(tjd_sys_slist_t *list, uint32_t ascend,
|
|
slist_cmpr_handle_t cmpr_handle, slist_swap_handle_t swap_handle)
|
|
{
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
tjd_sys_slist_item_t *marker_item = NULL;
|
|
tjd_sys_slist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL || cmpr_handle == NULL || swap_handle == NULL)
|
|
return ;
|
|
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
marker_item = cur_item;
|
|
next_item = cur_item->next;
|
|
while (next_item) {
|
|
if (ascend) {
|
|
if ((*cmpr_handle)(marker_item, next_item) < 0) {
|
|
marker_item = next_item;
|
|
}
|
|
} else {
|
|
if ((*cmpr_handle)(marker_item, next_item) > 0) {
|
|
marker_item = next_item;
|
|
}
|
|
}
|
|
next_item = next_item->next;
|
|
}
|
|
(*swap_handle)(marker_item, cur_item);
|
|
cur_item = cur_item->next;
|
|
}
|
|
}
|
|
|
|
void *tjd_sys_slist_find(tjd_sys_slist_t *list,
|
|
tjd_sys_slist_item_t *item, slist_cmpr_handle_t cmpr_handle)
|
|
{
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL || cmpr_handle == NULL)
|
|
return NULL;
|
|
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
if (cmpr_handle(cur_item, item) == 0) {
|
|
return cur_item;
|
|
}
|
|
cur_item = cur_item->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void *tjd_sys_slist_find_pre_item(tjd_sys_slist_t *list,
|
|
tjd_sys_slist_item_t *item, slist_cmpr_handle_t cmpr_handle)
|
|
{
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
tjd_sys_slist_item_t *pre_item = NULL;
|
|
|
|
if (list == NULL || cmpr_handle == NULL)
|
|
return NULL;
|
|
|
|
pre_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
if (cmpr_handle(cur_item, item) == 0) {
|
|
return pre_item;
|
|
}
|
|
pre_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void tjd_sys_slist_remove_first(tjd_sys_slist_t *list,
|
|
slist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL)
|
|
return;
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
if (cur_item) {
|
|
prev_item->next = cur_item->next;
|
|
cur_item->next = NULL;
|
|
|
|
if (free_handle) {
|
|
(*free_handle)(cur_item, cntx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tjd_sys_slist_remove_last(tjd_sys_slist_t *list,
|
|
slist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL)
|
|
return;
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item) {
|
|
if (cur_item->next == NULL) {
|
|
prev_item->next = NULL;
|
|
cur_item->next = NULL;
|
|
|
|
if (free_handle) {
|
|
(*free_handle)(cur_item, cntx);
|
|
}
|
|
break;
|
|
}
|
|
prev_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
}
|
|
}
|
|
|
|
bool tjd_sys_slist_remove_item_ret(tjd_sys_slist_t *list, tjd_sys_slist_item_t *item,
|
|
slist_cmpr_handle_t cmpr_handle, slist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_slist_item_t *prev_item = NULL;
|
|
tjd_sys_slist_item_t *cur_item = NULL;
|
|
|
|
if (list == NULL || item == NULL)
|
|
return false;
|
|
|
|
prev_item = list;
|
|
cur_item = list->next;
|
|
while (cur_item != NULL) {
|
|
if (cmpr_handle) {
|
|
if ((*cmpr_handle)(cur_item, item) == 0) {
|
|
break;
|
|
}
|
|
} else if (cur_item == item) {
|
|
break;
|
|
}
|
|
prev_item = cur_item;
|
|
cur_item = cur_item->next;
|
|
}
|
|
if (cur_item) {
|
|
prev_item->next = cur_item->next;
|
|
cur_item->next = NULL;
|
|
|
|
if (free_handle) {
|
|
(*free_handle)(cur_item, cntx);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void tjd_sys_slist_remove_item(tjd_sys_slist_t *list, tjd_sys_slist_item_t *item,
|
|
slist_cmpr_handle_t cmpr_handle, slist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_slist_remove_item_ret(list, item, cmpr_handle, free_handle, cntx);
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* EOF
|
|
*/
|
|
/** @} */
|
|
|
|
|