1 #include "lib/mlrutil.h"
2 #include "containers/sllv.h"
3 
4 // ----------------------------------------------------------------
sllv_alloc()5 sllv_t* sllv_alloc() {
6 	sllv_t* plist = mlr_malloc_or_die(sizeof(sllv_t));
7 	plist->phead  = NULL;
8 	plist->ptail  = NULL;
9 	plist->length = 0;
10 	return plist;
11 }
12 
13 // ----------------------------------------------------------------
sllv_free(sllv_t * plist)14 void sllv_free(sllv_t* plist) {
15 	if (plist == NULL)
16 		return;
17 	sllve_t* pnode = plist->phead;
18 	while (pnode != NULL) {
19 		sllve_t* pdel = pnode;
20 		pnode = pnode->pnext;
21 		free(pdel);
22 	}
23 	plist->phead  = NULL;
24 	plist->ptail  = 0;
25 	plist->length = 0;
26 
27 	free(plist);
28 }
29 
30 // ----------------------------------------------------------------
sllv_single(void * pvvalue)31 sllv_t* sllv_single(void* pvvalue) {
32 	sllv_t* psllv = sllv_alloc();
33 	sllv_append(psllv, pvvalue);
34 	return psllv;
35 }
36 
37 // ----------------------------------------------------------------
sllv_append(sllv_t * plist,void * pvvalue)38 void sllv_append(sllv_t* plist, void* pvvalue) {
39 	sllve_t* pnode = mlr_malloc_or_die(sizeof(sllve_t));
40 	pnode->pvvalue = pvvalue;
41 	if (plist->ptail == NULL) {
42 		pnode->pnext = NULL;
43 		plist->phead = pnode;
44 		plist->ptail = pnode;
45 	} else {
46 		pnode->pnext = NULL;
47 		plist->ptail->pnext = pnode;
48 		plist->ptail = pnode;
49 	}
50 	plist->length++;
51 }
52 
53 // ----------------------------------------------------------------
sllv_push(sllv_t * plist,void * pvvalue)54 void sllv_push(sllv_t* plist, void* pvvalue) {
55 	sllve_t* pnode = mlr_malloc_or_die(sizeof(sllve_t));
56 	pnode->pvvalue = pvvalue;
57 	if (plist->ptail == NULL) {
58 		pnode->pnext = NULL;
59 		plist->phead = pnode;
60 		plist->ptail = pnode;
61 	} else {
62 		pnode->pnext = plist->phead;
63 		plist->phead = pnode;
64 	}
65 	plist->length++;
66 }
67 
68 // ----------------------------------------------------------------
sllv_pop(sllv_t * plist)69 void* sllv_pop(sllv_t* plist) {
70 	// Zero entries in list
71 	if (plist->phead == NULL)
72 		return NULL;
73 
74 	void* pval = plist->phead->pvvalue;
75 	// One entry in list
76 	if (plist->phead->pnext == NULL) {
77 		free(plist->phead);
78 		plist->phead  = NULL;
79 		plist->ptail  = NULL;
80 		plist->length = 0;
81 	}
82 	// Two or more entries in list
83 	else {
84 		sllve_t* pnext = plist->phead->pnext;
85 		free(plist->phead);
86 		plist->phead = pnext;
87 		plist->length--;
88 	}
89 
90 	return pval;
91 }
92 
93 // ----------------------------------------------------------------
sllv_reverse(sllv_t * plist)94 void sllv_reverse(sllv_t* plist) {
95 	if (plist->phead == NULL)
96 		return;
97 
98 	sllve_t* pnewhead = NULL;
99 	sllve_t* pnewtail = plist->phead;
100 	sllve_t* p = plist->phead;
101 	sllve_t* q = p->pnext;
102 	while (1) {
103 		p->pnext = pnewhead;
104 		pnewhead = p;
105 		if (q == NULL)
106 			break;
107 		p = q;
108 		q = p->pnext;
109 	}
110 	plist->phead = pnewhead;
111 	plist->ptail = pnewtail;
112 }
113 
sllv_transfer(sllv_t * pthis,sllv_t * pthat)114 void sllv_transfer(sllv_t* pthis, sllv_t* pthat) {
115 	if (pthat == NULL)
116 		return;
117 	if (pthis->phead == NULL) {
118 		pthis->phead  = pthat->phead;
119 		pthis->ptail  = pthat->ptail;
120 		pthis->length = pthat->length;
121 	} else if (pthat->phead != NULL) {
122 		pthis->ptail->pnext = pthat->phead;
123 		pthis->ptail = pthat->ptail;
124 		pthis->length += pthat->length;
125 	}
126 	pthat->phead  = NULL;
127 	pthat->ptail  = NULL;
128 	pthat->length = 0;
129 }
130