mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-04 07:15:47 +01:00
added list and array backends for WMBag
This commit is contained in:
@@ -96,7 +96,8 @@ libWINGs_a_SOURCES = \
|
||||
wview.c \
|
||||
error.c \
|
||||
findfile.c \
|
||||
bag.c \
|
||||
bagarray.c \
|
||||
baglist.c \
|
||||
connection.c \
|
||||
data.c \
|
||||
hashtable.c \
|
||||
@@ -108,7 +109,8 @@ libWINGs_a_SOURCES = \
|
||||
libWUtil_a_SOURCES = \
|
||||
WINGs.h \
|
||||
WINGsP.h \
|
||||
bag.c \
|
||||
bagarray.c \
|
||||
baglist.c \
|
||||
connection.c \
|
||||
data.c \
|
||||
host.c \
|
||||
|
||||
@@ -70,6 +70,7 @@ GFXLIBS = @GFXLIBS@
|
||||
HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@
|
||||
ICONEXT = @ICONEXT@
|
||||
INTLIBS = @INTLIBS@
|
||||
LD = @LD@
|
||||
LIBPL = @LIBPL@
|
||||
LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
@@ -79,6 +80,7 @@ MAKEINFO = @MAKEINFO@
|
||||
MOFILES = @MOFILES@
|
||||
NETLIBS = @NETLIBS@
|
||||
NLSDIR = @NLSDIR@
|
||||
NM = @NM@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
@@ -145,10 +147,10 @@ connect_LDADD = libWUtil.a @LIBRARY_SEARCH_PATH@ @NETLIBS@ @LIBPL@
|
||||
EXTRA_DIST = logo.xpm BUGS
|
||||
|
||||
# wbutton.c
|
||||
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmenuitem.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bag.c connection.c data.c hashtable.c host.c memory.c usleep.c
|
||||
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmenuitem.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bagarray.c baglist.c connection.c data.c hashtable.c host.c memory.c usleep.c
|
||||
|
||||
|
||||
libWUtil_a_SOURCES = WINGs.h WINGsP.h bag.c connection.c data.c host.c international.c notification.c userdefaults.c wapplication.c wutil.c error.c findfile.c hashtable.c memory.c usleep.c
|
||||
libWUtil_a_SOURCES = WINGs.h WINGsP.h bagarray.c baglist.c connection.c data.c host.c international.c notification.c userdefaults.c wapplication.c wutil.c error.c findfile.c hashtable.c memory.c usleep.c
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG
|
||||
@@ -173,12 +175,12 @@ wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \
|
||||
wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \
|
||||
wmenuitem.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o \
|
||||
wprogressindicator.o wscroller.o wscrollview.o wslider.o wsplitview.o \
|
||||
wtabview.o wtextfield.o wwindow.o wview.o error.o findfile.o bag.o \
|
||||
connection.o data.o hashtable.o host.o memory.o usleep.o
|
||||
wtabview.o wtextfield.o wwindow.o wview.o error.o findfile.o bagarray.o \
|
||||
baglist.o connection.o data.o hashtable.o host.o memory.o usleep.o
|
||||
libWUtil_a_LIBADD =
|
||||
libWUtil_a_OBJECTS = bag.o connection.o data.o host.o international.o \
|
||||
notification.o userdefaults.o wapplication.o wutil.o error.o findfile.o \
|
||||
hashtable.o memory.o usleep.o
|
||||
libWUtil_a_OBJECTS = bagarray.o baglist.o connection.o data.o host.o \
|
||||
international.o notification.o userdefaults.o wapplication.o wutil.o \
|
||||
error.o findfile.o hashtable.o memory.o usleep.o
|
||||
AR = ar
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ typedef enum {
|
||||
} WMConnectionState;
|
||||
|
||||
|
||||
|
||||
typedef struct W_Bag WMBag; /* equivalent to a linked list or array */
|
||||
typedef struct W_Bag WMBag;
|
||||
typedef struct W_Data WMData;
|
||||
typedef struct W_HashTable WMHashTable;
|
||||
typedef struct W_UserDefaults WMUserDefaults;
|
||||
@@ -141,6 +140,38 @@ typedef struct {
|
||||
} WMHashTableCallbacks;
|
||||
|
||||
|
||||
typedef struct W_BagFunctions {
|
||||
int (*getItemCount)(WMBag *self);
|
||||
int (*appendBag)(WMBag *self, WMBag *bag);
|
||||
int (*putInBag)(WMBag *self, void *item);
|
||||
int (*insertInBag)(WMBag *self, int index, void *item);
|
||||
int (*removeFromBag)(WMBag *bag, void *item);
|
||||
int (*deleteFromBag)(WMBag *bag, int index);
|
||||
void *(*getFromBag)(WMBag *bag, int index);
|
||||
int (*firstInBag)(WMBag *bag, void *item);
|
||||
int (*countInBag)(WMBag *bag, void *item);
|
||||
void *(*replaceInBag)(WMBag *bag, int index, void *item);
|
||||
void (*sortBag)(WMBag *bag, int (*comparer)(const void*, const void*));
|
||||
void (*emptyBag)(WMBag *bag);
|
||||
void (*freeBag)(WMBag *bag);
|
||||
WMBag *(*mapBag)(WMBag *bag, void * (*function)(void*));
|
||||
int (*findInBag)(WMBag *bag, int (*match)(void*));
|
||||
void *(*first)(WMBag *bag, void **ptr);
|
||||
void *(*last)(WMBag *bag, void **ptr);
|
||||
void *(*next)(WMBag *bag, void **ptr);
|
||||
void *(*previous)(WMBag *bag, void **ptr);
|
||||
} W_BagFunctions;
|
||||
|
||||
|
||||
struct W_Bag {
|
||||
void *data;
|
||||
|
||||
void (*destructor)(void *item);
|
||||
|
||||
W_BagFunctions func;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
@@ -274,42 +305,58 @@ extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
|
||||
/*......................................................................*/
|
||||
|
||||
|
||||
WMBag *WMCreateBag(int size);
|
||||
WMBag* WMCreateArrayBag(int size);
|
||||
WMBag* WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*));
|
||||
|
||||
|
||||
WMBag *WMCreateListBag(void);
|
||||
WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
|
||||
|
||||
#define WMCreateBag(size) WMCreateArrayBag(size)
|
||||
|
||||
#define WMGetBagItemCount(bag) bag->func.getItemCount(bag)
|
||||
|
||||
#define WMAppendBag(bag, other) bag->func.appendBag(bag, other)
|
||||
|
||||
#define WMPutInBag(bag, item) bag->func.putInBag(bag, item)
|
||||
|
||||
#define WMInsertInBag(bag, index, item) bag->func.insertInBag(bag, index, item)
|
||||
|
||||
int WMGetBagItemCount(WMBag *bag);
|
||||
#define WMRemoveFromBag(bag, item) bag->func.removeFromBag(bag, item)
|
||||
|
||||
void WMAppendBag(WMBag *bag, WMBag *appendedBag);
|
||||
#define WMDeleteFromBag(bag, index) bag->func.deleteFromBag(bag, index)
|
||||
|
||||
void WMPutInBag(WMBag *bag, void *item);
|
||||
#define WMGetFromBag(bag, index) bag->func.getFromBag(bag, index)
|
||||
|
||||
void WMInsertInBag(WMBag *bag, int index, void *item);
|
||||
#define WMCountInBag(bag, item) bag->func.countInBag(bag, item)
|
||||
|
||||
int WMGetFirstInBag(WMBag *bag, void *item);
|
||||
#define WMReplaceInBag(bag, index, item) bag->func.replaceInBag(bag, index, item)
|
||||
|
||||
int WMGetLastInBag(WMBag *bag, void *item);
|
||||
|
||||
void WMRemoveFromBag(WMBag *bag, void *item);
|
||||
|
||||
void WMDeleteFromBag(WMBag *bag, int index);
|
||||
|
||||
void *WMGetFromBag(WMBag *bag, int index);
|
||||
|
||||
int WMCountInBag(WMBag *bag, void *item);
|
||||
|
||||
void *WMReplaceInBag(WMBag *bag, int index, void *item);
|
||||
|
||||
/* comparer must return:
|
||||
* < 0 if a < b
|
||||
* > 0 if a > b
|
||||
* = 0 if a = b
|
||||
*/
|
||||
void WMSortBag(WMBag *bag, int (*comparer)(const void*, const void*));
|
||||
#define WMSortBag(bag, comparer) bag->func.sortBag(bag, comparer)
|
||||
|
||||
void WMEmptyBag(WMBag *bag);
|
||||
#define WMEmptyBag(bag) bag->func.emptyBag(bag)
|
||||
|
||||
void WMFreeBag(WMBag *bag);
|
||||
#define WMFreeBag(bag) bag->func.freeBag(bag)
|
||||
|
||||
#define WMMapBag(bag, function) bag->func.mapBag(bag, function)
|
||||
|
||||
#define WMGetFirstInBag(bag, item) bag->func.firstInBag(bag, item)
|
||||
|
||||
#define WMFindInBag(bag, match) bag->func.findInBag(bag, match)
|
||||
|
||||
#define WMBagFirst(bag, ptr) bag->func.first(bag, ptr)
|
||||
|
||||
#define WMBagLast(bag, ptr) bag->func.last(bag, ptr)
|
||||
|
||||
#define WMBagNext(bag, ptr) bag->func.next(bag, ptr)
|
||||
|
||||
#define WMBagPrevious(bag, ptr) bag->func.previous(bag, ptr)
|
||||
|
||||
WMBag *WMMapBag(WMBag *bag, void* (*function)(void*));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
216
WINGs/bag.c
216
WINGs/bag.c
@@ -1,216 +0,0 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WUtil.h"
|
||||
|
||||
|
||||
|
||||
struct W_Bag {
|
||||
int size;
|
||||
int count;
|
||||
|
||||
void **items;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
WMBag*
|
||||
WMCreateBag(int size)
|
||||
{
|
||||
WMBag *bag;
|
||||
|
||||
wassertrv(size > 0, NULL);
|
||||
|
||||
bag = wmalloc(sizeof(WMBag));
|
||||
|
||||
bag->items = wmalloc(sizeof(void*) * size);
|
||||
bag->size = size;
|
||||
bag->count = 0;
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
WMGetBagItemCount(WMBag *bag)
|
||||
{
|
||||
return bag->count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMAppendBag(WMBag *bag, WMBag *appendedBag)
|
||||
{
|
||||
bag->items = wrealloc(bag->items,
|
||||
sizeof(void*) * (bag->size+appendedBag->count));
|
||||
|
||||
memcpy(bag->items + bag->count, appendedBag->items,
|
||||
sizeof(void*) * appendedBag->count);
|
||||
|
||||
bag->count += appendedBag->count;
|
||||
bag->size += appendedBag->count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMPutInBag(WMBag *bag, void *item)
|
||||
{
|
||||
WMInsertInBag(bag, bag->count, item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMInsertInBag(WMBag *bag, int index, void *item)
|
||||
{
|
||||
if (bag->count == bag->size) {
|
||||
bag->size += 16;
|
||||
bag->items = wrealloc(bag->items, sizeof(void*) * bag->size);
|
||||
}
|
||||
|
||||
if (index >= 0 && index < bag->count) {
|
||||
memmove(&bag->items[index+1], &bag->items[index],
|
||||
(bag->count - index) * sizeof(void*));
|
||||
} else {
|
||||
/* If index is invalid, place it at end */
|
||||
index = bag->count;
|
||||
}
|
||||
bag->items[index] = item;
|
||||
bag->count++;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
WMGetFirstInBag(WMBag *bag, void *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bag->count; i++) {
|
||||
if (bag->items[i] == item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
WMGetLastInBag(WMBag *bag, void *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = bag->count-1; i>= 0; i--) {
|
||||
if (bag->items[i] == item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMRemoveFromBag(WMBag *bag, void *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = WMGetFirstInBag(bag, item);
|
||||
if (i >= 0) {
|
||||
WMDeleteFromBag(bag, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMDeleteFromBag(WMBag *bag, int index)
|
||||
{
|
||||
wassertr(index >= 0 && index < bag->count);
|
||||
|
||||
if (index < bag->count-1) {
|
||||
memmove(&bag->items[index], &bag->items[index + 1],
|
||||
(bag->count - index - 1) * sizeof(void*));
|
||||
}
|
||||
bag->count--;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
WMGetFromBag(WMBag *bag, int index)
|
||||
{
|
||||
wassertrv(index >= 0 && index < bag->count, NULL);
|
||||
|
||||
return bag->items[index];
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
WMCountInBag(WMBag *bag, void *item)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0, i = 0; j < bag->count; j++) {
|
||||
if (bag->items[j] == item)
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMSortBag(WMBag *bag, int (*comparer)(const void*, const void*))
|
||||
{
|
||||
qsort(bag->items, bag->count, sizeof(void*), comparer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WMFreeBag(WMBag *bag)
|
||||
{
|
||||
wfree(bag->items);
|
||||
wfree(bag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMEmptyBag(WMBag *bag)
|
||||
{
|
||||
bag->count = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WMBag*
|
||||
WMMapBag(WMBag *bag, void *(*function)(void *))
|
||||
{
|
||||
int i;
|
||||
WMBag *new = WMCreateBag(bag->size);
|
||||
|
||||
for (i = 0; i < bag->count; i++) {
|
||||
WMPutInBag(new, (*function)(bag->items[i]));
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
WMReplaceInBag(WMBag *bag, int index, void *item)
|
||||
{
|
||||
void *old;
|
||||
|
||||
wassertrv(index >= 0 && index < bag->count, NULL);
|
||||
|
||||
old = bag->items[index];
|
||||
|
||||
bag->items[index] = item;
|
||||
|
||||
return old;
|
||||
}
|
||||
386
WINGs/bagarray.c
Normal file
386
WINGs/bagarray.c
Normal file
@@ -0,0 +1,386 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WUtil.h"
|
||||
|
||||
|
||||
|
||||
typedef struct W_ArrayBag {
|
||||
void **items;
|
||||
int size;
|
||||
int count;
|
||||
} 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 void sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
|
||||
static void emptyBag(WMBag *bag);
|
||||
static void freeBag(WMBag *bag);
|
||||
static WMBag* mapBag(WMBag *bag, void *(*function)(void *));
|
||||
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 W_BagFunctions arrayFunctions = {
|
||||
getItemCount,
|
||||
appendBag,
|
||||
putInBag,
|
||||
insertInBag,
|
||||
removeFromBag,
|
||||
deleteFromBag,
|
||||
getFromBag,
|
||||
firstInBag,
|
||||
countInBag,
|
||||
replaceInBag,
|
||||
sortBag,
|
||||
emptyBag,
|
||||
freeBag,
|
||||
mapBag,
|
||||
findInBag,
|
||||
first,
|
||||
last,
|
||||
next,
|
||||
previous
|
||||
};
|
||||
|
||||
|
||||
#define ARRAY ((W_ArrayBag*)bag->data)
|
||||
|
||||
|
||||
WMBag*
|
||||
WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
|
||||
{
|
||||
WMBag *bag;
|
||||
W_ArrayBag *array;
|
||||
|
||||
wassertrv(size > 0, NULL);
|
||||
|
||||
bag = wmalloc(sizeof(WMBag));
|
||||
|
||||
array = wmalloc(sizeof(W_ArrayBag));
|
||||
|
||||
bag->data = array;
|
||||
|
||||
array->items = wmalloc(sizeof(void*) * size);
|
||||
array->size = size;
|
||||
array->count = 0;
|
||||
|
||||
bag->func = arrayFunctions;
|
||||
|
||||
bag->destructor = destructor;
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
|
||||
WMBag*
|
||||
WMCreateArrayBag(int size)
|
||||
{
|
||||
return WMCreateArrayBagWithDestructor(size, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getItemCount(WMBag *bag)
|
||||
{
|
||||
return ARRAY->count;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
appendBag(WMBag *bag, WMBag *appendedBag)
|
||||
{
|
||||
W_ArrayBag *array1 = ARRAY;
|
||||
W_ArrayBag *array2 = (W_ArrayBag*)appendedBag->data;
|
||||
|
||||
if (array1->count + array2->count >= array1->size) {
|
||||
array1->items =
|
||||
wrealloc(array1->items, sizeof(void*) * (array1->size+array2->count));
|
||||
array1->size += array2->count;
|
||||
}
|
||||
|
||||
memcpy(array1->items + array1->count, array2->items,
|
||||
sizeof(void*) * array2->count);
|
||||
|
||||
array1->count += array2->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
putInBag(WMBag *bag, void *item)
|
||||
{
|
||||
return insertInBag(bag, ARRAY->count, item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
insertInBag(WMBag *bag, int index, void *item)
|
||||
{
|
||||
W_ArrayBag *array = ARRAY;
|
||||
|
||||
if (array->count == array->size) {
|
||||
array->size += 16;
|
||||
array->items = wrealloc(array->items, sizeof(void*) * array->size);
|
||||
}
|
||||
|
||||
if (index >= 0 && index < array->count) {
|
||||
memmove(&array->items[index+1], &array->items[index],
|
||||
(array->count - index) * sizeof(void*));
|
||||
} else {
|
||||
/* If index is invalid, place it at end */
|
||||
index = array->count;
|
||||
}
|
||||
array->items[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 void
|
||||
sortBag(WMBag *bag, int (*comparer)(const void*, const void*))
|
||||
{
|
||||
qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 WMBag*
|
||||
mapBag(WMBag *bag, void *(*function)(void *))
|
||||
{
|
||||
int i;
|
||||
void *data;
|
||||
WMBag *new = WMCreateArrayBagWithDestructor(ARRAY->size, bag->destructor);
|
||||
|
||||
for (i = 0; i < ARRAY->count; i++) {
|
||||
data = (*function)(ARRAY->items[i]);
|
||||
if (data)
|
||||
putInBag(new, data);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
findInBag(WMBag *bag, int (*match)(void*))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY->count; 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];
|
||||
}
|
||||
|
||||
|
||||
441
WINGs/baglist.c
Normal file
441
WINGs/baglist.c
Normal file
@@ -0,0 +1,441 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "WUtil.h"
|
||||
|
||||
|
||||
typedef struct W_Item {
|
||||
struct W_Item *next;
|
||||
struct W_Item *prev;
|
||||
void *data;
|
||||
} 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 WMBag *mapBag(WMBag *bag, void * (*function)(void*));
|
||||
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 W_BagFunctions bagFunctions = {
|
||||
getItemCount,
|
||||
appendBag,
|
||||
putInBag,
|
||||
insertInBag,
|
||||
removeFromBag,
|
||||
deleteFromBag,
|
||||
getFromBag,
|
||||
firstInBag,
|
||||
countInBag,
|
||||
replaceInBag,
|
||||
sortBag,
|
||||
emptyBag,
|
||||
freeBag,
|
||||
mapBag,
|
||||
findInBag,
|
||||
first,
|
||||
last,
|
||||
next,
|
||||
previous
|
||||
};
|
||||
|
||||
|
||||
#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*))
|
||||
{
|
||||
WMBag *bag = WMCreateListBagWithDestructor(self->destructor);
|
||||
W_Item *ptr = SELF->first;
|
||||
|
||||
while (ptr) {
|
||||
if ((*function)(ptr->data))
|
||||
putInBag(bag, ptr->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, void **ptr)
|
||||
{
|
||||
*ptr = SELF->first;
|
||||
|
||||
if (!*ptr)
|
||||
return NULL;
|
||||
|
||||
return SELF->first->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *last(WMBag *self, void **ptr)
|
||||
{
|
||||
*ptr = SELF->last;
|
||||
|
||||
if (!*ptr)
|
||||
return NULL;
|
||||
|
||||
return SELF->last->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *next(WMBag *bag, void **ptr)
|
||||
{
|
||||
W_Item *item = *(W_Item**)ptr;
|
||||
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
*ptr = item->next;
|
||||
|
||||
return item->next->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *previous(WMBag *bag, void **ptr)
|
||||
{
|
||||
W_Item *item = *(W_Item**)ptr;
|
||||
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
*ptr = item->prev;
|
||||
|
||||
return item->prev->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -481,8 +481,16 @@ testTabView(WMScreen *scr)
|
||||
WMSetTabViewItemLabel(tab, "Bla!");
|
||||
|
||||
|
||||
|
||||
frame = WMCreateFrame(win);
|
||||
WMSetFrameRelief(frame, WRFlat);
|
||||
label = WMCreateLabel(frame);
|
||||
WMResizeWidget(label, 100, 100);
|
||||
WMMoveWidget(label, 160, 40);
|
||||
WMSetLabelText(label, "Label fjweqklrj qwl");
|
||||
WMMapWidget(label);
|
||||
tab = WMCreateTabViewItemWithIdentifier(0);
|
||||
WMSetTabViewItemView(tab, WMWidgetView(frame));
|
||||
WMSetTabViewItemView(tab, WMWidgetView(frame));
|
||||
WMAddItemInTabView(tabv, tab);
|
||||
WMSetTabViewItemLabel(tab, "Weee!");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user