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