Move tons of stuff into oldstuff/
This commit is contained in:
5
oldstuff/lcthw-remnants-2/liblcthw/.gitignore
vendored
Normal file
5
oldstuff/lcthw-remnants-2/liblcthw/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
tests/runtests
|
||||
tests/*_tests
|
||||
tests/**/*_tests
|
||||
bstrlib.c
|
||||
bstrlib.h
|
21
oldstuff/lcthw-remnants-2/liblcthw/LICENSE
Normal file
21
oldstuff/lcthw-remnants-2/liblcthw/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
Copyright (C) 2016 Dan Buch
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
76
oldstuff/lcthw-remnants-2/liblcthw/Makefile
Normal file
76
oldstuff/lcthw-remnants-2/liblcthw/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
BSTRLIB_BASE_URL ?= https://raw.githubusercontent.com/websnarf/bstrlib/208b1f2a4dfc96b806ed499bd1909e87ec15981d
|
||||
CFLAGS = -g -O2 -Wall -Wextra -Isrc -Lbuild -rdynamic -DNDEBUG $(OPTFLAGS)
|
||||
LDLIBS = -ldl $(OPTLIBS)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
FIND ?= find
|
||||
CD ?= cd
|
||||
PATCH ?= patch
|
||||
INSTALL ?= install
|
||||
MKDIR ?= mkdir -p
|
||||
CURL ?= curl -sSL
|
||||
RANLIB ?= ranlib
|
||||
RUNTESTS ?= ./tests/runtests
|
||||
|
||||
SOURCES = $(wildcard src/**/*.c src/*.c)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
TEST_SRC = $(wildcard tests/**/*_tests.c tests/*_tests.c)
|
||||
TESTS = $(patsubst %.c,%,$(TEST_SRC))
|
||||
|
||||
LIBNAME = lcthw
|
||||
TARGET = build/lib$(LIBNAME).a
|
||||
SO_TARGET = $(patsubst %.a,%.so,$(TARGET))
|
||||
|
||||
all: $(TARGET) $(SO_TARGET) tests
|
||||
|
||||
dev: CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
|
||||
dev: all
|
||||
|
||||
$(TARGET): CFLAGS += -fPIC
|
||||
$(TARGET): build $(OBJECTS)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(SO_TARGET): $(TARGET) $(OBJECTS)
|
||||
$(CC) -shared -o $@ $(OBJECTS)
|
||||
|
||||
build: bin src/lcthw/bstrlib.c src/lcthw/bstrlib.h
|
||||
@$(MKDIR) $@
|
||||
|
||||
bin:
|
||||
@$(MKDIR) $@
|
||||
|
||||
src/lcthw/bstrlib.c: src/lcthw/bstrlib.h
|
||||
$(CURL) -o $@ $(BSTRLIB_BASE_URL)/bstrlib.c
|
||||
$(CD) src/lcthw && $(PATCH) -p1 < bstrlib.patch
|
||||
|
||||
src/lcthw/bstrlib.h:
|
||||
$(CURL) -o $@ $(BSTRLIB_BASE_URL)/bstrlib.h
|
||||
|
||||
.PHONY: tests
|
||||
tests: LDLIBS += -static -l$(LIBNAME) -lbsd
|
||||
tests: $(RUNTESTS) $(TESTS)
|
||||
$(RUNTESTS) ./tests/lcthw
|
||||
|
||||
valgrind:
|
||||
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||
|
||||
clean:
|
||||
$(RM) -r build $(OBJECTS) $(TESTS)
|
||||
$(RM) tests/tests.log tests/runtests
|
||||
$(FIND) . -name "*.gc*" -exec rm {} \;
|
||||
$(RM) -r `find . -name "*.dSYM" -print`
|
||||
|
||||
distclean: clean
|
||||
$(RM) src/lcthw/bstrlib.c src/lcthw/bstrlib.h
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d $(DESTDIR)/$(PREFIX)/lib/
|
||||
$(INSTALL) $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
|
||||
|
||||
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
|
||||
check:
|
||||
@echo Files with potentially dangerous functions
|
||||
@egrep $(BADFUNCS) $(SOURCES) || true
|
0
oldstuff/lcthw-remnants-2/liblcthw/README.md
Normal file
0
oldstuff/lcthw-remnants-2/liblcthw/README.md
Normal file
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/bstrlib.patch
Normal file
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/bstrlib.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/bstrlib.c 2016-04-21 12:26:50.000000000 -0400
|
||||
+++ b/bstrlib.c 2016-04-21 12:27:59.000000000 -0400
|
||||
@@ -22,7 +22,8 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
-#include "bstrlib.h"
|
||||
+// PATCH to include adjacent bstrlib.h
|
||||
+#include <lcthw/bstrlib.h>
|
||||
|
||||
/* Optionally include a mechanism for debugging memory */
|
||||
|
116
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.c
Normal file
116
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <lcthw/darray.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
DArray *DArray_create(size_t element_size, size_t initial_max)
|
||||
{
|
||||
DArray *array = malloc(sizeof(DArray));
|
||||
check_mem(array);
|
||||
array->max = initial_max;
|
||||
check(array->max > 0, "You must set an initial_max > 0.");
|
||||
|
||||
array->contents = calloc(initial_max, sizeof(void *));
|
||||
check_mem(array->contents);
|
||||
|
||||
array->end = 0;
|
||||
array->element_size = element_size;
|
||||
array->expand_rate = DEFAULT_EXPAND_RATE;
|
||||
|
||||
return array;
|
||||
|
||||
error:
|
||||
if(array) free(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DArray_clear(DArray *array)
|
||||
{
|
||||
int i = 0;
|
||||
if(array->element_size > 0) {
|
||||
for(i = 0; i < array->max; i++) {
|
||||
if(array->contents[i] != NULL) {
|
||||
free(array->contents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int DArray_resize(DArray *array, size_t newsize)
|
||||
{
|
||||
array->max = newsize;
|
||||
check(array->max > 0, "The newsize must be > 0.");
|
||||
|
||||
void *contents = realloc(array->contents, array->max * sizeof(void *));
|
||||
|
||||
check_mem(contents);
|
||||
|
||||
array->contents = contents;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DArray_expand(DArray *array)
|
||||
{
|
||||
size_t old_max = array->max;
|
||||
check(DArray_resize(array, array->max + array->expand_rate) == 0,
|
||||
"Failed to expand array to new size: %d",
|
||||
array->max + (int)array->expand_rate);
|
||||
|
||||
memset(array->contents + old_max, 0, array->expand_rate + 1);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DArray_contract(DArray *array)
|
||||
{
|
||||
int new_size = array->end < (int)array->expand_rate ? (int)array->expand_rate : array->end;
|
||||
|
||||
return DArray_resize(array, new_size + 1);
|
||||
}
|
||||
|
||||
|
||||
void DArray_destroy(DArray *array)
|
||||
{
|
||||
if(array) {
|
||||
if(array->contents) free(array->contents);
|
||||
free(array);
|
||||
}
|
||||
}
|
||||
|
||||
void DArray_clear_destroy(DArray *array)
|
||||
{
|
||||
DArray_clear(array);
|
||||
DArray_destroy(array);
|
||||
}
|
||||
|
||||
int DArray_push(DArray *array, void *el)
|
||||
{
|
||||
array->contents[array->end] = el;
|
||||
array->end++;
|
||||
|
||||
if(DArray_end(array) >= DArray_max(array)) {
|
||||
return DArray_expand(array);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *DArray_pop(DArray *array)
|
||||
{
|
||||
check(array->end - 1 >= 0, "Attempt to pop from empty array.");
|
||||
|
||||
void *el = DArray_remove(array, array->end - 1);
|
||||
array->end--;
|
||||
|
||||
if(DArray_end(array) > (int)array->expand_rate && DArray_end(array) % array->expand_rate) {
|
||||
DArray_contract(array);
|
||||
}
|
||||
|
||||
return el;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
78
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.h
Normal file
78
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef lcthw_DArray_h
|
||||
#define lcthw_DArray_h
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
typedef struct DArray {
|
||||
int end;
|
||||
int max;
|
||||
size_t element_size;
|
||||
size_t expand_rate;
|
||||
void **contents;
|
||||
} DArray;
|
||||
|
||||
DArray *DArray_create(size_t element_size, size_t initial_max);
|
||||
|
||||
void DArray_destroy(DArray *array);
|
||||
|
||||
void DArray_clear(DArray *array);
|
||||
|
||||
int DArray_expand(DArray *array);
|
||||
|
||||
int DArray_contract(DArray *array);
|
||||
|
||||
int DArray_push(DArray *array, void *el);
|
||||
|
||||
void *DArray_pop(DArray *array);
|
||||
|
||||
void DArray_clear_destroy(DArray *array);
|
||||
|
||||
#define DArray_last(A) ((A)->contents[(A)->end - 1])
|
||||
#define DArray_first(A) ((A)->contents[0])
|
||||
#define DArray_end(A) ((A)->end)
|
||||
#define DArray_count(A) DArray_end(A)
|
||||
#define DArray_max(A) ((A)->max)
|
||||
|
||||
#define DEFAULT_EXPAND_RATE 300
|
||||
|
||||
|
||||
static inline void DArray_set(DArray *array, int i, void *el)
|
||||
{
|
||||
check(i < array->max, "darray attempt to set past max");
|
||||
if(i > array->end) array->end = i;
|
||||
array->contents[i] = el;
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void *DArray_get(DArray *array, int i)
|
||||
{
|
||||
check(i < array->max, "darray attempt to get past max");
|
||||
return array->contents[i];
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *DArray_remove(DArray *array, int i)
|
||||
{
|
||||
void *el = array->contents[i];
|
||||
|
||||
array->contents[i] = NULL;
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
static inline void *DArray_new(DArray *array)
|
||||
{
|
||||
check(array->element_size > 0, "Can't use DArray_new on 0 size darrays.");
|
||||
|
||||
return calloc(1, array->element_size);
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define DArray_free(E) free((E))
|
||||
|
||||
#endif
|
19
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray_algos.c
Normal file
19
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray_algos.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <lcthw/darray_algos.h>
|
||||
#include <stdlib.h>
|
||||
#include <bsd/stdlib.h>
|
||||
|
||||
int DArray_qsort(DArray *array, DArray_compare cmp)
|
||||
{
|
||||
qsort(array->contents, DArray_count(array), sizeof(void *), cmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DArray_heapsort(DArray *array, DArray_compare cmp)
|
||||
{
|
||||
return heapsort(array->contents, DArray_count(array), sizeof(void *), cmp);
|
||||
}
|
||||
|
||||
int DArray_mergesort(DArray *array, DArray_compare cmp)
|
||||
{
|
||||
return mergesort(array->contents, DArray_count(array), sizeof(void *), cmp);
|
||||
}
|
14
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray_algos.h
Normal file
14
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray_algos.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef lcthw_DArray_algos_h
|
||||
#define lcthw_DArray_algos_h
|
||||
|
||||
#include <lcthw/darray.h>
|
||||
|
||||
typedef int (*DArray_compare)(const void *a, const void *b);
|
||||
|
||||
int DArray_qsort(DArray *array, DArray_compare cmp);
|
||||
|
||||
int DArray_heapsort(DArray *array, DArray_compare cmp);
|
||||
|
||||
int DArray_mergesort(DArray *array, DArray_compare cmp);
|
||||
|
||||
#endif
|
30
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/dbg.h
Normal file
30
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/dbg.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __dbg_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
244
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list.c
Normal file
244
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list.c
Normal file
@@ -0,0 +1,244 @@
|
||||
#include <lcthw/list.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
List *List_create()
|
||||
{
|
||||
return calloc(1, sizeof(List));
|
||||
}
|
||||
|
||||
void List_destroy(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(cur->prev) {
|
||||
free(cur->prev);
|
||||
}
|
||||
}
|
||||
|
||||
free(list->last);
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
void List_clear(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
free(cur->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void List_clear_destroy(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
free(cur->value);
|
||||
if(cur->prev) {
|
||||
free(cur->prev);
|
||||
}
|
||||
}
|
||||
|
||||
free(list->last);
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
void List_push(List *list, void *value)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
ListNode *node = calloc(1, sizeof(ListNode));
|
||||
check_mem(node);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if(list->last == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->last->next = node;
|
||||
node->prev = list->last;
|
||||
list->last = node;
|
||||
}
|
||||
|
||||
list->count++;
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
void *List_pop(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
ListNode *node = list->last;
|
||||
return node != NULL ? List_remove(list, node) : NULL;
|
||||
}
|
||||
|
||||
void List_unshift(List *list, void *value)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
ListNode *node = calloc(1, sizeof(ListNode));
|
||||
check_mem(node);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if(list->first == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
node->next = list->first;
|
||||
list->first->prev = node;
|
||||
list->first = node;
|
||||
}
|
||||
|
||||
list->count++;
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
void *List_shift(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
ListNode *node = list->first;
|
||||
return node != NULL ? List_remove(list, node) : NULL;
|
||||
}
|
||||
|
||||
void *List_remove(List *list, ListNode *node)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
void *result = NULL;
|
||||
|
||||
check(list->first && list->last, "List is empty.");
|
||||
check(node, "node can't be NULL");
|
||||
|
||||
if(node == list->first && node == list->last) {
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
} else if(node == list->first) {
|
||||
list->first = node->next;
|
||||
check(list->first != NULL, "Invalid list, somehow got a first that is NULL.");
|
||||
list->first->prev = NULL;
|
||||
} else if(node == list->last) {
|
||||
list->last = node->prev;
|
||||
check(list->last != NULL, "Invalid list, somehow got a next that is NULL.");
|
||||
list->last->next = NULL;
|
||||
} else {
|
||||
ListNode *after = node->next;
|
||||
ListNode *before = node->prev;
|
||||
after->prev = before;
|
||||
before->next = after;
|
||||
}
|
||||
|
||||
list->count--;
|
||||
result = node->value;
|
||||
free(node);
|
||||
|
||||
error:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
List *List_copy(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
List *out = List_create();
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
List_push(out, cur->value);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int List_split(List *list, void *split, List *a, List *b)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
check(list->first && list->last, "List is empty.");
|
||||
check(split, "split can't be NULL");
|
||||
|
||||
if(split == list->last->value || (split == list->first->value && split == list->last->value)) {
|
||||
(*a) = *List_copy(list);
|
||||
return 0;
|
||||
} else if(split == list->first->value) {
|
||||
(*b) = *List_copy(list);
|
||||
List_push(a, List_shift(b));
|
||||
return 0;
|
||||
} else {
|
||||
int past_split = 0;
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(past_split) {
|
||||
List_push(b, cur->value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cur->value == split) {
|
||||
past_split = 1;
|
||||
}
|
||||
|
||||
List_push(a, cur->value);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void List_join(List *list, List *b)
|
||||
{
|
||||
List_validate(list);
|
||||
List_validate(b);
|
||||
|
||||
List *tail = List_copy(b);
|
||||
|
||||
list->last->next = tail->first;
|
||||
list->count += tail->count;
|
||||
free(tail);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void List_swap(ListNode *a, ListNode *b)
|
||||
{
|
||||
ListNode *tmp = a->next;
|
||||
a->next = b->next;
|
||||
b->next = tmp;
|
||||
tmp = a->prev;
|
||||
a->prev = b->prev;
|
||||
b->prev = tmp;
|
||||
}
|
||||
|
||||
|
||||
void List_dump(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(i > 0) {
|
||||
for(j = 0; j < (i*4); j++) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("`");
|
||||
}
|
||||
printf("-> [%d] ListNode .value = %p (%s)\n", i, cur->value, (char *)cur->value);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
51
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list.h
Normal file
51
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef lcthw_List_h
|
||||
#define lcthw_List_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct ListNode;
|
||||
|
||||
typedef struct ListNode {
|
||||
struct ListNode *next;
|
||||
struct ListNode *prev;
|
||||
void *value;
|
||||
} ListNode;
|
||||
|
||||
typedef struct List {
|
||||
int count;
|
||||
ListNode *first;
|
||||
ListNode *last;
|
||||
} List;
|
||||
|
||||
List *List_create();
|
||||
void List_destroy(List *list);
|
||||
void List_clear(List *list);
|
||||
void List_clear_destroy(List *list);
|
||||
|
||||
#define List_count(A) ((A)->count)
|
||||
#define List_first(A) ((A)->first != NULL ? (A)->first->value : NULL)
|
||||
#define List_last(A) ((A)->last != NULL ? (A)->last->value : NULL)
|
||||
|
||||
void List_push(List *list, void *value);
|
||||
void *List_pop(List *list);
|
||||
|
||||
void List_unshift(List *list, void *value);
|
||||
void *List_shift(List *list);
|
||||
|
||||
void *List_remove(List *list, ListNode *node);
|
||||
|
||||
List *List_copy(List *list);
|
||||
int List_split(List *list, void *split, List *a, List *b);
|
||||
void List_join(List *list, List *b);
|
||||
void List_swap(ListNode *a, ListNode *b);
|
||||
void List_dump(List *list);
|
||||
|
||||
#define List_validate(A) (assert(A != NULL && List_count(A) > -1 &&\
|
||||
(List_count(A) > 0 && List_first(A) != NULL) && "invalid *List"))
|
||||
|
||||
#define LIST_FOREACH(L, F, N, C) ListNode *_node = NULL;\
|
||||
ListNode *C = NULL;\
|
||||
for(C = _node = L->F; _node != NULL; C = _node = _node->N)
|
||||
|
||||
#endif
|
87
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list_algos.c
Normal file
87
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list_algos.c
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <lcthw/list_algos.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
int List_bubble_sort(List *list, List_compare cmp)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
if(List_count(list) <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swapped = 1;
|
||||
|
||||
while(swapped == 1) {
|
||||
swapped = 0;
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(cur->next == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cmp(cur->value, cur->next->value) > 0) {
|
||||
List_swap(cur, cur->next);
|
||||
swapped = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
List *List_merge(List *left, List *right, List_compare cmp)
|
||||
{
|
||||
List *result = List_create();
|
||||
|
||||
while(List_count(left) > 0 && List_count(right) > 0) {
|
||||
if(cmp(List_first(left), List_first(right)) <= 0) {
|
||||
List_push(result, List_shift(left));
|
||||
continue;
|
||||
}
|
||||
|
||||
List_push(result, List_shift(right));
|
||||
}
|
||||
|
||||
while(List_count(left) > 0) {
|
||||
List_push(result, List_shift(left));
|
||||
}
|
||||
|
||||
while(List_count(right) > 0) {
|
||||
List_push(result, List_shift(right));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
List *List_merge_sort(List *list, List_compare cmp)
|
||||
{
|
||||
if(List_count(list) <= 1) {
|
||||
return list;;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
List *left = List_create();
|
||||
List *right = List_create();
|
||||
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(i % 2 == 0) {
|
||||
List_push(right, cur->value);
|
||||
} else {
|
||||
List_push(left, cur->value);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
List *sort_left = List_merge_sort(left, cmp);
|
||||
List *sort_right = List_merge_sort(right, cmp);
|
||||
|
||||
if(sort_left != left) {
|
||||
List_destroy(left);
|
||||
}
|
||||
|
||||
if(sort_right != right) {
|
||||
List_destroy(right);
|
||||
}
|
||||
|
||||
return List_merge(sort_left, sort_right, cmp);
|
||||
}
|
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list_algos.h
Normal file
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/list_algos.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef lcthw_List_algos_h
|
||||
#define lcthw_List_algos_h
|
||||
|
||||
#include <lcthw/list.h>
|
||||
|
||||
typedef int (*List_compare)(const void *a, const void *b);
|
||||
|
||||
int List_bubble_sort(List *list, List_compare cmp);
|
||||
|
||||
List *List_merge_sort(List *list, List_compare cmp);
|
||||
|
||||
#endif
|
140
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/radixmap.c
Normal file
140
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/radixmap.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Based on code by Andre Reinald then heavily modified by Zed A. Shaw
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <lcthw/radixmap.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
RadixMap *RadixMap_create(size_t max)
|
||||
{
|
||||
RadixMap *map = calloc(sizeof(RadixMap), 1);
|
||||
check_mem(map);
|
||||
|
||||
map->contents = calloc(sizeof(RMElement), max + 1);
|
||||
check_mem(map->contents);
|
||||
|
||||
map->temp = calloc(sizeof(RMElement), max + 1);
|
||||
check_mem(map->temp);
|
||||
|
||||
map->max = max;
|
||||
map->end = 0;
|
||||
|
||||
return map;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RadixMap_destroy(RadixMap *map)
|
||||
{
|
||||
if(map) {
|
||||
free(map->contents);
|
||||
free(map->temp);
|
||||
free(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ByteOf(x,y) (((uint8_t *)x)[y])
|
||||
|
||||
static inline void radix_sort(short offset, uint64_t max, uint64_t *source, uint64_t *dest)
|
||||
{
|
||||
uint64_t count[256] = {0};
|
||||
uint64_t *cp = NULL;
|
||||
uint64_t *sp = NULL;
|
||||
uint64_t *end = NULL;
|
||||
uint64_t s = 0;
|
||||
uint64_t c = 0;
|
||||
|
||||
// count occurences of every byte value
|
||||
for(sp = source, end = source + max; sp < end; sp++) {
|
||||
count[ByteOf(sp, offset)]++;
|
||||
}
|
||||
|
||||
// transform count into index by summing elements and storing into same array
|
||||
for(s = 0, cp = count, end = count + 256; cp < end; cp++) {
|
||||
c = *cp;
|
||||
*cp = s;
|
||||
s += c;
|
||||
}
|
||||
|
||||
// fill dest with the right values in the right place
|
||||
for(sp = source, end = source + max; sp < end; sp++) {
|
||||
cp = count + ByteOf(sp, offset);
|
||||
dest[*cp] = *sp;
|
||||
++(*cp);
|
||||
}
|
||||
}
|
||||
|
||||
void RadixMap_sort(RadixMap *map)
|
||||
{
|
||||
uint64_t *source = &map->contents[0].raw;
|
||||
uint64_t *temp = &map->temp[0].raw;
|
||||
|
||||
radix_sort(0, map->end, source, temp);
|
||||
radix_sort(1, map->end, temp, source);
|
||||
radix_sort(2, map->end, source, temp);
|
||||
radix_sort(3, map->end, temp, source);
|
||||
}
|
||||
|
||||
RMElement *RadixMap_find(RadixMap *map, uint32_t to_find)
|
||||
{
|
||||
int low = 0;
|
||||
int high = map->end - 1;
|
||||
RMElement *data = map->contents;
|
||||
|
||||
while(low <= high) {
|
||||
int middle = low + (high - low)/2;
|
||||
uint32_t key = data[middle].data.key;
|
||||
|
||||
if(to_find < key) {
|
||||
high = middle - 1;
|
||||
} else if(to_find > key) {
|
||||
low = middle + 1;
|
||||
} else {
|
||||
return &data[middle];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int RadixMap_add(RadixMap *map, uint32_t key, uint32_t value)
|
||||
{
|
||||
check(key < UINT32_MAX, "Key can't be equal to UINT32_MAX.");
|
||||
|
||||
RMElement element = {.data = {.key = key, .value = value}};
|
||||
check(map->end + 1 < map->max, "RadixMap is full.");
|
||||
|
||||
map->contents[map->end++] = element;
|
||||
|
||||
RadixMap_sort(map);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int RadixMap_delete(RadixMap *map, RMElement *el)
|
||||
{
|
||||
check(map->end > 0, "There is nothing to delete.");
|
||||
check(el != NULL, "Can't delete a NULL element.");
|
||||
|
||||
el->data.key = UINT32_MAX;
|
||||
|
||||
if(map->end > 1) {
|
||||
// don't bother resorting a map of 1 length
|
||||
RadixMap_sort(map);
|
||||
}
|
||||
|
||||
map->end--;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
35
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/radixmap.h
Normal file
35
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/radixmap.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef lcthw_radixmap_h
|
||||
#define lcthw_radixmap_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union RMElement {
|
||||
uint64_t raw;
|
||||
struct {
|
||||
uint32_t key;
|
||||
uint32_t value;
|
||||
} data;
|
||||
} RMElement;
|
||||
|
||||
typedef struct RadixMap {
|
||||
size_t max;
|
||||
size_t end;
|
||||
uint32_t counter;
|
||||
RMElement *contents;
|
||||
RMElement *temp;
|
||||
} RadixMap;
|
||||
|
||||
|
||||
RadixMap *RadixMap_create(size_t max);
|
||||
|
||||
void RadixMap_destroy(RadixMap *map);
|
||||
|
||||
void RadixMap_sort(RadixMap *map);
|
||||
|
||||
RMElement *RadixMap_find(RadixMap *map, uint32_t key);
|
||||
|
||||
int RadixMap_add(RadixMap *map, uint32_t key, uint32_t value);
|
||||
|
||||
int RadixMap_delete(RadixMap *map, RMElement *el);
|
||||
|
||||
#endif
|
@@ -0,0 +1,55 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/bstrlib.h>
|
||||
|
||||
char *test_bfromcstr()
|
||||
{
|
||||
bstring b = bfromcstr("oh hai");
|
||||
mu_assert(b != NULL, "bstring is NULL.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_blk2bstr()
|
||||
{
|
||||
bstring b = blk2bstr("hats", 5);
|
||||
mu_assert(b != NULL, "bstring is NULL.");
|
||||
|
||||
b = blk2bstr(NULL, 42);
|
||||
mu_assert(b == NULL, "bstring is not NULL.");
|
||||
|
||||
b = blk2bstr("bats", -17);
|
||||
mu_assert(b == NULL, "bstring is not NULL.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_bstrcpy()
|
||||
{
|
||||
bstring b = bfromcstr("mats");
|
||||
mu_assert(bstrcpy(b) != NULL, "bstring is NULL.");
|
||||
|
||||
mu_assert(bstrcpy(NULL) == NULL, "bstring is not NULL.");
|
||||
|
||||
int orig_len = b->slen;
|
||||
b->slen = -1;
|
||||
mu_assert(bstrcpy(b) == NULL, "bstring is not NULL.");
|
||||
b->slen = orig_len;
|
||||
|
||||
b->data = NULL;
|
||||
mu_assert(bstrcpy(b) == NULL, "bstring is not NULL.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_bfromcstr);
|
||||
mu_run_test(test_blk2bstr);
|
||||
mu_run_test(test_bstrcpy);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
@@ -0,0 +1,78 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/darray_algos.h>
|
||||
|
||||
int testcmp(char **a, char **b)
|
||||
{
|
||||
return strcmp(*a, *b);
|
||||
}
|
||||
|
||||
DArray *create_words()
|
||||
{
|
||||
DArray *result = DArray_create(0, 5);
|
||||
char *words[] = {"asdfasfd", "werwar", "13234", "asdfasfd", "oioj"};
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < 5; i++) {
|
||||
DArray_push(result, words[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int is_sorted(DArray *array)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < DArray_count(array) - 1; i++) {
|
||||
if(strcmp(DArray_get(array, i), DArray_get(array, i+1)) > 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *run_sort_test(int (*func)(DArray *, DArray_compare), const char *name)
|
||||
{
|
||||
DArray *words = create_words();
|
||||
mu_assert(!is_sorted(words), "Words should start not sorted.");
|
||||
|
||||
name = name;
|
||||
debug("--- Testing %s sorting algorithm", name);
|
||||
int rc = func(words, (DArray_compare)testcmp);
|
||||
mu_assert(rc == 0, "sort failed");
|
||||
mu_assert(is_sorted(words), "didn't sort it");
|
||||
|
||||
DArray_destroy(words);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_qsort()
|
||||
{
|
||||
return run_sort_test(DArray_qsort, "qsort");
|
||||
}
|
||||
|
||||
char *test_heapsort()
|
||||
{
|
||||
return run_sort_test(DArray_heapsort, "heapsort");
|
||||
}
|
||||
|
||||
char *test_mergesort()
|
||||
{
|
||||
return run_sort_test(DArray_mergesort, "mergesort");
|
||||
}
|
||||
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_qsort);
|
||||
mu_run_test(test_heapsort);
|
||||
mu_run_test(test_mergesort);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
124
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/darray_tests.c
Normal file
124
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/darray_tests.c
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/darray.h>
|
||||
|
||||
static DArray *array = NULL;
|
||||
static int *val1 = NULL;
|
||||
static int *val2 = NULL;
|
||||
|
||||
char *test_create()
|
||||
{
|
||||
array = DArray_create(sizeof(int), 100);
|
||||
mu_assert(array != NULL, "DArray_create failed.");
|
||||
mu_assert(array->contents != NULL, "contents are wrong in darray");
|
||||
mu_assert(array->end == 0, "end isn't at the right spot");
|
||||
mu_assert(array->element_size == sizeof(int), "element size is wrong.");
|
||||
mu_assert(array->max == 100, "wrong max length on initial size");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_destroy()
|
||||
{
|
||||
DArray_destroy(array);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_new()
|
||||
{
|
||||
val1 = DArray_new(array);
|
||||
mu_assert(val1 != NULL, "failed to make a new element");
|
||||
|
||||
val2 = DArray_new(array);
|
||||
mu_assert(val2 != NULL, "failed to make a new element");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_set()
|
||||
{
|
||||
DArray_set(array, 0, val1);
|
||||
DArray_set(array, 1, val2);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_get()
|
||||
{
|
||||
mu_assert(DArray_get(array, 0) == val1, "Wrong first value.");
|
||||
mu_assert(DArray_get(array, 1) == val2, "Wrong second value.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_remove()
|
||||
{
|
||||
int *val_check = DArray_remove(array, 0);
|
||||
mu_assert(val_check != NULL, "Should not get NULL.");
|
||||
mu_assert(*val_check == *val1, "Should get the first value.");
|
||||
mu_assert(DArray_get(array, 0) == NULL, "Should be gone.");
|
||||
DArray_free(val_check);
|
||||
|
||||
val_check = DArray_remove(array, 1);
|
||||
mu_assert(val_check != NULL, "Should not get NULL.");
|
||||
mu_assert(*val_check == *val2, "Should get the second value.");
|
||||
mu_assert(DArray_get(array, 1) == NULL, "Should be gone.");
|
||||
DArray_free(val_check);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_expand_contract()
|
||||
{
|
||||
int old_max = array->max;
|
||||
DArray_expand(array);
|
||||
mu_assert((unsigned int)array->max == old_max + array->expand_rate, "Wrong size after expand.");
|
||||
|
||||
DArray_contract(array);
|
||||
mu_assert((unsigned int)array->max == array->expand_rate + 1, "Should stay at the expand_rate at least.");
|
||||
|
||||
DArray_contract(array);
|
||||
mu_assert((unsigned int)array->max == array->expand_rate + 1, "Should stay at the expand_rate at least.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_push_pop()
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i < 1000; i++) {
|
||||
int *val = DArray_new(array);
|
||||
*val = i * 333;
|
||||
DArray_push(array, val);;
|
||||
}
|
||||
|
||||
mu_assert(array->max == 1201, "Wrong max size.");
|
||||
|
||||
for(i = 999; i >= 0; i--) {
|
||||
int *val = DArray_pop(array);
|
||||
mu_assert(val != NULL, "Shouldn't get a NULL.");
|
||||
mu_assert(*val == i * 333, "Wrong value.");
|
||||
DArray_free(val);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_create);
|
||||
mu_run_test(test_new);
|
||||
mu_run_test(test_set);
|
||||
mu_run_test(test_get);
|
||||
mu_run_test(test_remove);
|
||||
mu_run_test(test_expand_contract);
|
||||
mu_run_test(test_push_pop);
|
||||
mu_run_test(test_destroy);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
@@ -0,0 +1,91 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/list_algos.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
char *values[] = {"XXXX", "1234", "abcd", "xjvef", "NDSS"};
|
||||
#define NUM_VALUES 5
|
||||
|
||||
List *create_words()
|
||||
{
|
||||
int i = 0;
|
||||
List *words = List_create();
|
||||
|
||||
for(i = 0; i < NUM_VALUES; i++) {
|
||||
List_push(words, values[i]);
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
int is_sorted(List *words)
|
||||
{
|
||||
LIST_FOREACH(words, first, next, cur) {
|
||||
if(cur->next && strcmp(cur->value, cur->next->value) > 0) {
|
||||
debug("%s %s", (char *)cur->value, (char *)cur->next->value);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *test_bubble_sort()
|
||||
{
|
||||
List *words = create_words();
|
||||
|
||||
// should work on a list that needs sorting
|
||||
int rc = List_bubble_sort(words, (List_compare)strcmp);
|
||||
mu_assert(rc == 0, "Bubble sort failed.");
|
||||
mu_assert(is_sorted(words), "Words are not sorted after bubble sort.");
|
||||
|
||||
// should work on an already sorted list
|
||||
rc = List_bubble_sort(words, (List_compare)strcmp);
|
||||
mu_assert(rc == 0, "Bubble sort of already sorted failed.");
|
||||
mu_assert(is_sorted(words), "Words should be sorted if already bubble sorted.");
|
||||
|
||||
List_destroy(words);
|
||||
|
||||
// should work on an empty list
|
||||
words = List_create();
|
||||
rc = List_bubble_sort(words, (List_compare)strcmp);
|
||||
mu_assert(rc == 0, "Bubble sort failed on empty list.");
|
||||
mu_assert(is_sorted(words), "Words should be sorted if empty.");
|
||||
|
||||
List_destroy(words);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_merge_sort()
|
||||
{
|
||||
List *words = create_words();
|
||||
|
||||
// should work on a list that needs sorting
|
||||
List *res = List_merge_sort(words, (List_compare)strcmp);
|
||||
mu_assert(List_count(res) == List_count(words), "Sorted list has different count.");
|
||||
mu_assert(is_sorted(res), "Words are not sorted after merge sort.");
|
||||
|
||||
List *res2 = List_merge_sort(res, (List_compare)strcmp);
|
||||
mu_assert(List_count(res2) == List_count(res), "Sorted list has different count.");
|
||||
mu_assert(is_sorted(res), "Should still be sorted after merge sort.");
|
||||
|
||||
List_destroy(res2);
|
||||
List_destroy(res);
|
||||
|
||||
List_destroy(words);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_bubble_sort);
|
||||
mu_run_test(test_merge_sort);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
205
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c
Normal file
205
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/list.h>
|
||||
#include <assert.h>
|
||||
|
||||
static List *list = NULL;
|
||||
char *test1 = "test1 data";
|
||||
char *test2 = "test2 data";
|
||||
char *test3 = "test3 data";
|
||||
char *test4 = "test4 data";
|
||||
|
||||
|
||||
char *test_create()
|
||||
{
|
||||
list = List_create();
|
||||
mu_assert(list != NULL, "Failed to create list.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_destroy()
|
||||
{
|
||||
List_clear_destroy(list);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_push_pop()
|
||||
{
|
||||
List_push(list, test1);
|
||||
mu_assert(List_last(list) == test1, "Wrong last value.");
|
||||
|
||||
List_push(list, test2);
|
||||
mu_assert(List_last(list) == test2, "Wrong last value");
|
||||
|
||||
List_push(list, test3);
|
||||
mu_assert(List_last(list) == test3, "Wrong last value");
|
||||
mu_assert(List_count(list) == 3, "Wrong count on push.");
|
||||
|
||||
char *val = List_pop(list);
|
||||
mu_assert(val == test3, "Wrong value on pop.");
|
||||
|
||||
val = List_pop(list);
|
||||
mu_assert(val == test2, "Wrong value on pop.");
|
||||
|
||||
val = List_pop(list);
|
||||
mu_assert(val == test1, "Wrong value on pop.");
|
||||
mu_assert(List_count(list) == 0, "Wrong count after pop.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_unshift()
|
||||
{
|
||||
List_unshift(list, test1);
|
||||
mu_assert(List_first(list) == test1, "Wrong first value.");
|
||||
|
||||
List_unshift(list, test2);
|
||||
mu_assert(List_first(list) == test2, "Wrong first value.");
|
||||
|
||||
List_unshift(list, test3);
|
||||
mu_assert(List_first(list) == test3, "Wrong first value.");
|
||||
mu_assert(List_count(list) == 3, "Wrong count on unshift.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_remove()
|
||||
{
|
||||
// we only need to test the middle remove case since push/shift
|
||||
// already tests the other cases
|
||||
|
||||
char *val = List_remove(list, list->first->next);
|
||||
mu_assert(val == test2, "Wrong removed element.");
|
||||
mu_assert(List_count(list) == 2, "Wrong count after remove.");
|
||||
mu_assert(List_first(list) == test3, "Wrong first after remove.");
|
||||
mu_assert(List_last(list) == test1, "Wrong last after remove.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_shift()
|
||||
{
|
||||
mu_assert(List_count(list) != 0, "Wrong count before shift.");
|
||||
|
||||
char *val = List_shift(list);
|
||||
mu_assert(val == test3, "Wrong value on shift.");
|
||||
|
||||
val = List_shift(list);
|
||||
mu_assert(val == test1, "Wrong value on shift.");
|
||||
mu_assert(List_count(list) == 0, "Wrong count after shift.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_copy()
|
||||
{
|
||||
list = List_create();
|
||||
|
||||
mu_assert(List_count(list) == 0, "Wrong count before copy.");
|
||||
List_push(list, test1);
|
||||
List_push(list, test2);
|
||||
List_push(list, test3);
|
||||
List_push(list, test4);
|
||||
|
||||
mu_assert(List_count(list) == 4, "Wrong count after push.");
|
||||
|
||||
List *copy = List_copy(list);
|
||||
mu_assert(copy != list, "Copy and list have same address.");
|
||||
mu_assert(List_count(copy) == 4, "Copy has wrong count.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_split()
|
||||
{
|
||||
mu_assert(List_count(list) == 4, "Wrong count before split.");
|
||||
|
||||
List *a = List_create();
|
||||
List *b = List_create();
|
||||
List *tmp = List_copy(list);
|
||||
|
||||
int rc = -1;
|
||||
rc = List_split(tmp, test2, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 2, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 2, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test1, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 1, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 3, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test3, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 3, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 1, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test4, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 4, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 0, "List 'b' has wrong count.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_join()
|
||||
{
|
||||
mu_assert(List_count(list) == 4, "Wrong count before join.");
|
||||
|
||||
List *b = List_create();
|
||||
List_push(b, test4);
|
||||
mu_assert(List_count(b) == 1, "List 'b' has wrong count.");
|
||||
|
||||
List_join(list, b);
|
||||
mu_assert(List_count(list) == 5, "Wrong count after join.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *all_tests() {
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_create);
|
||||
mu_run_test(test_push_pop);
|
||||
mu_run_test(test_unshift);
|
||||
mu_run_test(test_remove);
|
||||
mu_run_test(test_shift);
|
||||
mu_run_test(test_destroy);
|
||||
mu_run_test(test_copy);
|
||||
mu_run_test(test_split);
|
||||
mu_run_test(test_join);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
105
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/radixmap_tests.c
Normal file
105
oldstuff/lcthw-remnants-2/liblcthw/tests/lcthw/radixmap_tests.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "../minunit.h"
|
||||
#include <stdint.h>
|
||||
#include <lcthw/radixmap.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
static int make_random(RadixMap *map)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for(i = 0; i < map->max - 1; i++) {
|
||||
uint32_t key = (uint32_t)(rand() | (rand() << 16));
|
||||
check(RadixMap_add(map, key, i) == 0, "Failed to add key %u", key);
|
||||
}
|
||||
|
||||
return i;
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_order(RadixMap *map)
|
||||
{
|
||||
RMElement d1, d2;
|
||||
unsigned int i = 0;
|
||||
|
||||
// only signal errors if any (should not be)
|
||||
for(i = 0; map->end > 0 && i < map->end-1; i++) {
|
||||
d1 = map->contents[i];
|
||||
d2 = map->contents[i+1];
|
||||
|
||||
if(d1.data.key > d2.data.key) {
|
||||
debug("FAIL:i=%u, key: %u, value: %u, equals max? %d\n", i, d1.data.key, d1.data.value,
|
||||
d2.data.key == UINT32_MAX);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_search(RadixMap *map)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
RMElement *d = NULL;
|
||||
RMElement *found = NULL;
|
||||
|
||||
for(i = map->end / 2; i < map->end; i++) {
|
||||
d = &map->contents[i];
|
||||
found = RadixMap_find(map, d->data.key);
|
||||
check(found != NULL, "Didn't find %u at %u.", d->data.key, i);
|
||||
check(found->data.key == d->data.key, "Got the wrong result: %p:%u looking for %u at %u",
|
||||
found, found->data.key, d->data.key, i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// test for big number of elements
|
||||
static char *test_operations()
|
||||
{
|
||||
size_t N = 200;
|
||||
|
||||
RadixMap *map = RadixMap_create(N);
|
||||
mu_assert(map != NULL, "Failed to make the map.");
|
||||
mu_assert(make_random(map), "Didn't make a random fake radix map.");
|
||||
|
||||
RadixMap_sort(map);
|
||||
mu_assert(check_order(map), "Failed to properly sort the RadixMap.");
|
||||
|
||||
mu_assert(test_search(map), "Failed the search test.");
|
||||
mu_assert(check_order(map), "RadixMap didn't stay sorted after search.");
|
||||
|
||||
while(map->end > 0) {
|
||||
RMElement *el = RadixMap_find(map, map->contents[map->end / 2].data.key);
|
||||
mu_assert(el != NULL, "Should get a result.");
|
||||
|
||||
size_t old_end = map->end;
|
||||
|
||||
mu_assert(RadixMap_delete(map, el) == 0, "Didn't delete it.");
|
||||
mu_assert(old_end - 1 == map->end, "Wrong size after delete.");
|
||||
|
||||
// test that the end is now the old value, but uint32 max so it trails off
|
||||
mu_assert(check_order(map), "RadixMap didn't stay sorted after delete.");
|
||||
}
|
||||
|
||||
RadixMap_destroy(map);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
srand(time(NULL));
|
||||
|
||||
mu_run_test(test_operations);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
38
oldstuff/lcthw-remnants-2/liblcthw/tests/minunit.h
Normal file
38
oldstuff/lcthw-remnants-2/liblcthw/tests/minunit.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#undef DNDEBUG
|
||||
#ifndef _minunit_h
|
||||
#define _minunit_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <lcthw/dbg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define mu_suite_start() char *message = NULL
|
||||
|
||||
#define mu_assert(test, message) if (!(test)) {\
|
||||
log_err(message); return message;\
|
||||
}\
|
||||
assertions_made++;
|
||||
#define mu_run_test(test) debug("\n-----%s", " " #test); \
|
||||
message = test(); tests_run++; if (message) return message;
|
||||
|
||||
#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
|
||||
argc = argc; \
|
||||
argv = argv; \
|
||||
debug("----- RUNNING: %s", argv[0]);\
|
||||
printf("----\nRUNNING: %s\n", argv[0]);\
|
||||
char *result = name();\
|
||||
if (result != 0) {\
|
||||
printf("FAILED: %s\n", result);\
|
||||
}\
|
||||
else {\
|
||||
printf("ALL TESTS PASSED\n");\
|
||||
}\
|
||||
printf("Tests run: %d\n", tests_run);\
|
||||
printf("Assertions made: %d\n", assertions_made);\
|
||||
exit(result != 0);\
|
||||
}
|
||||
|
||||
int tests_run;
|
||||
int assertions_made;
|
||||
|
||||
#endif
|
107
oldstuff/lcthw-remnants-2/liblcthw/tests/runtests.c
Normal file
107
oldstuff/lcthw-remnants-2/liblcthw/tests/runtests.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fnmatch.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
int test_selector(const struct dirent *ep)
|
||||
{
|
||||
return fnmatch("*_tests", ep->d_name, 0) == 0;
|
||||
}
|
||||
|
||||
int run_tests_file(char *filename)
|
||||
{
|
||||
if(access(filename, R_OK | X_OK) == 0) {
|
||||
return system(filename);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int entcount = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
int ntests = 0;
|
||||
char *testsdir = NULL;
|
||||
char *valgrind = getenv("VALGRIND");
|
||||
struct dirent **namelist = NULL;
|
||||
struct dirent *ep = NULL;
|
||||
|
||||
if(argc > 1) {
|
||||
testsdir = argv[1];
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = getenv("TESTS");
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = "./tests";
|
||||
}
|
||||
|
||||
entcount = scandir((const char *)testsdir, &namelist, test_selector, alphasort);
|
||||
check(entcount > -1, "Failed to scan tests dir");
|
||||
|
||||
for(i = 0; i < entcount; i++) {
|
||||
ep = namelist[i];
|
||||
check(ep, "Dirent is missing.");
|
||||
|
||||
char filename[256];
|
||||
rc = sprintf(filename, "%s/%s", testsdir, ep->d_name);
|
||||
check(rc > -1, "Failed to build filename.");
|
||||
debug("Found filename '%s'", filename);
|
||||
|
||||
free(ep);
|
||||
|
||||
if(valgrind) {
|
||||
char command[1024];
|
||||
rc = sprintf(command, "%s %s", valgrind, filename);
|
||||
check(rc > -1, "Failed to build command with valgrind.");
|
||||
rc = run_tests_file(command);
|
||||
} else {
|
||||
rc = run_tests_file(filename);
|
||||
}
|
||||
|
||||
if(rc > 0) {
|
||||
debug("Skipping '%s'", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
ntests++;
|
||||
|
||||
if(rc == 0) {
|
||||
printf("%s PASS\n", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("ERROR in test %s", filename);
|
||||
if(access("tests/tests.log", R_OK) == 0) {
|
||||
printf(": here's tests/tests.log\n");
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("------\n");
|
||||
printf("Total of %d test file%s run.\n", ntests, ntests > 1 ? "s" : "");
|
||||
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return rc != 0 ? rc : 1;
|
||||
}
|
Reference in New Issue
Block a user