mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-24 00:18:39 +00:00
140 lines
3.8 KiB
C
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");
|
|
}
|