mirror of
https://github.com/Cloudef/bemenu
synced 2024-11-23 17:32:11 +01:00
140 lines
3.1 KiB
C
140 lines
3.1 KiB
C
#include "internal.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
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;
|
|
}
|
|
|
|
/** !!! Frees the old list, not items !!! */
|
|
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;
|
|
}
|
|
|
|
/** !!! Frees the old items and list !!! */
|
|
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);
|
|
free(list->list);
|
|
}
|
|
}
|
|
|
|
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 :*/
|