From a6d0413b972580f3bbfde8750090270b0d8d463e Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Thu, 10 Apr 2014 20:04:06 +0300 Subject: Implement list structure, and feature for multiple selections. --- lib/list.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 lib/list.c (limited to 'lib/list.c') diff --git a/lib/list.c b/lib/list.c new file mode 100644 index 0000000..2123818 --- /dev/null +++ b/lib/list.c @@ -0,0 +1,135 @@ +#include "internal.h" +#include +#include +#include + +void _bmItemListFreeList(struct _bmItemList *list) +{ + assert(list); + + if (list->list) + free(list->list); + + list->allocated = list->count = 0; + list->list = NULL; +} + +void _bmItemListFreeItems(struct _bmItemList *list) +{ + assert(list); + + unsigned int i; + for (i = 0; i < list->count; ++i) + bmItemFree(list->list[i]); + + _bmItemListFreeList(list); +} + +bmItem** _bmItemListGetItems(const struct _bmItemList *list, unsigned int *outNmemb) +{ + assert(list); + + if (outNmemb) + *outNmemb = list->count; + + return list->list; +} + +int _bmItemListSetItemsNoCopy(struct _bmItemList *list, bmItem **items, unsigned int nmemb) +{ + assert(list); + + _bmItemListFreeList(list); + + if (!items || nmemb == 0) { + items = NULL; + nmemb = 0; + } + + list->list = items; + list->allocated = list->count = nmemb; + return 1; +} + +int _bmItemListSetItems(struct _bmItemList *list, const bmItem **items, unsigned int nmemb) +{ + assert(list); + + if (!items || nmemb == 0) { + _bmItemListFreeItems(list); + return 1; + } + + bmItem **newItems; + if (!(newItems = calloc(sizeof(bmItem*), nmemb))) + return 0; + + memcpy(newItems, items, sizeof(bmItem*) * nmemb); + return _bmItemListSetItemsNoCopy(list, newItems, nmemb); +} + +int _bmItemListGrow(struct _bmItemList *list, unsigned int step) +{ + assert(list); + + void *tmp; + unsigned int nsize = sizeof(bmItem*) * (list->allocated + step); + + if (!list->list || !(tmp = realloc(list->list, nsize))) { + if (!(tmp = malloc(nsize))) + return 0; + + if (list->list) + memcpy(tmp, list->list, sizeof(bmItem*) * list->allocated); + } + + list->list = tmp; + list->allocated += step; + memset(&list->list[list->count], 0, sizeof(bmItem*) * (list->allocated - list->count)); + return 1; +} + +int _bmItemListAddItemAt(struct _bmItemList *list, bmItem *item, unsigned int index) +{ + assert(list); + assert(item); + + if ((!list->list || list->allocated <= list->count) && !_bmItemListGrow(list, 32)) + return 0; + + if (index + 1 != list->count) { + unsigned int i = index; + memmove(&list->list[i + 1], &list->list[i], sizeof(bmItem*) * (list->count - i)); + } + + list->list[index] = item; + list->count++; + return 1; +} + +int _bmItemListAddItem(struct _bmItemList *list, bmItem *item) +{ + assert(list); + return _bmItemListAddItemAt(list, item, list->count); +} + +int _bmItemListRemoveItemAt(struct _bmItemList *list, unsigned int index) +{ + assert(list); + + unsigned int i = index; + if (!list->list || list->count <= i) + return 0; + + memmove(&list->list[i], &list->list[i], sizeof(bmItem*) * (list->count - i)); + return 1; +} + +int _bmItemListRemoveItem(struct _bmItemList *list, const bmItem *item) +{ + unsigned int i; + for (i = 0; i < list->count && list->list[i] != item; ++i); + return _bmItemListRemoveItemAt(list, i); +} + +/* vim: set ts=8 sw=4 tw=0 :*/ -- cgit v1.2.3-70-g09d2 From 40bd036c5390118a8f1631e1d990cce29edb40f4 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Fri, 11 Apr 2014 01:59:05 +0300 Subject: Free the old list. --- lib/list.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/list.c') diff --git a/lib/list.c b/lib/list.c index 2123818..fb0bdb2 100644 --- a/lib/list.c +++ b/lib/list.c @@ -79,8 +79,10 @@ int _bmItemListGrow(struct _bmItemList *list, unsigned int step) if (!(tmp = malloc(nsize))) return 0; - if (list->list) + if (list->list) { memcpy(tmp, list->list, sizeof(bmItem*) * list->allocated); + free(list->list); + } } list->list = tmp; -- cgit v1.2.3-70-g09d2 From ab54f2bc0796b963ac8181f8f31d720e9feffd98 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 12 Apr 2014 20:55:45 +0300 Subject: Here be dragons comments. --- lib/list.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/list.c') diff --git a/lib/list.c b/lib/list.c index fb0bdb2..203adf2 100644 --- a/lib/list.c +++ b/lib/list.c @@ -35,6 +35,7 @@ bmItem** _bmItemListGetItems(const struct _bmItemList *list, unsigned int *outNm return list->list; } +/** !!! Frees the old list, not items !!! */ int _bmItemListSetItemsNoCopy(struct _bmItemList *list, bmItem **items, unsigned int nmemb) { assert(list); @@ -51,6 +52,7 @@ int _bmItemListSetItemsNoCopy(struct _bmItemList *list, bmItem **items, unsigned return 1; } +/** !!! Frees the old items and list !!! */ int _bmItemListSetItems(struct _bmItemList *list, const bmItem **items, unsigned int nmemb) { assert(list); -- cgit v1.2.3-70-g09d2