mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-20 04:48:06 +01:00
removed list bag
This commit is contained in:
452
WINGs/baglist.c
452
WINGs/baglist.c
@@ -1,452 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WUtil.h"
|
||||
|
||||
|
||||
typedef struct W_Item {
|
||||
struct W_Item *next;
|
||||
struct W_Item *prev;
|
||||
void *data;
|
||||
int index;
|
||||
} W_Item;
|
||||
|
||||
|
||||
typedef struct W_ListBag {
|
||||
W_Item *first;
|
||||
W_Item *last;
|
||||
int count;
|
||||
} W_ListBag;
|
||||
|
||||
|
||||
|
||||
static int getItemCount(WMBag *self);
|
||||
static int appendBag(WMBag *self, WMBag *bag);
|
||||
static int putInBag(WMBag *self, void *item);
|
||||
static int insertInBag(WMBag *self, int index, void *item);
|
||||
static int removeFromBag(WMBag *bag, void *item);
|
||||
static int deleteFromBag(WMBag *bag, int index);
|
||||
static void *getFromBag(WMBag *bag, int index);
|
||||
static int countInBag(WMBag *bag, void *item);
|
||||
static int firstInBag(WMBag *bag, void *item);
|
||||
static void *replaceInBag(WMBag *bag, int index, void *item);
|
||||
static void sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
|
||||
static void emptyBag(WMBag *bag);
|
||||
static void freeBag(WMBag *bag);
|
||||
static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
|
||||
static int findInBag(WMBag *bag, int (*match)(void*));;
|
||||
static void *first(WMBag *bag, WMBagIterator *ptr);
|
||||
static void *last(WMBag *bag, WMBagIterator *ptr);
|
||||
static void *next(WMBag *bag, WMBagIterator *ptr);
|
||||
static void *previous(WMBag *bag, WMBagIterator *ptr);
|
||||
static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
|
||||
static int indexForIterator(WMBag *bag, WMBagIterator ptr);
|
||||
|
||||
|
||||
static W_BagFunctions bagFunctions = {
|
||||
getItemCount,
|
||||
appendBag,
|
||||
putInBag,
|
||||
insertInBag,
|
||||
removeFromBag,
|
||||
deleteFromBag,
|
||||
getFromBag,
|
||||
firstInBag,
|
||||
countInBag,
|
||||
replaceInBag,
|
||||
sortBag,
|
||||
emptyBag,
|
||||
freeBag,
|
||||
mapBag,
|
||||
findInBag,
|
||||
first,
|
||||
last,
|
||||
next,
|
||||
previous,
|
||||
iteratorAtIndex,
|
||||
indexForIterator
|
||||
};
|
||||
|
||||
|
||||
#define SELF ((W_ListBag*)self->data)
|
||||
|
||||
WMBag *WMCreateListBag(void)
|
||||
{
|
||||
return WMCreateListBagWithDestructor(NULL);
|
||||
}
|
||||
|
||||
|
||||
WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*))
|
||||
{
|
||||
WMBag *bag;
|
||||
|
||||
bag = wmalloc(sizeof(WMBag));
|
||||
|
||||
bag->data = wmalloc(sizeof(W_ListBag));
|
||||
memset(bag->data, 0, sizeof(W_ListBag));
|
||||
|
||||
bag->destructor = destructor;
|
||||
|
||||
bag->func = bagFunctions;
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
|
||||
static int getItemCount(WMBag *self)
|
||||
{
|
||||
return SELF->count;
|
||||
}
|
||||
|
||||
|
||||
static int appendBag(WMBag *self, WMBag *bag)
|
||||
{
|
||||
void *ptr;
|
||||
void *data;
|
||||
|
||||
for (data = first(bag, &ptr); data != NULL; data = next(bag, &ptr)) {
|
||||
if (!putInBag(self, data))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int putInBag(WMBag *self, void *item)
|
||||
{
|
||||
W_Item *ptr;
|
||||
|
||||
ptr = wmalloc(sizeof(W_Item));
|
||||
|
||||
ptr->next = NULL;
|
||||
ptr->prev = SELF->last;
|
||||
ptr->data = item;
|
||||
|
||||
SELF->count++;
|
||||
|
||||
if (SELF->last)
|
||||
SELF->last->next = ptr;
|
||||
else {
|
||||
SELF->last = ptr;
|
||||
SELF->first = ptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int insertInBag(WMBag *self, int index, void *item)
|
||||
{
|
||||
W_Item *tmp;
|
||||
W_Item *ptr;
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
if (index >= SELF->count) {
|
||||
return putInBag(self, item);
|
||||
}
|
||||
|
||||
ptr = wmalloc(sizeof(W_Item));
|
||||
|
||||
ptr->next = NULL;
|
||||
ptr->prev = NULL;
|
||||
ptr->data = item;
|
||||
|
||||
SELF->count++;
|
||||
|
||||
if (!SELF->first) {
|
||||
SELF->first = ptr;
|
||||
SELF->last = ptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
tmp = SELF->first;
|
||||
while (index-- && tmp->next)
|
||||
tmp = tmp->next;
|
||||
|
||||
if (tmp->prev) {
|
||||
tmp->prev->next = ptr;
|
||||
ptr->prev = tmp->prev;
|
||||
ptr->next = tmp;
|
||||
tmp->prev = ptr;
|
||||
} else {
|
||||
assert(SELF->first == tmp);
|
||||
|
||||
SELF->first->prev = ptr;
|
||||
ptr->next = SELF->first;
|
||||
|
||||
SELF->first = ptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int removeFromBag(WMBag *self, void *item)
|
||||
{
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr) {
|
||||
|
||||
if (ptr->data == item) {
|
||||
|
||||
SELF->count--;
|
||||
|
||||
if (self->destructor) {
|
||||
self->destructor(item);
|
||||
}
|
||||
if (ptr->next)
|
||||
ptr->next->prev = ptr->prev;
|
||||
if (ptr->prev)
|
||||
ptr->prev->next = ptr->next;
|
||||
|
||||
if (SELF->first == ptr)
|
||||
SELF->first = ptr->next;
|
||||
if (SELF->last == ptr)
|
||||
SELF->last = ptr->prev;
|
||||
|
||||
free(ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int deleteFromBag(WMBag *self, int index)
|
||||
{
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr && index--) {
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
if (ptr && index==0) {
|
||||
SELF->count--;
|
||||
if (self->destructor) {
|
||||
self->destructor(ptr->data);
|
||||
}
|
||||
if (ptr->next)
|
||||
ptr->next->prev = ptr->prev;
|
||||
if (ptr->prev)
|
||||
ptr->prev->next = ptr->next;
|
||||
|
||||
if (SELF->first == ptr)
|
||||
SELF->first = ptr->next;
|
||||
if (SELF->last == ptr)
|
||||
SELF->last = ptr->prev;
|
||||
|
||||
free(ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void *getFromBag(WMBag *self, int index)
|
||||
{
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
if (index < 0 || index > SELF->count)
|
||||
return NULL;
|
||||
|
||||
while (ptr && index--)
|
||||
ptr = ptr->next;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int firstInBag(WMBag *self, void *item)
|
||||
{
|
||||
int index = 0;
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr) {
|
||||
if (ptr->data == item)
|
||||
return index;
|
||||
index++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int countInBag(WMBag *self, void *item)
|
||||
{
|
||||
int count = 0;
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr) {
|
||||
if (ptr->data == item)
|
||||
count++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static void *replaceInBag(WMBag *self, int index, void *item)
|
||||
{
|
||||
void *old;
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr && index--)
|
||||
ptr = ptr->next;
|
||||
|
||||
if (!ptr || index!=0)
|
||||
return NULL;
|
||||
|
||||
old = ptr->data;
|
||||
|
||||
ptr->data = item;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void sortBag(WMBag *self, int (*comparer)(const void*, const void*))
|
||||
{
|
||||
assert(0&&"not implemented");
|
||||
}
|
||||
|
||||
|
||||
static void emptyBag(WMBag *self)
|
||||
{
|
||||
W_Item *ptr = SELF->first;
|
||||
W_Item *tmp;
|
||||
|
||||
while (ptr) {
|
||||
tmp = ptr->next;
|
||||
|
||||
if (self->destructor) {
|
||||
self->destructor(ptr->data);
|
||||
}
|
||||
free(ptr);
|
||||
|
||||
ptr = tmp;
|
||||
}
|
||||
SELF->count = 0;
|
||||
}
|
||||
|
||||
|
||||
static void freeBag(WMBag *self)
|
||||
{
|
||||
emptyBag(self);
|
||||
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
||||
static WMBag *mapBag(WMBag *self, void * (*function)(void*, void*), void *data)
|
||||
{
|
||||
WMBag *bag = WMCreateListBagWithDestructor(self->destructor);
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr) {
|
||||
(*function)(ptr->data, data);
|
||||
|
||||
ptr = ptr->next;
|
||||
}
|
||||
return bag;
|
||||
}
|
||||
|
||||
|
||||
static int findInBag(WMBag *self, int (*match)(void*))
|
||||
{
|
||||
W_Item *ptr = SELF->first;
|
||||
int index = 0;
|
||||
|
||||
while (ptr) {
|
||||
if ((*match)(ptr)) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void *first(WMBag *self, WMBagIterator *ptr)
|
||||
{
|
||||
*ptr = SELF->first;
|
||||
|
||||
if (!*ptr)
|
||||
return NULL;
|
||||
|
||||
return SELF->first->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *last(WMBag *self, WMBagIterator *ptr)
|
||||
{
|
||||
*ptr = SELF->last;
|
||||
|
||||
if (!*ptr)
|
||||
return NULL;
|
||||
|
||||
return SELF->last->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *next(WMBag *bag, WMBagIterator *ptr)
|
||||
{
|
||||
W_Item *item = *(W_Item**)ptr;
|
||||
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
*ptr = item->next;
|
||||
|
||||
return item->next->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *previous(WMBag *bag, WMBagIterator *ptr)
|
||||
{
|
||||
W_Item *item = *(W_Item**)ptr;
|
||||
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
*ptr = item->prev;
|
||||
|
||||
return item->prev->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int indexForIterator(WMBag *bag, WMBagIterator ptr)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user