Kaynağa Gözat

[list/sll] Adding Untested Single Linked List

Vinicius Teshima 2 yıl önce
ebeveyn
işleme
d2bab766ee
2 değiştirilmiş dosya ile 226 ekleme ve 0 silme
  1. 54 0
      include/toolbox/list/sll.h
  2. 172 0
      src/toolbox/list/sll.c

+ 54 - 0
include/toolbox/list/sll.h

@@ -0,0 +1,54 @@
+#ifndef TOOLBOX_LIST_SLL_H
+#define TOOLBOX_LIST_SLL_H
+
+#include "toolbox/errcode.h"
+#include "toolbox/errno.h"
+#include "toolbox/vptr.h"
+#include <stddef.h>
+
+struct sll_item {
+	void *item;
+	const size_t size;
+	struct sll_item *next;
+};
+
+struct sll {
+	size_t size;
+	struct sll_item *head;
+};
+
+__attribute__((__pure__))
+struct sll *
+sll_create(void);
+
+RET_TYPE
+sll_destroy(struct sll **self);
+
+RET_TYPE
+sll_insert(struct sll *restrict self
+	   , const void *restrict item, const size_t item_size
+	   , const size_t index);
+
+RET_TYPE
+sll_append(struct sll *restrict self
+	   , const void *restrict item, const size_t item_size);
+
+struct vptr
+sll_remove(struct sll *self, const size_t index);
+
+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));
+
+#define sll_size(self)				\
+	(self->size)
+
+#define sll_pop(self)				\
+	sll_remove(self, ssl_size(self))
+
+#define sll_prepend(self, item, item_size)	\
+	sll_insert(self, item, item_size, 0)
+
+#endif

+ 172 - 0
src/toolbox/list/sll.c

@@ -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