|
@@ -0,0 +1,172 @@
|
|
|
|
|
+#include "toolbox/list/sll.h"
|
|
|
|
|
+
|
|
|
|
|
+#include <stddef.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+#include <string.h>
|
|
|
|
|
+#include <strings.h>
|
|
|
|
|
+
|
|
|
|
|
+#include "toolbox/errcode.h"
|
|
|
|
|
+#include "toolbox/errno.h"
|
|
|
|
|
+#include "toolbox/log.h"
|
|
|
|
|
+
|
|
|
|
|
+#define TEST_FOR_NULL(POINTER) \
|
|
|
|
|
+ if ( POINTER == NULL ) { \
|
|
|
|
|
+ LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
|
|
+ toolbox_errno = RET_EVN; \
|
|
|
|
|
+ return toolbox_errno; \
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+#define TEST_FOR_NULL_SR(POINTER, RET) \
|
|
|
|
|
+ if ( POINTER == NULL ) { \
|
|
|
|
|
+ LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
|
|
+ toolbox_errno = RET_EVN; \
|
|
|
|
|
+ return RET; \
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+struct sll *
|
|
|
|
|
+sll_create(void) {
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ struct sll *ret = malloc(sizeof(struct sll));
|
|
|
|
|
+ bzero(ret, sizeof(struct sll));
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static RET_TYPE
|
|
|
|
|
+m_sll_item_free(void *item, size_t item_size) {
|
|
|
|
|
+ (void) item_size;
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ TEST_FOR_NULL(item);
|
|
|
|
|
+
|
|
|
|
|
+ free(item);
|
|
|
|
|
+
|
|
|
|
|
+ return RET_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+RET_TYPE
|
|
|
|
|
+sll_destroy(struct sll **self) {
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ sll_for_each(*self, m_sll_item_free);
|
|
|
|
|
+
|
|
|
|
|
+ free(*self);
|
|
|
|
|
+
|
|
|
|
|
+ *self = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ return RET_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+RET_TYPE
|
|
|
|
|
+sll_insert(struct sll *restrict self
|
|
|
|
|
+ , const void *restrict item, const size_t item_size
|
|
|
|
|
+ , const size_t index) {
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ TEST_FOR_NULL(self);
|
|
|
|
|
+ TEST_FOR_NULL(item);
|
|
|
|
|
+
|
|
|
|
|
+ size_t z = 0;
|
|
|
|
|
+ struct sll_item *tmp = NULL;
|
|
|
|
|
+ size_t tmp_index = index - 1;
|
|
|
|
|
+
|
|
|
|
|
+ if ( self->head == NULL )
|
|
|
|
|
+ self->head = malloc(sizeof(struct sll_item));
|
|
|
|
|
+
|
|
|
|
|
+ if ( self->size > index ) {
|
|
|
|
|
+ self->size = index;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ++self->size;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tmp = self->head;
|
|
|
|
|
+ for ( z = 0; z < self->size; ++z ) {
|
|
|
|
|
+
|
|
|
|
|
+ if ( z == tmp_index ) {
|
|
|
|
|
+ tmp->item = malloc(item_size);
|
|
|
|
|
+ memcpy((void *) tmp->item, item, item_size);
|
|
|
|
|
+ memcpy((void *) tmp->size, &item_size, sizeof(size_t));
|
|
|
|
|
+ goto exit_ok;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ( tmp->next == NULL )
|
|
|
|
|
+ tmp->next = malloc(sizeof(struct sll_item));
|
|
|
|
|
+
|
|
|
|
|
+ tmp = tmp->next;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+exit_ok:
|
|
|
|
|
+ return RET_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+RET_TYPE
|
|
|
|
|
+sll_append(struct sll *restrict self
|
|
|
|
|
+ , const void *restrict item, const size_t item_size) {
|
|
|
|
|
+ struct sll_item *tmp = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ TEST_FOR_NULL(self);
|
|
|
|
|
+ TEST_FOR_NULL(item);
|
|
|
|
|
+
|
|
|
|
|
+ if ( self->head == NULL )
|
|
|
|
|
+ self->head = malloc(sizeof(struct sll_item));
|
|
|
|
|
+
|
|
|
|
|
+ tmp = self->head;
|
|
|
|
|
+
|
|
|
|
|
+ while ( tmp->item != NULL && tmp->size != 0 )
|
|
|
|
|
+ tmp = tmp->next;
|
|
|
|
|
+
|
|
|
|
|
+ tmp->item = malloc(item_size);
|
|
|
|
|
+ memcpy((void *) tmp->item, item, item_size);
|
|
|
|
|
+ memcpy((void *) tmp->size, &item_size, sizeof(size_t));
|
|
|
|
|
+
|
|
|
|
|
+ return RET_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+struct vptr
|
|
|
|
|
+sll_remove(struct sll *self, const size_t index) {
|
|
|
|
|
+ struct sll_item *tmp = NULL;
|
|
|
|
|
+ struct vptr ret = {.data=NULL,.size=0};
|
|
|
|
|
+ size_t z = 0;
|
|
|
|
|
+
|
|
|
|
|
+ toolbox_errno = RET_OK;
|
|
|
|
|
+
|
|
|
|
|
+ TEST_FOR_NULL_SR(self, ret);
|
|
|
|
|
+
|
|
|
|
|
+ if ( index > self->size ) {
|
|
|
|
|
+ toolbox_errno = RET_EVBTS;
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tmp = self->head;
|
|
|
|
|
+ for ( z = 0; z < index - 1; ++z ) {
|
|
|
|
|
+ tmp = tmp->next;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret.data = (void *) tmp->next->item;
|
|
|
|
|
+ ret.size = tmp->next->size;
|
|
|
|
|
+
|
|
|
|
|
+ tmp->next = tmp->next->next;
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+struct vptr
|
|
|
|
|
+sll_get(struct sll *self, const size_t index);
|
|
|
|
|
+
|
|
|
|
|
+RET_TYPE
|
|
|
|
|
+sll_for_each(struct sll *self, RET_TYPE (*for_each)(void *, size_t)) {
|
|
|
|
|
+ struct sll_item *t = self->head;
|
|
|
|
|
+
|
|
|
|
|
+ do {
|
|
|
|
|
+ for_each(t->item, t->size);
|
|
|
|
|
+ t = t->next;
|
|
|
|
|
+ } while ( t != NULL );
|
|
|
|
|
+
|
|
|
|
|
+ return RET_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#undef TEST_FOR_NULL_SR
|
|
|
|
|
+#undef TEST_FOR_NULL
|