mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 04:20:27 +01:00
Created Documentation, Examples and Tests subdirectories. Run update-autoconf after this update.
419 lines
7.2 KiB
C
419 lines
7.2 KiB
C
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "WUtil.h"
|
|
|
|
#if 0
|
|
|
|
typedef struct W_ArrayBag {
|
|
void **items;
|
|
int size;
|
|
int count;
|
|
|
|
int base;
|
|
int first;
|
|
int last;
|
|
} W_ArrayBag;
|
|
|
|
|
|
static int getItemCount(WMBag *bag);
|
|
static int appendBag(WMBag *bag, WMBag *appendedBag);
|
|
static int putInBag(WMBag *bag, void *item);
|
|
static int insertInBag(WMBag *bag, 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 firstInBag(WMBag *bag, void *item);
|
|
static int countInBag(WMBag *bag, void *item);
|
|
static void* replaceInBag(WMBag *bag, int index, void *item);
|
|
static int 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, void **ptr);
|
|
static void* last(WMBag *bag, void **ptr);
|
|
static void* next(WMBag *bag, void **ptr);
|
|
static void* previous(WMBag *bag, void **ptr);
|
|
static void* iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
|
|
static int indexForIterator(WMBag *bag, WMBagIterator ptr);
|
|
|
|
|
|
static W_BagFunctions arrayFunctions = {
|
|
getItemCount,
|
|
appendBag,
|
|
putInBag,
|
|
insertInBag,
|
|
removeFromBag,
|
|
deleteFromBag,
|
|
deleteFromBag,
|
|
getFromBag,
|
|
firstInBag,
|
|
countInBag,
|
|
replaceInBag,
|
|
sortBag,
|
|
emptyBag,
|
|
freeBag,
|
|
mapBag,
|
|
findInBag,
|
|
first,
|
|
last,
|
|
next,
|
|
previous,
|
|
iteratorAtIndex,
|
|
indexForIterator
|
|
};
|
|
|
|
|
|
#define ARRAY ((W_ArrayBag*)(bag->data))
|
|
|
|
|
|
#define I2O(a, i) ((a)->base + i)
|
|
|
|
|
|
WMBag*
|
|
WMCreateArrayBagWithDestructor(int initialSize, void (*destructor)(void*))
|
|
{
|
|
WMBag *bag;
|
|
W_ArrayBag *array;
|
|
int size;
|
|
|
|
assert(0&&"array bag is not working");
|
|
bag = wmalloc(sizeof(WMBag));
|
|
|
|
array = wmalloc(sizeof(W_ArrayBag));
|
|
|
|
bag->data = array;
|
|
|
|
array->items = wmalloc(sizeof(void*) * size);
|
|
array->size = size;
|
|
array->count = 0;
|
|
array->first = 0;
|
|
array->last = 0;
|
|
array->base = 0;
|
|
|
|
bag->func = arrayFunctions;
|
|
|
|
bag->destructor = destructor;
|
|
|
|
return bag;
|
|
}
|
|
|
|
|
|
WMBag*
|
|
WMCreateArrayBag(int initialSize)
|
|
{
|
|
return WMCreateArrayBagWithDestructor(initialSize, NULL);
|
|
}
|
|
|
|
|
|
static int
|
|
getItemCount(WMBag *bag)
|
|
{
|
|
return ARRAY->count;
|
|
}
|
|
|
|
|
|
static int
|
|
appendBag(WMBag *bag, WMBag *appendedBag)
|
|
{
|
|
W_ArrayBag *array = (W_ArrayBag*)appendedBag->data;
|
|
int ok;
|
|
int i;
|
|
|
|
for (i = array->first; i <= array->last; i++) {
|
|
if (array->items[array->base+i]) {
|
|
ok = putInBag(bag, array->items[array->base+i]);
|
|
if (!ok)
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
putInBag(WMBag *bag, void *item)
|
|
{
|
|
return insertInBag(bag, ARRAY->last+1, item);
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
insertInBag(WMBag *bag, int index, void *item)
|
|
{
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
if (I2O(array, index) >= array->size) {
|
|
array->size = WMAX(array->size + 16, I2O(array, index));
|
|
array->items = wrealloc(array->items, sizeof(void*) * array->size);
|
|
memset(array->items + I2O(array, array->last), 0,
|
|
sizeof(void*) * (array->size - I2O(array, array->last)));
|
|
}
|
|
|
|
if (index > array->last) {
|
|
array->last = index;
|
|
} else if (index >= array->first) {
|
|
memmove(array->items + I2O(array, index),
|
|
array->items + (I2O(array, index) + 1), sizeof(void*));
|
|
array->last++;
|
|
} else {
|
|
memmove(array->items,
|
|
array->items + (abs(index) - array->base),
|
|
sizeof(void*) * (abs(index) - array->base));
|
|
memset(array->items, 0, sizeof(void*) * (abs(index) - array->base));
|
|
array->first = index;
|
|
array->base = abs(index);
|
|
}
|
|
|
|
array->items[array->base + index] = item;
|
|
array->count++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
static int
|
|
removeFromBag(WMBag *bag, void *item)
|
|
{
|
|
int i;
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
for (i = 0; i < array->count; i++) {
|
|
if (array->items[i] == item) {
|
|
if (bag->destructor)
|
|
bag->destructor(array->items[i]);
|
|
|
|
memmove(&array->items[i], &array->items[i + 1],
|
|
(array->count - i - 1) * sizeof(void*));
|
|
array->count--;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
deleteFromBag(WMBag *bag, int index)
|
|
{
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
if (index < 0 || index >= array->count)
|
|
return 0;
|
|
|
|
if (index < array->count-1) {
|
|
if (bag->destructor)
|
|
bag->destructor(array->items[index]);
|
|
|
|
memmove(&array->items[index], &array->items[index + 1],
|
|
(array->count - index - 1) * sizeof(void*));
|
|
}
|
|
array->count--;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
static void*
|
|
getFromBag(WMBag *bag, int index)
|
|
{
|
|
if (index < 0 || index >= ARRAY->count)
|
|
return NULL;
|
|
|
|
return ARRAY->items[index];
|
|
}
|
|
|
|
|
|
static int
|
|
firstInBag(WMBag *bag, void *item)
|
|
{
|
|
int j;
|
|
int count = ARRAY->count;
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
for (j = 0; j < count; j++) {
|
|
if (array->items[j] == item)
|
|
return j;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
countInBag(WMBag *bag, void *item)
|
|
{
|
|
int i, j;
|
|
int count = ARRAY->count;
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
for (j = 0, i = 0; j < count; j++) {
|
|
if (array->items[j] == item)
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|
|
static void*
|
|
replaceInBag(WMBag *bag, int index, void *item)
|
|
{
|
|
void *old;
|
|
|
|
if (index < 0 || index >= ARRAY->count)
|
|
return NULL;
|
|
|
|
old = ARRAY->items[index];
|
|
|
|
ARRAY->items[index] = item;
|
|
|
|
return old;
|
|
}
|
|
|
|
|
|
static int
|
|
sortBag(WMBag *bag, int (*comparer)(const void*, const void*))
|
|
{
|
|
qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
emptyBag(WMBag *bag)
|
|
{
|
|
W_ArrayBag *array = ARRAY;
|
|
|
|
if (bag->destructor) {
|
|
while (--array->count) {
|
|
bag->destructor(array->items[array->count]);
|
|
}
|
|
}
|
|
ARRAY->count=0;
|
|
}
|
|
|
|
|
|
static void
|
|
freeBag(WMBag *bag)
|
|
{
|
|
emptyBag(bag);
|
|
|
|
wfree(ARRAY->items);
|
|
wfree(ARRAY);
|
|
wfree(bag);
|
|
}
|
|
|
|
|
|
static void
|
|
mapBag(WMBag *bag, void (*function)(void *, void *), void *clientData)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY->last; i++) {
|
|
if (ARRAY->items[i])
|
|
(*function)(ARRAY->items[i], clientData);
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
findInBag(WMBag *bag, int (*match)(void*))
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY->last; i++) {
|
|
if ((*match)(ARRAY->items[i]))
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
static void*
|
|
first(WMBag *bag, void **ptr)
|
|
{
|
|
*ptr = NULL;
|
|
|
|
if (ARRAY->count == 0)
|
|
return NULL;
|
|
|
|
*(int**)ptr = 0;
|
|
return ARRAY->items[0];
|
|
}
|
|
|
|
|
|
static void*
|
|
last(WMBag *bag, void **ptr)
|
|
{
|
|
*ptr = NULL;
|
|
|
|
if (ARRAY->count == 0)
|
|
return NULL;
|
|
|
|
*(int*)ptr = ARRAY->count-1;
|
|
|
|
return ARRAY->items[ARRAY->count-1];
|
|
}
|
|
|
|
|
|
static void*
|
|
next(WMBag *bag, void **ptr)
|
|
{
|
|
if (!*ptr)
|
|
return NULL;
|
|
|
|
(*(int*)ptr)++;
|
|
if (*(int*)ptr >= ARRAY->count) {
|
|
*ptr = NULL;
|
|
return NULL;
|
|
}
|
|
|
|
return ARRAY->items[*(int*)ptr];
|
|
}
|
|
|
|
|
|
static void*
|
|
previous(WMBag *bag, void **ptr)
|
|
{
|
|
if (!*ptr)
|
|
return NULL;
|
|
|
|
(*(int*)ptr)--;
|
|
if (*(int*)ptr < 0) {
|
|
*ptr = NULL;
|
|
return NULL;
|
|
}
|
|
|
|
return ARRAY->items[*(int*)ptr];
|
|
}
|
|
|
|
|
|
|
|
static void*
|
|
iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr)
|
|
{
|
|
}
|
|
|
|
|
|
static int
|
|
indexForIterator(WMBag *bag, WMBagIterator ptr)
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|