Initial commit list

generic linked list
This commit is contained in:
Michael Tryby
2019-04-09 14:26:33 -04:00
parent 8b4727eac5
commit 30f0def02a
5 changed files with 265 additions and 2 deletions

View File

@@ -9,7 +9,7 @@ EPANET {#epanet-readme}
## For EPANET-related questions and discussion
For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet).
For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet).
## What is on this Repository?
The EPANET Library is a pressurized pipe network hydraulic and water quality analysis toolkit written in C. If you are interested in using/extending EPANET for academic, personal, or commercial use, then you've come to the right place.

124
src/util/list.c Normal file
View File

@@ -0,0 +1,124 @@
//
// Author: David Muto
// https://gist.github.com/pseudomuto/6334796#file-list-c
//
// Modified by:
// Michael E. Tryby
// US EPA ORD
//
// Accessed on: April 9, 2019
//
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "list.h"
list_t *create_list(int elementSize, freeFunction freeFn)
{
list_t *list;
list = (list_t *)calloc(1, sizeof(list_t));
assert(elementSize > 0);
list->logicalLength = 0;
list->elementSize = elementSize;
list->head = list->tail = NULL;
list->freeFn = freeFn;
return list;
}
void delete_list(list_t *list)
{
listNode *current;
while(list->head != NULL) {
current = list->head;
list->head = current->next;
if (list->freeFn) {
list->freeFn(current->data);
}
free(current->data);
free(current);
}
free(list);
}
void prepend_list(list_t *list, void *element)
{
listNode *node = malloc(sizeof(listNode));
node->data = malloc(list->elementSize);
memcpy(node->data, element, list->elementSize);
node->next = list->head;
list->head = node;
// first node?
if(!list->tail) {
list->tail = list->head;
}
list->logicalLength++;
}
void append_list(list_t *list, void *element)
{
listNode *node = malloc(sizeof(listNode));
node->data = malloc(list->elementSize);
node->next = NULL;
memcpy(node->data, element, list->elementSize);
if(list->logicalLength == 0) {
list->head = list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
list->logicalLength++;
}
void for_each_list(list_t *list, listIterator iterator)
{
assert(iterator != NULL);
listNode *node = list->head;
bool result = true;
while(node != NULL && result) {
result = iterator(node->data);
node = node->next;
}
}
void head_list(list_t *list, void *element, bool removeFromList)
{
assert(list->head != NULL);
listNode *node = list->head;
memcpy(element, node->data, list->elementSize);
if(removeFromList) {
list->head = node->next;
list->logicalLength--;
free(node->data);
free(node);
}
}
void tail_list(list_t *list, void *element)
{
assert(list->tail != NULL);
listNode *node = list->tail;
memcpy(element, node->data, list->elementSize);
}
int size_list(list_t *list)
{
return list->logicalLength;
}

59
src/util/list.h Normal file
View File

@@ -0,0 +1,59 @@
//
// Author: David Muto
// https://gist.github.com/pseudomuto/6334796#file-list-h
//
// Modified by:
// Michael E. Tryby
// US EPA ORD
//
// Accessed on: April 9, 2019
//
#ifndef LIST_H
#define LIST_H
#include <stdbool.h>
#if defined(__cplusplus)
extern "C" {
#endif
// a common function used to free malloc'd objects
typedef void(*freeFunction)(void *);
typedef bool (*listIterator)(void *);
typedef struct _listNode {
void *data;
struct _listNode *next;
} listNode;
typedef struct {
int logicalLength;
int elementSize;
listNode *head;
listNode *tail;
freeFunction freeFn;
} list_t;
list_t *create_list(int elementSize, freeFunction freeFn);
void delete_list(list_t *list);
void prepend_list(list_t *list, void *element);
void append_list(list_t *list, void *element);
int size_list(list_t *list);
void for_each_list(list_t *list, listIterator iterator);
void head_list(list_t *list, void *element, bool removeFromList);
void tail_list(list_t *list, void *element);
#if defined(__cplusplus)
}
#endif
#endif /* LIST_H */

View File

@@ -7,7 +7,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
add_executable(test_errormanager ./test_errormanager.cpp
add_executable(test_errormanager ./test_errormanager.cpp
../../src/util/errormanager.c)
target_include_directories(test_errormanager PUBLIC ../../src/)
target_link_libraries(test_errormanager ${Boost_LIBRARIES})
@@ -18,3 +18,9 @@ add_executable(test_filemanager ./test_filemanager.cpp
../../src/util/cstr_helper.c)
target_include_directories(test_filemanager PUBLIC ../../src/)
target_link_libraries(test_filemanager ${Boost_LIBRARIES})
add_executable(test_list ./test_list.cpp
../../src/util/list.c)
target_include_directories(test_list PUBLIC ../../src/)
target_link_libraries(test_list ${Boost_LIBRARIES})

74
tests/util/test_list.cpp Normal file
View File

@@ -0,0 +1,74 @@
/*
******************************************************************************
Project: OWA EPANET
Version: 2.2
Module: util/test_list.cpp
Description: Tests for util/list.c
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 04/09/2019
******************************************************************************
*/
#define BOOST_TEST_MODULE list
#include <boost/test/unit_test.hpp>
#include "util/list.h"
bool iterate_int(void *data)
{
printf("Found value: %d\n", *(int *)data);
return true;
}
BOOST_AUTO_TEST_SUITE(test_list)
BOOST_AUTO_TEST_CASE(test_create_delete) {
list_t *list;
list = create_list(sizeof(int), NULL);
delete_list(list);
}
struct Fixture{
Fixture() {
list = NULL;
list = create_list(sizeof(int), NULL);
}
~Fixture() {
delete_list(list);
}
list_t *list;
};
BOOST_FIXTURE_TEST_CASE(test_list_append, Fixture){
int i, numbers = 10;
for(i = 1; i <= numbers; i++) {
append_list(list, &i);
}
BOOST_CHECK(size_list(list) == 10);
}
BOOST_FIXTURE_TEST_CASE(test_list_foreach, Fixture) {
int i, numbers = 10;
for (i = 1; i <= numbers; i++) {
append_list(list, &i);
}
for_each_list(list, iterate_int);
}
BOOST_AUTO_TEST_SUITE_END()