From 1dc5c1882c220f9f56aac326fe16e55c716d69d3 Mon Sep 17 00:00:00 2001 From: kojima Date: Sun, 5 Mar 2000 22:01:34 +0000 Subject: [PATCH] added list and array backends for WMBag --- WINGs/Makefile.am | 6 +- WINGs/Makefile.in | 16 +- WINGs/WUtil.h | 95 +++++++--- WINGs/bag.c | 216 ----------------------- WINGs/bagarray.c | 386 ++++++++++++++++++++++++++++++++++++++++ WINGs/baglist.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++ WINGs/wtest.c | 10 +- 7 files changed, 920 insertions(+), 250 deletions(-) delete mode 100644 WINGs/bag.c create mode 100644 WINGs/bagarray.c create mode 100644 WINGs/baglist.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index ea9164cd..ba05ecc2 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -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 \ diff --git a/WINGs/Makefile.in b/WINGs/Makefile.in index 5eba20e8..3751f28b 100644 --- a/WINGs/Makefile.in +++ b/WINGs/Makefile.in @@ -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) diff --git a/WINGs/WUtil.h b/WINGs/WUtil.h index 43f043f5..61eb4a2a 100644 --- a/WINGs/WUtil.h +++ b/WINGs/WUtil.h @@ -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*)); /*-------------------------------------------------------------------------*/ diff --git a/WINGs/bag.c b/WINGs/bag.c deleted file mode 100644 index ba1975c0..00000000 --- a/WINGs/bag.c +++ /dev/null @@ -1,216 +0,0 @@ - - -#include -#include - -#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; -} diff --git a/WINGs/bagarray.c b/WINGs/bagarray.c new file mode 100644 index 00000000..6f746bab --- /dev/null +++ b/WINGs/bagarray.c @@ -0,0 +1,386 @@ + + + + +#include +#include + +#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]; +} + + diff --git a/WINGs/baglist.c b/WINGs/baglist.c new file mode 100644 index 00000000..9c7b6285 --- /dev/null +++ b/WINGs/baglist.c @@ -0,0 +1,441 @@ + + + + +#include +#include + +#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; +} + + + + diff --git a/WINGs/wtest.c b/WINGs/wtest.c index 9aba32f1..81758d01 100644 --- a/WINGs/wtest.c +++ b/WINGs/wtest.c @@ -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!");