ustr-pool-code.h
#ifndef USTR_POOL_H
#error " You should have already included ustr-pool.h, or just include ustr.h."
#endif
struct Ustr__pool_ll_node
{
struct Ustr__pool_ll_node *next;
void *ptr;
};
struct Ustr__pool_ll_base
{
struct Ustr_pool cbs;
struct Ustr__pool_ll_node *beg;
struct Ustr__pool_ll_base *sbeg;
struct Ustr__pool_ll_base *base;
struct Ustr__pool_ll_base *next;
struct Ustr__pool_ll_base *prev;
unsigned int free_num : 30;
unsigned int call_realloc : 1;
};
#define USTR__POOL_LL_SIB_NULL ((struct Ustr__pool_ll_base *) 0)
USTR_CONF_e_PROTO void *ustr__pool_ll_sys_malloc(struct Ustr_pool *, size_t)
USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_A()
USTR__COMPILE_ATTR_MALLOC();
USTR_CONF_e_PROTO
void *ustr__pool_ll_sys_realloc(struct Ustr_pool *, void *, size_t, size_t)
USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_L((1))
USTR__COMPILE_ATTR_MALLOC();
USTR_CONF_e_PROTO void ustr__pool_ll_sys_free(struct Ustr_pool *, void *)
USTR__COMPILE_ATTR_NONNULL_L((1));
USTR_CONF_e_PROTO
struct Ustr_pool *ustr__pool_ll_make_subpool(struct Ustr_pool *)
USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_MALLOC();
USTR_CONF_e_PROTO void ustr__pool_ll__clear(struct Ustr__pool_ll_base *, int);
USTR_CONF_e_PROTO void ustr__pool_ll_clear(struct Ustr_pool *)
USTR__COMPILE_ATTR_NONNULL_A();
USTR_CONF_e_PROTO void ustr__pool_ll__free(struct Ustr__pool_ll_base *, int);
USTR_CONF_e_PROTO void ustr__pool_ll_free(struct Ustr_pool *);
USTR_CONF_i_PROTO void *ustr__pool_ll_sys_malloc(struct Ustr_pool *p,size_t len)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
struct Ustr__pool_ll_node *np;
void *ret = USTR_CONF_MALLOC(len);
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
sizeof(struct Ustr__pool_ll_base)));
if (!ret)
return (ret);
if (!(np = USTR_CONF_MALLOC(sizeof(struct Ustr__pool_ll_node))))
{
USTR_CONF_FREE(ret);
return (0);
}
np->next = sip->beg;
sip->beg = np;
np->ptr = ret;
return (ret);
}
USTR_CONF_i_PROTO
void *ustr__pool_ll_sys_realloc(struct Ustr_pool *p, void *old,
size_t olen, size_t nlen)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
void *ret = 0;
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
sizeof(struct Ustr__pool_ll_base)));
USTR_ASSERT((old && sip->beg && sip->beg->ptr) || !olen);
ustr_assert(olen ? USTR_CNTL_MALLOC_CHECK_MEM_MINSZ(old, olen) :
(!old || USTR_CNTL_MALLOC_CHECK_MEM(old)));
if (!nlen)
++nlen;
if (olen && (sip->beg->ptr == old) && sip->call_realloc)
{
if ((ret = USTR_CONF_REALLOC(old, nlen)))
sip->beg->ptr = ret;
}
else if (olen >= nlen)
{
USTR__CNTL_MALLOC_CHECK_FIXUP_REALLOC(old, nlen);
return (old);
}
else if ((ret = ustr__pool_ll_sys_malloc(p, nlen)))
memcpy(ret, old, olen);
return (ret);
}
USTR_CONF_i_PROTO
void ustr__pool_ll_sys_free(struct Ustr_pool *p, void *old)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
struct Ustr__pool_ll_node **op = &sip->beg;
unsigned int num = sip->free_num;
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
sizeof(struct Ustr__pool_ll_base)));
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM(old));
while (*op && num--)
{
if ((*op)->ptr == old)
{
struct Ustr__pool_ll_node *rm = *op;
*op = rm->next;
USTR_CONF_FREE(rm->ptr);
USTR_CONF_FREE(rm);
return;
}
op = &(*op)->next;
}
}
USTR_CONF_i_PROTO void ustr__pool_ll__clear(struct Ustr__pool_ll_base *base,
int siblings)
{
struct Ustr__pool_ll_node *scan;
if (!base)
return;
scan = base->beg;
while (scan)
{
struct Ustr__pool_ll_node *scan_next = scan->next;
USTR_CONF_FREE(scan->ptr);
USTR_CONF_FREE(scan);
scan = scan_next;
}
base->beg = 0;
if (siblings)
ustr__pool_ll__clear(base->next, USTR_TRUE);
ustr__pool_ll__clear(base->sbeg, USTR_TRUE);
}
USTR_CONF_i_PROTO void ustr__pool_ll_clear(struct Ustr_pool *base)
{
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(base,
sizeof(struct Ustr__pool_ll_base)));
ustr__pool_ll__clear((struct Ustr__pool_ll_base *)base, USTR_FALSE);
}
USTR_CONF_i_PROTO void ustr__pool_ll__free(struct Ustr__pool_ll_base *base,
int siblings)
{
if (!base)
return;
if (siblings)
ustr__pool_ll__free(base->next, USTR_TRUE);
ustr__pool_ll__free(base->sbeg, USTR_TRUE);
base->sbeg = 0;
ustr__pool_ll__clear(base, USTR_FALSE);
USTR_CONF_FREE(base);
}
USTR_CONF_i_PROTO void ustr__pool_ll_free(struct Ustr_pool *p)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
sizeof(struct Ustr__pool_ll_base)));
if (sip->prev)
sip->prev->next = sip->next;
else if (sip->base)
sip->base->sbeg = sip->next;
if (sip->next)
sip->next->prev = sip->prev;
ustr__pool_ll__free(sip, USTR_FALSE);
}
USTR_CONF_i_PROTO
struct Ustr_pool *ustr__pool_ll_make_subpool(struct Ustr_pool *p)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
struct Ustr__pool_ll_base *tmp;
if (!(tmp = USTR_CONF_MALLOC(sizeof(struct Ustr__pool_ll_base))))
return (USTR_POOL_NULL);
tmp->cbs.pool_sys_malloc = ustr__pool_ll_sys_malloc;
tmp->cbs.pool_sys_realloc = ustr__pool_ll_sys_realloc;
tmp->cbs.pool_sys_free = ustr__pool_ll_sys_free;
tmp->cbs.pool_make_subpool = ustr__pool_ll_make_subpool;
tmp->cbs.pool_clear = ustr__pool_ll_clear;
tmp->cbs.pool_free = ustr__pool_ll_free;
tmp->beg = 0;
tmp->sbeg = USTR__POOL_LL_SIB_NULL;
tmp->prev = USTR__POOL_LL_SIB_NULL;
tmp->next = USTR__POOL_LL_SIB_NULL;
tmp->base = USTR__POOL_LL_SIB_NULL;
tmp->free_num = 2;
tmp->call_realloc = USTR_TRUE;
if (!p)
return (&tmp->cbs);
ustr_assert(USTR_CNTL_MALLOC_CHECK_MEM_SZ(p,
sizeof(struct Ustr__pool_ll_base)));
if ((tmp->next = sip->sbeg))
tmp->next->prev = tmp;
sip->sbeg = tmp;
tmp->base = sip;
return (&tmp->cbs);
}
USTR_CONF_I_PROTO struct Ustr_pool *ustr_pool_ll_make(void)
{ return (ustr__pool_ll_make_subpool(USTR_POOL_NULL)); }
#include <stdarg.h>
USTR_CONF_I_PROTO
int ustr_pool_ll_cntl(struct Ustr_pool *p, int option, ...)
{
struct Ustr__pool_ll_base *sip = (struct Ustr__pool_ll_base *)p;
int ret = USTR_FALSE;
va_list ap;
va_start(ap, option);
switch (option)
{
case USTR_POOL_LL_CNTL_GET_FREE_CMP:
{
unsigned int *num = va_arg(ap, unsigned int *);
*num = sip->free_num;
ret = USTR_TRUE;
}
break;
case USTR_POOL_LL_CNTL_SET_FREE_CMP:
{
unsigned int num = va_arg(ap, unsigned int);
USTR_ASSERT_RET((num <= 65535), USTR_FALSE);
sip->free_num = num;
ret = USTR_TRUE;
}
break;
case USTR_POOL_LL_CNTL_GET_REALLOC:
{
int *toggle = va_arg(ap, int *);
*toggle = sip->call_realloc;
ret = USTR_TRUE;
}
break;
case USTR_POOL_LL_CNTL_SET_REALLOC:
{
int toggle = va_arg(ap, int);
USTR_ASSERT_RET((toggle == !!toggle), USTR_FALSE);
sip->call_realloc = toggle;
ret = USTR_TRUE;
}
break;
}
USTR_ASSERT(ret);
va_end(ap);
return (ret);
}
USTR_CONF_I_PROTO struct Ustr_pool *ustr_pool_make_pool(void)
{ return (ustr__pool_ll_make_subpool(USTR_POOL_NULL)); }