Files
checker_gen1/source/soft/list.c

589 lines
10 KiB
C
Raw Normal View History

2023-06-10 11:52:00 +08:00
#include "list.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "board.h"
#include "mystdlib.h"
#include "debug.h"
#include "bytearray.h"
#include "rtthread.h"
#define LIST_APPEND_SKIP 10
typedef struct{
int32_t next;
int32_t prev;
uint32_t data[0];
}list_node_def;
struct _list_def{
int32_t all;
int32_t used;
int32_t block_size;
int32_t block_size4;
rt_mutex_t mutex;
int32_t head;
int32_t tail;
sub_fun_def sub;
del_fun_def del;
str_fun_def str;
uint32_t data[0];
};
//#define list_enter_mutex(l)\
// rt_mutex_take((l)->mutex,RT_WAITING_FOREVER)
//
//#define list_exit_mutex(l)\
// rt_mutex_release((l)->mutex)
#define list_enter_mutex(l)
#define list_exit_mutex(l)
#define rt_mutex_create(...) 0
#define rt_mutex_delete(l)
list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str)
{
static uint16_t count=0;
char s1[16]={0};
sprintf(s1,"list_mut#%d",count);
int size=0;
int block_size4;
list_def *l;
size+=sizeof(list_def);
// 4字节对齐
block_size4=((block_size+3)/4)*4;
size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP;
l=malloc(size);
param_check(l);
l->all=LIST_APPEND_SKIP;
l->used=0;
l->block_size=block_size;
l->block_size4=block_size4;
l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO);
l->head=-1;
l->tail=-1;
l->sub=sub;
l->del=del;
l->str=str;
// 初始化列表
list_node_def *node;
node=(list_node_def *)l->data;
for(int i=0;i<l->all;i++)
{
node->next=-1;
node->prev=-1;
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
}
count++;
return l;
}
// 对于数据里有指针数据的成员,需要提供del函数
void _list_delete(list_def **l)
{
param_check(l);
param_check(*l);
list_enter_mutex(*l);
if((*l)->del)
{
for(int i=0;i<(*l)->used;i++)
{
(*l)->del(list_get(*l,i));
}
}
list_exit_mutex(*l);
rt_mutex_delete((*l)->mutex);
free(*l);
*l=0;
}
int list_block_size4(list_def *l)
{
param_check(l);
return l->block_size4;
}
//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
//{
// for(int i=0;i<num_4byte;i++)
// {
// dst[i]=src[i];
// }
//}
static list_def *list_expend(list_def *l)
{
int size=0;
int cpysize=0;
list_def *r;
size+=sizeof(list_def);
size+=(sizeof(list_node_def)+l->block_size4)*(l->all);
cpysize=size;
size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP);
r=malloc(size);
param_check(r);
cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4);
// 初始化列表
list_node_def *node;
node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4));
for(int i=0;i<LIST_APPEND_SKIP;i++)
{
node->next=-1;
node->prev=-1;
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4);
}
r->all+=LIST_APPEND_SKIP;
free(l);
return r;
}
// 查找一个未使用的节点
static list_node_def *list_unused_node(list_def *l,int *index)
{
list_node_def *node=0;
node=(list_node_def *)l->data;
for(int i=0;i<l->all;i++)
{
if((node->next==-1)&&(node->prev==-1)){
if(index) *index=i;
return node;
}
node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
}
return node;
}
// 取得指定序号的节点
static list_node_def *list_node(list_def *l,int index)
{
list_node_def *node;
param_check(index>=0&&index<l->all);
node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4));
return node;
}
// 取得节点的物理索引
static int list_phy_index(list_def *l,list_node_def *n)
{
return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4);
}
/*
// 改为统一使用insert函数
list_def *list_append(list_def **l,void *data)
{
param_check(l);
param_check(*l);
list_def *r=*l;
if((*l)->used>=(*l)->all)
{
r=list_expend(*l);
}
list_node_def *node;
int index;
node=list_unused_node(r,&index);
param_check(node);
memcpy(node->data,data,r->block_size);
if(r->head==-1&&r->tail==-1)
{
r->head=index;
r->tail=index;
node->next=index;
node->prev=index;
}
else if(r->head!=-1&&r->tail!=-1)
{
node->prev=r->tail;
node->next=list_node(r,r->tail)->next;
list_node(r,r->tail)->next=index;
r->tail=index;
list_node(r,r->head)->prev=index;
}
else
{
param_check(0);
}
r->used++;
*l=r;
return r;
}
*/
// 返回指定index的已使用节点
static list_node_def *list_used_node(list_def *l,int index)
{
list_node_def *node=0;
if(index>l->used/2)
{
index=l->used-1-index;
node=list_node(l,l->tail);
for(int i=0;i<index;i++)
{
node=list_node(l,node->prev);
}
}
else{
node=list_node(l,l->head);
for(int i=0;i<index;i++)
{
node=list_node(l,node->next);
}
}
return node;
}
// 获取第index项数据,不删除
// index支持负数-1表示最后一项
// 返回数据引用
void *list_get(list_def *l,int index)
{
param_check(l);
void *ret=0;
list_enter_mutex(l);
list_node_def *node;
if(index<0) index=l->used+index;
if((index>=0&&index<l->used)==0)
ret=0;
else{
node=list_used_node(l,index);
param_check(node);
ret=node->data;
}
list_exit_mutex(l);
return ret;
}
// 删除第index项数据
// index支持负数-1表示最后一项
void list_remove(list_def *l,int index)
{
param_check(l);
list_node_def *node;
int phy_index;
if(index<0) index=l->used+index;
list_enter_mutex(l);
if((index>=0&&index<l->used)){
node=list_used_node(l,index);
param_check(node);
phy_index=list_phy_index(l,node);
if(l->used==1)
{
l->head=-1;
l->tail=-1;
}
else
{
if(l->head==phy_index)
{
l->head=node->next;
}
if(l->tail==phy_index)
{
l->tail=node->prev;
}
list_node(l,node->prev)->next=node->next;
list_node(l,node->next)->prev=node->prev;
}
node->next=-1;
node->prev=-1;
if(l->del) l->del(node->data);
l->used--;
}
list_enter_mutex(l);
}
// 获取指定index的数据随后删除
// 返回数据的临时指针
// 对于存在动态指针的对象由于take之后会自动删除take操作会出现野指针
// 建议使用list_get + list_remove的方式代替list_take
void *list_take(list_def *l,int index)
{
param_check(l);
void *p;
p=list_get(l,index);
void *t=tmalloc(l->block_size);
param_check(t);
memcpy(t,p,l->block_size);
list_remove(l,index);
return t;
}
// 清空
void list_clear(list_def *l)
{
param_check(l);
list_enter_mutex(l);
while(l->used>0)
{
list_remove(l,0);
}
list_exit_mutex(l);
}
int list_length(list_def *l)
{
param_check(l);
return l->used;
}
// 在指定位置插入
// index为节点插入之后所在的位置
list_def *_list_insert(list_def **l,void *data,int index)
{
param_check(l);
param_check(*l);
list_enter_mutex(*l);
if(index<0) index=(*l)->used+index+1;
if((index>=0&&index<=(*l)->used)==0){
list_exit_mutex(*l);
return *l;
}
list_def *r=*l;
if((*l)->used>=(*l)->all)
{
r=list_expend(*l);
}
list_node_def *node;
int phy_index;
node=list_unused_node(r,&phy_index);
param_check(node);
memcpy(node->data,data,r->block_size);
if(r->head==-1&&r->tail==-1)
{
r->head=phy_index;
r->tail=phy_index;
node->next=phy_index;
node->prev=phy_index;
}
else if(r->head!=-1&&r->tail!=-1)
{
list_node_def *n;
int n_phy_index;
if(index<r->used)
{
n=list_used_node(r,index);
n_phy_index=list_phy_index(r,n);
list_node(r,n->prev)->next=phy_index;
node->prev=n->prev;
node->next=n_phy_index;
n->prev=phy_index;
if(index==0)
{
r->head=phy_index;
}
}
else
{
node->prev=r->tail;
node->next=list_node(r,r->tail)->next;
list_node(r,r->tail)->next=phy_index;
r->tail=index;
list_node(r,r->head)->prev=phy_index;
}
}
else
{
param_check(0);
}
r->used++;
*l=r;
list_exit_mutex(*l);
return r;
}
void list_sort(list_def *l)
{
param_check(l);
list_enter_mutex(l);
if(l->sub){
_list_sort(l,l->sub);
}
else{
DBG_WARN("obj->sub fun is null.");
}
list_exit_mutex(l);
}
// 在列表内返回1不在返回0
int list_contains(list_def *l,void *d)
{
param_check(l);
list_enter_mutex(l);
if(l->sub)
{
for(int i=0;i<list_length(l);i++)
{
if(l->sub(list_get(l,i),d)==0){
list_exit_mutex(l);
return 1;
}
}
}
else{
DBG_WARN("obj->sub fun is null.");
}
list_exit_mutex(l);
return 0;
}
// 交换两个位置
void list_swap(list_def *l,int index_a,int index_b)
{
param_check(l);
list_enter_mutex(l);
void *a_=list_get(l,index_a);
void *b_=list_get(l,index_b);
void *t_=0;
if(a_&&b_)
{
t_=calloc(1,sizeof(l->block_size4));
cpy4byte(t_,a_,l->block_size4/4);
cpy4byte(a_,b_,l->block_size4/4);
cpy4byte(b_,t_,l->block_size4/4);
free(t_);
}
list_exit_mutex(l);
}
// 向后循环移动
void list_shift(list_def *l)
{
param_check(l);
list_enter_mutex(l);
if(l->used>0){
l->head=list_node(l,l->head)->next;
l->tail=list_node(l,l->tail)->next;
}
list_exit_mutex(l);
}
// 输出打印字符串
char *list_string(list_def *l)
{
param_check(l);
list_enter_mutex(l);
array_def *d=arr_creat();
param_check(d);
int len=0;
char *s=0;
arr_append(d,'(');
if(l->str)
{
for(int i=0;i<list_length(l);i++)
{
s=l->str(list_get(l,i));
len=strlen(s);
arr_appends(d,s,len);
free(s);
arr_append(d,',');
arr_append(d,' ');
}
}
arr_append(d,')');
len=arr_length(d);
s=malloc(len+1);
param_check(s);
memcpy(s,arr_data(d),len);
arr_delete(d);
s[len]=0;
list_exit_mutex(l);
return s;
}
// int sub函数
int _list_int_sub(void *a,void *b)
{
return *(int *)a-*(int *)b;
}
// int 打印函数
char *_list_int_str(void *a)
{
char *s=malloc(20);
param_check(s);
sprintf(s,"%d",*(int *)a);
return s;
}
// str sub函数
int _list_str_sub(void *a,void *b)
{
char *a_=*(char **)a;
char *b_=*(char **)b;
return strcmp(a_,b_);
}
// str删除函数
int _list_str_del(void *d)
{
char **c=d;
if(*c) free(*c);
return 0;
}
// str 打印函数
char *_list_str_str(void *a)
{
char *a_=*(char **)a;
int len=strlen(a_);
char *s=malloc(len+1);
param_check(s);
memcpy(s,a_,len+1);
return s;
}
// 延迟删除,不需要修改指针
void _list_delete_later(list_def *l)
{
_list_delete(&l);
}