miller/c/containers/sllmv.c
2016-11-13 23:00:30 -05:00

140 lines
3.8 KiB
C

#include "lib/mlrutil.h"
#include "containers/sllmv.h"
// ----------------------------------------------------------------
sllmv_t* sllmv_alloc() {
sllmv_t* plist = mlr_malloc_or_die(sizeof(sllmv_t));
plist->phead = NULL;
plist->ptail = NULL;
plist->length = 0;
return plist;
}
// ----------------------------------------------------------------
void sllmv_free(sllmv_t* plist) {
if (plist == NULL)
return;
sllmve_t* pnode = plist->phead;
while (pnode != NULL) {
sllmve_t* pdel = pnode;
pnode = pnode->pnext;
if (pdel->free_flags & FREE_ENTRY_VALUE)
mv_free(&pdel->value);
free(pdel);
}
plist->phead = NULL;
plist->ptail = 0;
plist->length = 0;
free(plist);
}
// ----------------------------------------------------------------
// Mlrvals are small structs and we do struct assignment from argument
// to list storage. For all but string mlrvals, this is a copy.
// For string mlrvals, it is pointer assignment without string duplication.
// This is intentional (for performance); callees are advised.
static void sllmv_append(sllmv_t* plist, mv_t* pvalue, char free_flags) {
sllmve_t* pnode = mlr_malloc_or_die(sizeof(sllmve_t));
pnode->value = *pvalue; // struct assignment
pnode->free_flags = free_flags;
if (plist->ptail == NULL) {
pnode->pnext = NULL;
plist->phead = pnode;
plist->ptail = pnode;
} else {
pnode->pnext = NULL;
plist->ptail->pnext = pnode;
plist->ptail = pnode;
}
plist->length++;
}
void sllmv_append_with_free(sllmv_t* plist, mv_t* pvalue) {
sllmv_append(plist, pvalue, FREE_ENTRY_VALUE);
}
void sllmv_append_no_free(sllmv_t* plist, mv_t* pvalue) {
sllmv_append(plist, pvalue, NO_FREE);
}
static void sllmv_prepend(sllmv_t* plist, mv_t* pvalue, char free_flags) {
sllmve_t* pnode = mlr_malloc_or_die(sizeof(sllmve_t));
pnode->value = *pvalue; // struct assignment
pnode->free_flags = free_flags;
pnode->value = *pvalue; // struct assignment
if (plist->ptail == NULL) {
pnode->pnext = NULL;
plist->phead = pnode;
plist->ptail = pnode;
} else {
pnode->pnext = plist->phead;
plist->phead = pnode;
}
plist->length++;
}
void sllmv_prepend_with_free(sllmv_t* plist, mv_t* pvalue) {
sllmv_prepend(plist, pvalue, FREE_ENTRY_VALUE);
}
void sllmv_prepend_no_free(sllmv_t* plist, mv_t* pvalue) {
sllmv_prepend(plist, pvalue, NO_FREE);
}
// ----------------------------------------------------------------
sllmv_t* sllmv_single_no_free(mv_t* pvalue) {
sllmv_t* psllmv = sllmv_alloc();
sllmv_append_no_free(psllmv, pvalue);
return psllmv;
}
sllmv_t* sllmv_single_with_free(mv_t* pvalue) {
sllmv_t* psllmv = sllmv_alloc();
sllmv_append_with_free(psllmv, pvalue);
return psllmv;
}
sllmv_t* sllmv_double_with_free(mv_t* pvalue1, mv_t* pvalue2) {
sllmv_t* psllmv = sllmv_alloc();
sllmv_append_with_free(psllmv, pvalue1);
sllmv_append_with_free(psllmv, pvalue2);
return psllmv;
}
sllmv_t* sllmv_triple_with_free(mv_t* pvalue1, mv_t* pvalue2, mv_t* pvalue3) {
sllmv_t* psllmv = sllmv_alloc();
sllmv_append_with_free(psllmv, pvalue1);
sllmv_append_with_free(psllmv, pvalue2);
sllmv_append_with_free(psllmv, pvalue3);
return psllmv;
}
sllmv_t* sllmv_quadruple_with_free(mv_t* pvalue1, mv_t* pvalue2, mv_t* pvalue3, mv_t* pvalue4) {
sllmv_t* psllmv = sllmv_alloc();
sllmv_append_with_free(psllmv, pvalue1);
sllmv_append_with_free(psllmv, pvalue2);
sllmv_append_with_free(psllmv, pvalue3);
sllmv_append_with_free(psllmv, pvalue4);
return psllmv;
}
// ----------------------------------------------------------------
void sllmv_print(sllmv_t* plist) {
sllmve_tail_print(plist->phead);
}
void sllmve_tail_print(sllmve_t* pnode) {
printf("[");
int i = 0;
for (sllmve_t* pe = pnode; pe != NULL; pe = pe->pnext, i++) {
char* string = mv_alloc_format_val(&pe->value);
if (i > 0)
printf(", ");
printf(" ");
printf("%s", string);
free(string);
}
printf("]\n");
}