Had some issues with the first version that annoyed me, so I rebuilt it with the ideas and techniques I already had. Seems to work just fine, there are some other functions that I'd like to add in the future, such as adding different lists together, or adding an item to a specific point in the list. But I can always improve it peicemeal.
Next I'm gonna build some other data things, such as a stack, on top of this and go from there :P
Any feedback of design, technique would be good. ( pasting this over from the source is telling me to stop using tabs and change to spaces )
header:
Code:
/* sllist.h
may 4/2011
deepcode
version 2.0
header for sllist version 2. */
#ifndef SL_LIST_H
#define SL_LIST_H
#define SL_SUCCESS 0
#define SL_ERROR -1
struct sl_node {
void *object;
size_t size;
struct sl_node *next;
};
struct sl_header {
struct sl_node *head;
struct sl_node *tail;
};
struct sl_memory {
unsigned long int header_memory;
unsigned long int data_memory;
};
typedef struct sl_node SL_LIST_NODE;
typedef struct sl_header SL_LIST;
typedef struct sl_memory SL_MEMORY;
int sl_create_list ( SL_LIST ** );
int sl_destroy_list ( SL_LIST ** );
void sl_display_list ( const SL_LIST *list );
int sl_add_head ( SL_LIST *, const void *, const size_t );
int sl_add_tail ( SL_LIST *, const void *, const size_t );
int sl_count_items ( const SL_LIST * );
void * sl_get_item ( const SL_LIST *, int );
int sl_update_item ( const SL_LIST *, int, void *, size_t );
int sl_remove_item ( SL_LIST *, int );
int sl_get_mem ( const SL_LIST *, SL_MEMORY * );
#endif
source
Code:
/* sllist.c
may 4/2011
deepcode
version 2.0
Module for management of single linked lists. */
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "sllist.h"
#ifdef VDEBUG
#include <stdio.h>
#endif
int sl_get_mem ( const SL_LIST *list, SL_MEMORY *mem ) {
SL_LIST_NODE *tmp;
if( list != NULL ) {
if( mem != NULL ) {
mem->header_memory = 0;
mem->data_memory = 0;
if( list->head != NULL ) {
mem->header_memory += sizeof *list;
tmp = list->head;
do {
mem->header_memory += sizeof *tmp;
mem->data_memory += tmp->size;
tmp = tmp->next;
} while ( tmp != NULL );
return SL_SUCCESS;
}
mem->header_memory += sizeof *list;
mem->data_memory = 0;
return SL_SUCCESS;
}
}
return SL_ERROR;
}
/* Finished. */
int sl_remove_item ( SL_LIST *list, int node ) {
SL_LIST_NODE *tmp = NULL;
SL_LIST_NODE *front = NULL;
SL_LIST_NODE *back = NULL;
int record = 1;
if( node > 0) {
if( list != NULL ) {
if( list->head != NULL ) {
tmp = list->head;
if( node == 1 ) {
if( tmp->next == NULL ) {
free( tmp->object );
free( tmp );
list->head = NULL;
list->tail = NULL;
return SL_SUCCESS;
}
back = tmp->next;
free( tmp->object );
free( tmp );
list->head = back;
return SL_SUCCESS;
}
do {
if( record == ( node - 1 ) ) {
front = tmp;
if( tmp->next == NULL ) {
return SL_ERROR;
}
tmp = tmp->next;
if( tmp->next == NULL ) {
front->next = NULL;
list->tail = front;
free( tmp->object );
free( tmp );
return SL_SUCCESS;
}
back = tmp->next;
front->next = back;
free ( tmp->object );
free ( tmp );
return SL_SUCCESS;
}
tmp = tmp->next;
record++;
} while ( tmp != NULL );
}
}
}
return SL_ERROR;
}
/* Finished. */
int sl_update_item ( const SL_LIST *list, int node, void *object, size_t size) {
SL_LIST_NODE *tmp = NULL;
void *mem = NULL;
int record = 1;
if( node > 0 ) {
if( list != NULL ) {
if ( list->head != NULL ) {
tmp = list->head;
while( tmp != NULL ) {
if( record == node ) {
if( (mem = realloc(tmp->object, size)) != NULL) {
mem = memcpy(mem, object, size);
tmp->object = mem;
tmp->size = size;
return SL_SUCCESS;
}
break;
}
record++;
tmp = tmp->next;
}
}
}
}
return SL_ERROR;
}
/* Finished */
void * sl_get_item ( const SL_LIST *list, int node ) {
SL_LIST_NODE *tmp;
int record = 0;
if( node > 0 ) {
if( list != NULL ) {
if( list->head != NULL ) {
tmp = list->head;
do {
record++;
if( record == node ) {
return tmp->object;
}
tmp = tmp->next;
} while( tmp != NULL );
}
}
}
return NULL;
}
/* Finished. */
int sl_count_items ( const SL_LIST *list ) {
SL_LIST_NODE *tmp = NULL;
int records = 1;
if( list != NULL ) {
if( list->head != NULL ) {
tmp = list->head;
while( tmp->next != NULL ) {
records++;
tmp = tmp->next;
}
return records;
}
return 0;
}
return SL_ERROR;
}
/* Finished */
int sl_add_tail ( SL_LIST *list, const void *object, const size_t size ) {
SL_LIST_NODE *tmp = NULL;
void *mem = NULL;
if( list != NULL ) {
if( (mem = malloc(size)) != NULL ) {
if( (tmp = malloc(sizeof *tmp)) != NULL ) {
mem = memcpy(mem, object, size);
tmp->next = NULL;
tmp->size = size;
tmp->object = mem;
if( list->tail != NULL ) {
list->tail->next = tmp;
}
list->tail = tmp;
return SL_SUCCESS;
}
free(mem);
}
}
return SL_ERROR;
}
/* Finished. */
int sl_add_head ( SL_LIST *list, const void *object, const size_t size ) {
SL_LIST_NODE *tmp = NULL;
void *mem = NULL;
if( list != NULL ) {
if( (mem = malloc(size)) != NULL ) {
if( (tmp = malloc(sizeof *tmp)) != NULL ) {
mem = memcpy(mem, object, size);
tmp->next = list->head;
tmp->size = size;
tmp->object = mem;
list->head = tmp;
if( list->tail == NULL ) {
list->tail = tmp;
}
return SL_SUCCESS;
}
free(mem);
}
}
return SL_ERROR;
}
/* Finished. */
int sl_create_list ( SL_LIST **list ) {
SL_LIST *tmp = NULL;
if( *list == NULL ) {
tmp = malloc( sizeof(SL_LIST) );
if( tmp != NULL ) {
tmp->head = NULL;
tmp->tail = NULL;
*list = tmp;
return SL_SUCCESS;
}
}
return SL_ERROR;
}
/* Finished */
int sl_destroy_list ( SL_LIST **list ) {
SL_LIST_NODE *tmp = NULL;
if( *list != NULL ) {
if( (*list)->head != NULL ) {
do {
tmp = (*list)->head->next;
free( (*list)->head->object );
free( (*list)->head );
(*list)->head = tmp;
} while( tmp != NULL );
}
free( *list );
*list = NULL;
return SL_SUCCESS;
}
return SL_ERROR;
}
#ifdef VDEBUG
/* Finished. */
void sl_display_list( const SL_LIST *list ) {
SL_LIST_NODE *tmp = NULL;
SL_LIST_NODE *tmphead = NULL;
unsigned char *data = NULL;
unsigned int records = 0;
size_t size = 0;
if( list != NULL ) {
tmphead = list->head;
if( list->head != NULL ) {
records++;
do {
tmp = tmphead->next;
data = tmphead->object;
printf("Node: %d\n", records);
for( size = tmphead->size ; size > 0 ; size-- ) {
printf("%c", *data);
data++;
}
printf("\n");
records++;
tmphead = tmp;
} while ( tmp != NULL );
return;
}
printf("No nodes in the list.\n");
return;
}
printf("No list.\n");
}
#endif