1 #include "lib/mlrutil.h"
2 #include "containers/sllmv.h"
3 
4 // ----------------------------------------------------------------
sllmv_alloc()5 sllmv_t* sllmv_alloc() {
6 	sllmv_t* plist = mlr_malloc_or_die(sizeof(sllmv_t));
7 	plist->phead  = NULL;
8 	plist->ptail  = NULL;
9 	plist->length = 0;
10 	return plist;
11 }
12 
13 // ----------------------------------------------------------------
sllmv_free(sllmv_t * plist)14 void sllmv_free(sllmv_t* plist) {
15 	if (plist == NULL)
16 		return;
17 	sllmve_t* pnode = plist->phead;
18 	while (pnode != NULL) {
19 		sllmve_t* pdel = pnode;
20 		pnode = pnode->pnext;
21 		if (pdel->free_flags & FREE_ENTRY_VALUE)
22 			mv_free(&pdel->value);
23 		free(pdel);
24 	}
25 	plist->phead  = NULL;
26 	plist->ptail  = 0;
27 	plist->length = 0;
28 
29 	free(plist);
30 }
31 
32 // ----------------------------------------------------------------
33 // Mlrvals are small structs and we do struct assignment from argument
34 // to list storage. For all but string mlrvals, this is a copy.
35 // For string mlrvals, it is pointer assignment without string duplication.
36 // This is intentional (for performance); callees are advised.
37 
sllmv_append(sllmv_t * plist,mv_t * pvalue,char free_flags)38 static void sllmv_append(sllmv_t* plist, mv_t* pvalue, char free_flags) {
39 	sllmve_t* pnode = mlr_malloc_or_die(sizeof(sllmve_t));
40 	pnode->value = *pvalue; // struct assignment
41 	pnode->free_flags = free_flags;
42 	if (plist->ptail == NULL) {
43 		pnode->pnext = NULL;
44 		plist->phead = pnode;
45 		plist->ptail = pnode;
46 	} else {
47 		pnode->pnext = NULL;
48 		plist->ptail->pnext = pnode;
49 		plist->ptail = pnode;
50 	}
51 	plist->length++;
52 }
53 
sllmv_append_with_free(sllmv_t * plist,mv_t * pvalue)54 void sllmv_append_with_free(sllmv_t* plist, mv_t* pvalue) {
55 	sllmv_append(plist, pvalue, FREE_ENTRY_VALUE);
56 }
57 
sllmv_append_no_free(sllmv_t * plist,mv_t * pvalue)58 void sllmv_append_no_free(sllmv_t* plist, mv_t* pvalue) {
59 	sllmv_append(plist, pvalue, NO_FREE);
60 }
61 
sllmv_prepend(sllmv_t * plist,mv_t * pvalue,char free_flags)62 static void sllmv_prepend(sllmv_t* plist, mv_t* pvalue, char free_flags) {
63 	sllmve_t* pnode = mlr_malloc_or_die(sizeof(sllmve_t));
64 	pnode->value = *pvalue; // struct assignment
65 	pnode->free_flags = free_flags;
66 	pnode->value = *pvalue; // struct assignment
67 	if (plist->ptail == NULL) {
68 		pnode->pnext = NULL;
69 		plist->phead = pnode;
70 		plist->ptail = pnode;
71 	} else {
72 		pnode->pnext = plist->phead;
73 		plist->phead = pnode;
74 	}
75 	plist->length++;
76 }
77 
sllmv_prepend_with_free(sllmv_t * plist,mv_t * pvalue)78 void sllmv_prepend_with_free(sllmv_t* plist, mv_t* pvalue) {
79 	sllmv_prepend(plist, pvalue, FREE_ENTRY_VALUE);
80 }
81 
sllmv_prepend_no_free(sllmv_t * plist,mv_t * pvalue)82 void sllmv_prepend_no_free(sllmv_t* plist, mv_t* pvalue) {
83 	sllmv_prepend(plist, pvalue, NO_FREE);
84 }
85 
86 // ----------------------------------------------------------------
sllmv_single_no_free(mv_t * pvalue)87 sllmv_t* sllmv_single_no_free(mv_t* pvalue) {
88 	sllmv_t* psllmv = sllmv_alloc();
89 	sllmv_append_no_free(psllmv, pvalue);
90 	return psllmv;
91 }
92 
sllmv_single_with_free(mv_t * pvalue)93 sllmv_t* sllmv_single_with_free(mv_t* pvalue) {
94 	sllmv_t* psllmv = sllmv_alloc();
95 	sllmv_append_with_free(psllmv, pvalue);
96 	return psllmv;
97 }
98 
sllmv_double_with_free(mv_t * pvalue1,mv_t * pvalue2)99 sllmv_t* sllmv_double_with_free(mv_t* pvalue1, mv_t* pvalue2) {
100 	sllmv_t* psllmv = sllmv_alloc();
101 	sllmv_append_with_free(psllmv, pvalue1);
102 	sllmv_append_with_free(psllmv, pvalue2);
103 	return psllmv;
104 }
105 
sllmv_triple_with_free(mv_t * pvalue1,mv_t * pvalue2,mv_t * pvalue3)106 sllmv_t* sllmv_triple_with_free(mv_t* pvalue1, mv_t* pvalue2, mv_t* pvalue3) {
107 	sllmv_t* psllmv = sllmv_alloc();
108 	sllmv_append_with_free(psllmv, pvalue1);
109 	sllmv_append_with_free(psllmv, pvalue2);
110 	sllmv_append_with_free(psllmv, pvalue3);
111 	return psllmv;
112 }
113 
sllmv_quadruple_with_free(mv_t * pvalue1,mv_t * pvalue2,mv_t * pvalue3,mv_t * pvalue4)114 sllmv_t* sllmv_quadruple_with_free(mv_t* pvalue1, mv_t* pvalue2, mv_t* pvalue3, mv_t* pvalue4) {
115 	sllmv_t* psllmv = sllmv_alloc();
116 	sllmv_append_with_free(psllmv, pvalue1);
117 	sllmv_append_with_free(psllmv, pvalue2);
118 	sllmv_append_with_free(psllmv, pvalue3);
119 	sllmv_append_with_free(psllmv, pvalue4);
120 	return psllmv;
121 }
122 
123 // ----------------------------------------------------------------
sllmv_print(sllmv_t * plist)124 void sllmv_print(sllmv_t* plist) {
125 	sllmve_tail_print(plist->phead);
126 }
127 
sllmve_tail_print(sllmve_t * pnode)128 void sllmve_tail_print(sllmve_t* pnode) {
129 	printf("[");
130 	int i = 0;
131 	for (sllmve_t* pe = pnode; pe != NULL; pe = pe->pnext, i++) {
132 		char* string = mv_alloc_format_val(&pe->value);
133 		if (i > 0)
134 			printf(", ");
135 		printf(" ");
136 		printf("%s", string);
137 		free(string);
138 	}
139 	printf("]\n");
140 }
141