list.c
来自「SEAL是DOS 下的32位保护模式的GUI程序」· C语言 代码 · 共 516 行
C
516 行
/******************************************************************
* SEAL 2.0 *
* Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved. *
* *
* Web site: http://sealsystem.sourceforge.net/ *
* E-mail (current maintainer): orudge@users.sourceforge.net *
******************************************************************/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <seal.h>
//#include"object.h"
#include <list.h>
//#include<string.h>
p_list (*list_init) ( p_list o, void (*func_free)(void *), l_tag tag ) = &_list_init;
l_bool list_done ( p_list o )
{
p_item v = o->last;
while ( o->last ) {
o->remove_item(o, o->last);
};
o->last = NULL;
l_tag_cpy(o->tag, TAG_NONE);
o->func_free = NULL;
return true;
};
void list_copy_ctx ( p_list dst, p_list src )
{
p_item x = src->first(src);
p_item f = x;
if ( f )
do {
dst->insert_ex(dst, x->rec, x->func_free, x->tag);
x = x->next;
} while ( x != f );
};
/*
call function callback for each item in the list,
callback contains argument ob = (object f.e.), o->item = item of list,
ind what's indicator of process. This argument contains value of number of
items ( f.e. copied size )
if callback return false, for_each cycle is stoped
else go while all items are done
- return false, if some callback return false, else return true
*/
l_bool list_for_each_item ( p_list o, void *ob, l_int (*callback)(), l_dword *ind )
{
p_item x = o->first(o);
p_item f = x;
l_bool ok = true;
if ( f && callback )
do {
ok = callback(ob, x->rec, ind);
x = x->next;
} while ( ok && x != f );
return ok;
};
/*
call function callback for each item in the list,
callback contains argument ob, item and o->item = item of list,
ind what's indicator of process. This argument contains value of number of
items ( f.e. copied size )
if callback return false, for_each cycle is stoped
else go while all items are done
- return false, if some callback return false, else return true
*/
l_bool list_for_each_item_to_item ( p_list o, void *ob, void *item, l_int (*callback)(), l_dword *ind )
{
p_item x = o->first(o);
p_item f = x;
l_bool ok = true;
if ( f && callback )
do {
ok = callback(ob, item, x->rec, ind);
x = x->next;
} while ( ok && x != f );
return ok;
};
void *list_first_rec ( p_list o )
{
if ( o->last ) return o->last->next->rec;
return NULL;
};
p_item list_first ( p_list o )
{
if ( o->last ) return o->last->next;
return NULL;
};
p_item list_at_item ( p_list o, l_long index )
{
p_item v = o->first(o);
p_item f = v;
if ( v && index >= 0 )
do {
if ( !index ) return v;
v = v->next;
index--;
} while ( v != f );
return NULL;
};
void *list_at ( p_list o, l_long index )
{
p_item v = o->at_item(o, index);
if ( v ) return v->rec;
return NULL;
};
l_long list_index_of ( p_list o, void *rec )
{
p_item v = o->first(o);
p_item f = v;
l_long index = 0;
if ( v && rec )
do {
if ( v->rec == rec ) return index;
v = v->next;
index++;
} while ( v != f );
return -1;
};
l_long list_index_of_item ( p_list o, p_item item )
{
p_item v = o->first(o);
p_item f = v;
l_long index = 0;
if ( v && item )
do {
if ( v == item ) return index;
v = v->next;
index++;
} while ( v != f );
return -1;
};
p_item list_find_rec ( p_list o, void *rec )
{
p_item v = o->first(o);
p_item f = v;
if ( v && rec )
do {
if ( v->rec == rec ) return v;
v = v->next;
} while ( v != f );
return NULL;
};
l_long list_insert_ex ( p_list o, void *rec, void (*f_free)(void *), l_tag tag )
{
p_item xp = o->find_rec(o, rec);
if ( !xp ) {
p_item v = (p_item)_malloc(sizeof(t_item));
if ( !v ) return -1;
clear_type(v, sizeof(t_item));
v->rec = rec;
v->func_free = f_free;
l_tag_cpy(v->tag, tag);
v->next = v;
v->prev = v;
if ( !o->last ) o->last = v;
else {
v->prev = o->last;
v->next = o->first(o);
o->first(o)->prev = v;
o->last->next = v;
o->last = v;
};
return o->index_of_item(o, v);
};
return o->index_of_item(o, xp);
};
l_long list_insert ( p_list o, void *rec )
{
return o->insert_ex(o, rec, o->func_free, o->tag);
};
l_long list_get_max_item ( p_list o )
{
return o->index_of_item(o, o->last);
};
void list_remove_index ( p_list o, l_long index )
{
p_item v = o->at_item(o, index);
o->remove_item(o, v);
};
void list_remove_item ( p_list o, p_item item )
{
if ( item ) {
p_item x = item->prev;
if ( o->last == item ) o->last = x;
if ( o->last == item ) o->last = NULL;
x->next = item->next;
item->next->prev = x;
item->next = NULL;
item->prev = NULL;
_free(item);
};
};
void list_free_index ( p_list o, l_long index )
{
p_item v = o->at_item(o, index);
o->free_item(o, v);
};
void list_free_item ( p_list o, p_item item )
{
if ( item ) {
if ( item->func_free ) item->func_free(item->rec);
else
if ( o->func_free ) o->func_free(item->rec);
o->remove_item(o, item);
};
};
void list_free_all ( p_list o ) {
//p_item v = o->last;
while ( o->last ) {
o->free_item(o, o->last);
};
o->last = NULL;
l_tag_cpy(o->tag, TAG_NONE);
o->func_free = NULL;
};
l_bool list_collect_by_name_from ( p_list o, p_item from, l_int rec_delta )
{
p_item f = o->first(o);
p_item m = from;
if ( !from ) from = m = f;
else from = m = from->next;
if ( from && m )
do {
from = m;
do {
if ( !l_tag_cmp(o->tag, DAT_TEXT) && from->rec && m->rec ) { /* it's structure */
struct s_t {
l_text s;
};
l_text str1 = ((struct s_t*)from->rec)->s;
l_text str2 = ((struct s_t*)m->rec)->s;
if ( str1 && str2 && stricmp(str1, str2) < 0 ) {
void *old = m->rec;
m->rec = from->rec;
from->rec = old;
};
} else { /* it's text */
l_text str1 = from->rec;
l_text str2 = m->rec;
if ( str1 && str2 && stricmp(str1, str2) < 0 ) {
void *old = m->rec;
m->rec = from;
from->rec = old;
};
};
from = from->next;
} while ( from != f );
m = m->next;
} while ( m != f );
return true;
};
void dispose_list ( p_list *o, l_bool freeitem )
{
if ( o && (*o) ) {
if ( freeitem )
(*o)->free_all(*o);
else
(*o)->done(*o);
_free(*o);
(*o) = NULL;
};
};
p_list _list_init ( p_list o, void (*func_free)(void *), l_tag tag )
{
if ( !o ) return NULL;
clear_type(o, sizeof(t_list));
o->func_free = func_free;
l_tag_cpy(o->tag, tag);
/* list's functions */
o->done = &list_done;
o->copy_ctx = &list_copy_ctx;
o->first_rec = &list_first_rec;
o->first = &list_first;
o->at_item = &list_at_item;
o->at = &list_at;
o->index_of = &list_index_of;
o->index_of_item = &list_index_of_item;
o->find_rec = &list_find_rec;
o->insert_ex = &list_insert_ex;
o->insert = &list_insert;
o->get_max_item = &list_get_max_item;
o->remove_index = &list_remove_index;
o->remove_item = &list_remove_item;
o->free_index = &list_free_index;
o->free_item = &list_free_item;
o->free_all = &list_free_all;
o->for_each_item = &list_for_each_item;
o->for_each_item_to_item = &list_for_each_item_to_item;
o->collect_by_name_from = &list_collect_by_name_from;
return o;
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?