Compare commits
No commits in common. "9daffd4ed1883ea50ae94b14275b46937cc348ce" and "5e4ae41113e63004bd131010853e5265b31302d3" have entirely different histories.
9daffd4ed1
...
5e4ae41113
5 changed files with 241 additions and 459 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1 @@
|
|||
test
|
||||
.cache
|
||||
compile_commands.json
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -8,8 +8,8 @@ Example of working with a singly linked list (sll):
|
|||
char *a = "one";
|
||||
char *b = "two";
|
||||
ds_sll_t *ll = ds_sll_init();
|
||||
ds_sll_append(ll, a); // [ "one" ]
|
||||
ds_sll_append(ll, b); // [ "one", "two" ]
|
||||
ds_sll_insert(ll, a); // [ "one" ]
|
||||
ds_sll_insert(ll, b); // [ "one", "two" ]
|
||||
ds_ll_foreach(ds_sll_t, ll) {
|
||||
puts(cur->data);
|
||||
// one
|
||||
|
|
@ -45,20 +45,6 @@ ds_hmp_free(&hmp, NULL);
|
|||
free(b);
|
||||
```
|
||||
|
||||
## Stack
|
||||
```c
|
||||
char *a = "a";
|
||||
char *b = "b";
|
||||
|
||||
ds_stack_t *stack = ds_stack_init();
|
||||
ds_stack_push(stack, a); // [ "a" ]
|
||||
ds_stack_push(stack, b); // [ "b", "a" ]
|
||||
ds_stack_peek(stack, 0); // "b"
|
||||
ds_stack_pop(stack); // "b"
|
||||
ds_stack_pop(stack); // "a"
|
||||
free(stack);
|
||||
```
|
||||
|
||||
# TODO
|
||||
- [ ] more data structures
|
||||
- [x] tests
|
||||
|
|
|
|||
477
ds.c
477
ds.c
|
|
@ -6,13 +6,13 @@
|
|||
ds_sll_t
|
||||
*ds_sll_init(void)
|
||||
{
|
||||
return ds_sll_new_node(NULL);
|
||||
return ds_sll_new_node(NULL);
|
||||
}
|
||||
|
||||
ds_dll_t
|
||||
*ds_dll_init(void)
|
||||
{
|
||||
return ds_dll_new_node(NULL);
|
||||
return ds_dll_new_node(NULL);
|
||||
}
|
||||
|
||||
ds_sll_t
|
||||
|
|
@ -40,227 +40,167 @@ ds_dll_t
|
|||
}
|
||||
|
||||
int
|
||||
ds_sll_add(ds_sll_t **ll, void *data, unsigned x)
|
||||
ds_sll_insert(ds_sll_t *ll, void *data)
|
||||
{
|
||||
int i;
|
||||
ds_sll_t *cur, *prev, *new;
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0, cur = *ll; cur; prev = cur, cur = cur->next, i++) {
|
||||
if (i == x) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
}
|
||||
new = ds_sll_new_node(data);
|
||||
new->next = cur;
|
||||
if (i == 0) {
|
||||
*ll = new;
|
||||
} else {
|
||||
prev->next = new;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ds_ll_foreach(ds_sll_t, ll) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
} else if (!cur->next) {
|
||||
cur->next = ds_sll_new_node(data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ds_dll_add(ds_dll_t **ll, void *data, unsigned x)
|
||||
ds_dll_insert(ds_dll_t *ll, void *data)
|
||||
{
|
||||
int i;
|
||||
ds_dll_t *cur, *new;
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0, cur = *ll; cur; cur = cur->next, i++) {
|
||||
if (i == x) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
}
|
||||
new = ds_dll_new_node(data);
|
||||
new->next = cur;
|
||||
new->prev = cur->prev;
|
||||
cur->prev = new;
|
||||
if (i == 0) {
|
||||
*ll = new;
|
||||
} else {
|
||||
cur->prev->next = new;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ds_ll_foreach(ds_dll_t, ll) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
} else if (!cur->next) {
|
||||
cur->next = ds_dll_new_node(data);
|
||||
cur->next->prev = cur;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ds_sll_append(ds_sll_t *ll, void *data)
|
||||
{
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ds_ll_foreach(ds_sll_t, ll) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
} else if (!cur->next) {
|
||||
cur->next = ds_sll_new_node(data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ds_dll_append(ds_dll_t *ll, void *data)
|
||||
{
|
||||
if (!ll || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ds_ll_foreach(ds_dll_t, ll) {
|
||||
if (!cur->data) {
|
||||
cur->data = data;
|
||||
return 0;
|
||||
} else if (!cur->next) {
|
||||
cur->next = ds_dll_new_node(data);
|
||||
cur->next->prev = cur;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_sll_remove(ds_sll_t **ll, unsigned idx)
|
||||
{
|
||||
int i;
|
||||
void *data;
|
||||
ds_sll_t *cur, *rm;
|
||||
int i;
|
||||
void *data;
|
||||
ds_sll_t *cur, *rm;
|
||||
|
||||
rm = NULL;
|
||||
if (!ll || !*ll) {
|
||||
return NULL;
|
||||
}
|
||||
rm = NULL;
|
||||
if (!ll || !*ll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
rm = *ll;
|
||||
*ll = rm->next;
|
||||
} else {
|
||||
for (i = -1, cur = *ll; cur; i++, cur = cur->next) {
|
||||
if (idx == i + 1) {
|
||||
rm = cur->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == 0) {
|
||||
rm = *ll;
|
||||
*ll = rm->next;
|
||||
} else {
|
||||
for (i = -1, cur = *ll; cur; i++, cur = cur->next) {
|
||||
if (idx == i + 1) {
|
||||
rm = cur->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rm) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rm) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur->next = rm->next;
|
||||
}
|
||||
cur->next = rm->next;
|
||||
}
|
||||
|
||||
data = rm->data;
|
||||
free(rm);
|
||||
return data;
|
||||
data = rm->data;
|
||||
free(rm);
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_dll_remove(ds_dll_t **ll, unsigned idx)
|
||||
{
|
||||
int i;
|
||||
void *data;
|
||||
ds_dll_t *cur, *rm;
|
||||
int i;
|
||||
void *data;
|
||||
ds_dll_t *cur, *rm;
|
||||
|
||||
rm = NULL;
|
||||
if (!ll || !*ll) {
|
||||
return NULL;
|
||||
}
|
||||
rm = NULL;
|
||||
if (!ll || !*ll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
rm = *ll;
|
||||
*ll = rm->next;
|
||||
if (rm->next) {
|
||||
rm->next->prev = NULL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0, cur = *ll; cur; i++, cur = cur->next) {
|
||||
if (i == idx) {
|
||||
rm = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == 0) {
|
||||
rm = *ll;
|
||||
*ll = rm->next;
|
||||
if (rm->next) {
|
||||
rm->next->prev = NULL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0, cur = *ll; cur; i++, cur = cur->next) {
|
||||
if (i == idx) {
|
||||
rm = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rm) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rm) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rm->prev->next = rm->next;
|
||||
if (rm->next) {
|
||||
rm->next->prev = rm->prev;
|
||||
}
|
||||
}
|
||||
rm->prev->next = rm->next;
|
||||
if (rm->next) {
|
||||
rm->next->prev = rm->prev;
|
||||
}
|
||||
}
|
||||
|
||||
data = rm->data;
|
||||
free(rm);
|
||||
return data;
|
||||
data = rm->data;
|
||||
free(rm);
|
||||
return data;
|
||||
}
|
||||
|
||||
ds_hmp_t
|
||||
*ds_hmp_init(int data_len)
|
||||
{
|
||||
ds_hmp_t *hmp;
|
||||
ds_hmp_t *hmp;
|
||||
|
||||
if (!data_len) {
|
||||
return NULL;
|
||||
}
|
||||
if (!data_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hmp = calloc(1, sizeof(ds_hmp_t));
|
||||
hmp->data_len = data_len;
|
||||
hmp->data = calloc(data_len, sizeof(ds_sll_t **));
|
||||
hmp = calloc(1, sizeof(ds_hmp_t));
|
||||
hmp->data_len = data_len;
|
||||
hmp->data = calloc(data_len, sizeof(ds_sll_t **));
|
||||
|
||||
return hmp;
|
||||
return hmp;
|
||||
}
|
||||
|
||||
int
|
||||
ds_hmp_free(ds_hmp_t **hmp, void kv_callback(_ds_hmp_kv_t *kv))
|
||||
{
|
||||
int i;
|
||||
_ds_hmp_kv_t *kv;
|
||||
ds_sll_t *ll;
|
||||
int i;
|
||||
_ds_hmp_kv_t *kv;
|
||||
ds_sll_t *ll;
|
||||
|
||||
if (!hmp || !*hmp) {
|
||||
return -1;
|
||||
}
|
||||
if (!hmp || !*hmp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < (*hmp)->data_len; i++) {
|
||||
ll = (*hmp)->data[i];
|
||||
while (ll && ll->data) {
|
||||
if ((kv = ds_sll_remove(&ll, 0))) {
|
||||
if (kv_callback) {
|
||||
kv_callback(kv);
|
||||
}
|
||||
free(kv);
|
||||
}
|
||||
}
|
||||
if (ll) {
|
||||
free(ll);
|
||||
}
|
||||
}
|
||||
free((*hmp)->data);
|
||||
free(*hmp);
|
||||
for (i = 0; i < (*hmp)->data_len; i++) {
|
||||
ll = (*hmp)->data[i];
|
||||
while (ll && ll->data) {
|
||||
if ((kv = ds_sll_remove(&ll, 0))) {
|
||||
if (kv_callback) {
|
||||
kv_callback(kv);
|
||||
}
|
||||
free(kv);
|
||||
}
|
||||
}
|
||||
if (ll) {
|
||||
free(ll);
|
||||
}
|
||||
}
|
||||
free((*hmp)->data);
|
||||
free(*hmp);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -279,144 +219,91 @@ _ds_hmp_gen_hash(char *str)
|
|||
int
|
||||
ds_hmp_insert(ds_hmp_t *hmp, char *key, void *data)
|
||||
{
|
||||
_ds_hmp_kv_t *kv;
|
||||
ds_sll_t *ll;
|
||||
unsigned hash_pos;
|
||||
_ds_hmp_kv_t *kv;
|
||||
ds_sll_t *ll;
|
||||
unsigned hash_pos;
|
||||
|
||||
if (!hmp || !key || !data) {
|
||||
return -1;
|
||||
}
|
||||
if (!hmp || !key || !data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
kv = malloc(sizeof(_ds_hmp_kv_t));
|
||||
kv->key = key;
|
||||
kv->val = data;
|
||||
kv = malloc(sizeof(_ds_hmp_kv_t));
|
||||
kv->key = key;
|
||||
kv->val = data;
|
||||
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
if (!hmp->data[hash_pos]) {
|
||||
hmp->data[hash_pos] = ds_sll_init();
|
||||
if (!hmp->data[hash_pos]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
if (!hmp->data[hash_pos]) {
|
||||
hmp->data[hash_pos] = ds_sll_init();
|
||||
if (!hmp->data[hash_pos]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the ll and put the data into it */
|
||||
ll = hmp->data[hash_pos];
|
||||
if (ds_sll_append(ll, kv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
/* get the ll and put the data into it */
|
||||
ll = hmp->data[hash_pos];
|
||||
if (ds_sll_insert(ll, kv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_hmp_get(ds_hmp_t *hmp, char *key)
|
||||
{
|
||||
ds_sll_t *cur, *ll;
|
||||
unsigned hash_pos;
|
||||
ds_sll_t *cur, *ll;
|
||||
unsigned hash_pos;
|
||||
|
||||
if (!hmp || !key) {
|
||||
return NULL;
|
||||
}
|
||||
if (!hmp || !key) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
ll = hmp->data[hash_pos];
|
||||
if (!ll) {
|
||||
return NULL;
|
||||
}
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
ll = hmp->data[hash_pos];
|
||||
if (!ll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ds_ll_foreach(ds_sll_t, ll) {
|
||||
if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) {
|
||||
return ((_ds_hmp_kv_t *)cur->data)->val;
|
||||
}
|
||||
}
|
||||
ds_ll_foreach(ds_sll_t, ll) {
|
||||
if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) {
|
||||
return ((_ds_hmp_kv_t *)cur->data)->val;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_hmp_remove(ds_hmp_t *hmp, char *key)
|
||||
{
|
||||
int i;
|
||||
void *data;
|
||||
unsigned hash_pos;
|
||||
ds_sll_t *ll, *cur;
|
||||
_ds_hmp_kv_t *kv;
|
||||
int i;
|
||||
void *data;
|
||||
unsigned hash_pos;
|
||||
ds_sll_t *ll, *cur;
|
||||
_ds_hmp_kv_t *kv;
|
||||
|
||||
if (!hmp || !key) {
|
||||
return NULL;
|
||||
}
|
||||
if (!hmp || !key) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
ll = hmp->data[hash_pos];
|
||||
if (!ll) {
|
||||
return NULL;
|
||||
}
|
||||
hash_pos = _ds_hmp_gen_hash(key) % hmp->data_len;
|
||||
ll = hmp->data[hash_pos];
|
||||
if (!ll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0, cur = ll; cur; i++, cur = cur->next) {
|
||||
if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) {
|
||||
kv = ds_sll_remove(&ll, i);
|
||||
hmp->data[hash_pos] = ll;
|
||||
if (!kv) {
|
||||
return NULL;
|
||||
}
|
||||
data = kv->val;
|
||||
free(kv);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
for (i = 0, cur = ll; cur; i++, cur = cur->next) {
|
||||
if (strcmp(((_ds_hmp_kv_t *)cur->data)->key, key) == 0) {
|
||||
kv = ds_sll_remove(&ll, i);
|
||||
hmp->data[hash_pos] = ll;
|
||||
if (!kv) {
|
||||
return NULL;
|
||||
}
|
||||
data = kv->val;
|
||||
free(kv);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ds_stack_t
|
||||
*ds_stack_init(void)
|
||||
{
|
||||
ds_stack_t *stack = malloc(sizeof(ds_stack_t));
|
||||
stack->n = 0;
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
int
|
||||
ds_stack_push(ds_stack_t *stack, void *data)
|
||||
{
|
||||
if (stack->n == 0) {
|
||||
stack->items = ds_sll_new_node(data);
|
||||
stack->n++;
|
||||
return 0;
|
||||
}
|
||||
int r = ds_sll_add(&stack->items, data, 0);
|
||||
if (!r) {
|
||||
stack->n++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_stack_pop(ds_stack_t *stack)
|
||||
{
|
||||
void *r = ds_sll_remove(&stack->items, 0);
|
||||
if (r != NULL) {
|
||||
stack->n--;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
*ds_stack_peek(ds_stack_t *stack, unsigned x)
|
||||
{
|
||||
int i;
|
||||
ds_sll_t *cur;
|
||||
|
||||
if (x > stack->n) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (cur = stack->items, i = 0; cur; cur = cur->next, i++) {
|
||||
if (i == x) {
|
||||
return cur->data;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
76
ds.h
76
ds.h
|
|
@ -14,19 +14,14 @@ typedef struct _ds_dll {
|
|||
|
||||
typedef struct {
|
||||
ds_sll_t **data;
|
||||
unsigned data_len;
|
||||
unsigned data_len;
|
||||
} ds_hmp_t;
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
void *val;
|
||||
char *key;
|
||||
void *val;
|
||||
} _ds_hmp_kv_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned n;
|
||||
ds_sll_t *items;
|
||||
} ds_stack_t;
|
||||
|
||||
#define ds_ll_foreach(t, ll) for (t *cur = ll; cur; cur = cur->next)
|
||||
|
||||
/**
|
||||
|
|
@ -60,46 +55,24 @@ ds_sll_t *ds_sll_new_node(void *data);
|
|||
ds_dll_t *ds_dll_new_node(void *data);
|
||||
|
||||
/**
|
||||
* @brief data to add at x of a singly linked list. This will use
|
||||
* @brief data to insert into a singly linked list. This will use
|
||||
* ds_sll_new_node to create the node for you.
|
||||
*
|
||||
* @param ll singly linked list
|
||||
* @param data data you want to add
|
||||
* @param x the position to add it at
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ds_sll_add(ds_sll_t **ll, void *data, unsigned x);
|
||||
int ds_sll_insert(ds_sll_t *ll, void *data);
|
||||
|
||||
/**
|
||||
* @brief data to add at x of a doubly linked list. This will use
|
||||
* ds_dll_new_node to create the node for you.
|
||||
* @brief data to insert into a doubly linked list. This will use
|
||||
* ds_sll_new_node to create the node for you.
|
||||
*
|
||||
* @param ll doubly linked list
|
||||
* @param data data you want to add
|
||||
* @param x the position to add it at
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ds_dll_add(ds_dll_t **ll, void *data, unsigned x);
|
||||
|
||||
/**
|
||||
* @brief data to append to the end of a singly linked list. This will use
|
||||
* ds_sll_new_node to create the node for you.
|
||||
*
|
||||
* @param ll singly linked list
|
||||
* @param data data you want to append
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ds_sll_append(ds_sll_t *ll, void *data);
|
||||
|
||||
/**
|
||||
* @brief data to append to the end of a doubly linked list. This will use
|
||||
* ds_dll_new_node to create the node for you.
|
||||
*
|
||||
* @param ll doubly linked list
|
||||
* @param data data you want to append
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ds_dll_append(ds_dll_t *ll, void *data);
|
||||
int ds_dll_insert(ds_dll_t *ll, void *data);
|
||||
|
||||
/**
|
||||
* @brief remove an index from a singly linked list
|
||||
|
|
@ -173,37 +146,4 @@ void *ds_hmp_get(ds_hmp_t *hmp, char *key);
|
|||
*/
|
||||
void *ds_hmp_remove(ds_hmp_t *hmp, char *key);
|
||||
|
||||
/**
|
||||
* @brief initialize a new stack
|
||||
*
|
||||
* @return the stack
|
||||
*/
|
||||
ds_stack_t *ds_stack_init(void);
|
||||
|
||||
/**
|
||||
* @brief push new data onto the stack
|
||||
*
|
||||
* @param stack the stack
|
||||
* @param data the data
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ds_stack_push(ds_stack_t *stack, void *data);
|
||||
|
||||
/**
|
||||
* @brief pop the data off the top of the stack
|
||||
*
|
||||
* @param stack the stack
|
||||
* @return the data
|
||||
*/
|
||||
void *ds_stack_pop(ds_stack_t *stack);
|
||||
|
||||
/**
|
||||
* @brief peek forward x items
|
||||
*
|
||||
* @param stack the stack
|
||||
* @param x how many items to look ahead
|
||||
* @return the data or NULL if out of range
|
||||
*/
|
||||
void *ds_stack_peek(ds_stack_t *stack, unsigned x);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
127
test.c
127
test.c
|
|
@ -1,102 +1,73 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ds.h"
|
||||
|
||||
#define test(name, tests) do { \
|
||||
const char *_test_name = name; \
|
||||
int _tests_passed = 0; \
|
||||
int _tests = 0; \
|
||||
tests \
|
||||
_tests_passed += _tests; \
|
||||
printf("%s: %d/%d tests passed\n", name, _tests_passed, _tests); \
|
||||
} while (0)
|
||||
#define test(name, tests) do { \
|
||||
const char *_test_name = name; \
|
||||
int _tests_passed = 0; \
|
||||
int _tests = 0; \
|
||||
tests \
|
||||
_tests_passed += _tests; \
|
||||
printf("%s: %d/%d tests passed\n", name, _tests_passed, _tests); \
|
||||
} while (0)
|
||||
|
||||
#define it(message, test) do { \
|
||||
_tests++; \
|
||||
if (!(test)) { \
|
||||
printf("%s %s FAILED @ %s:%d\n", _test_name, message, __FILE__, __LINE__); \
|
||||
printf(" -> test condition: (%s)\n", #test); \
|
||||
_tests_passed--; \
|
||||
} \
|
||||
#define it(message, test) do { \
|
||||
_tests++; \
|
||||
if (!(test)) { \
|
||||
printf("%s %s FAILED\n", _test_name, message); \
|
||||
_tests_passed--; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct {
|
||||
int num;
|
||||
char *str;
|
||||
int num;
|
||||
char *str;
|
||||
} complex;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test("sll",
|
||||
char *a = "a";
|
||||
char *b = "b";
|
||||
test("sll",
|
||||
char *a = "one";
|
||||
|
||||
ds_sll_t *tmp;
|
||||
it("creates a new linked list", tmp = ds_sll_init());
|
||||
free(tmp);
|
||||
ds_sll_t *tmp;
|
||||
it("ensures creates a new linked list", tmp = ds_sll_init());
|
||||
free(tmp);
|
||||
|
||||
ds_sll_t *ll = ds_sll_new_node(a);
|
||||
it("appends an invalid item", ds_sll_append(ll, NULL) == -1);
|
||||
it("removes an invalid index", ds_sll_remove(&ll, 1234) == NULL);
|
||||
it("adds an item to the beginning", ds_sll_add(&ll, b, 0) == 0);
|
||||
it("removes an item", b == ds_sll_remove(&ll, 0));
|
||||
ds_sll_remove(&ll, 0);
|
||||
);
|
||||
ds_sll_t *ll = ds_sll_new_node(a);
|
||||
it("inserts an invalid item", ds_sll_insert(ll, NULL) == -1);
|
||||
it("removes an invalid index", ds_sll_remove(&ll, 1234) == NULL);
|
||||
it("removes an item", a == ds_sll_remove(&ll, 0));
|
||||
);
|
||||
|
||||
test("dll",
|
||||
char *a = "a";
|
||||
char *b = "b";
|
||||
test("dll",
|
||||
char *a = "one";
|
||||
|
||||
ds_dll_t *tmp;
|
||||
it("creates a new linked list", tmp = ds_dll_init());
|
||||
free(tmp);
|
||||
ds_dll_t *tmp;
|
||||
it("ensures creates a new linked list", tmp = ds_dll_init());
|
||||
free(tmp);
|
||||
|
||||
ds_dll_t *ll = ds_dll_new_node(a);
|
||||
it("appends an invalid item", ds_dll_append(ll, NULL) == -1);
|
||||
it("removes an invalid index", ds_dll_remove(&ll, 1234) == NULL);
|
||||
it("adds an item to the beginning", ds_dll_add(&ll, b, 0) == 0);
|
||||
it("removes an item", b == ds_dll_remove(&ll, 0));
|
||||
ds_dll_remove(&ll, 0);
|
||||
);
|
||||
ds_dll_t *ll = ds_dll_new_node(a);
|
||||
it("inserts an invalid item", ds_dll_insert(ll, NULL) == -1);
|
||||
it("removes an invalid index", ds_dll_remove(&ll, 1234) == NULL);
|
||||
it("removes an item", a == ds_dll_remove(&ll, 0));
|
||||
);
|
||||
|
||||
test("hmp",
|
||||
complex *a = calloc(1, sizeof(complex));
|
||||
a->num = 1;
|
||||
a->str = "abc";
|
||||
test("hmp",
|
||||
complex *a = calloc(1, sizeof(complex));
|
||||
a->num = 1;
|
||||
a->str = "abc";
|
||||
|
||||
ds_hmp_t *hmp = ds_hmp_init(101);
|
||||
it("inserts an item", ds_hmp_insert(hmp, a->str, a) == 0);
|
||||
it("generates a hash", _ds_hmp_gen_hash("a") == 177670);
|
||||
it("removes a non-existent item", ds_hmp_remove(hmp, "???") == NULL);
|
||||
it("removes an invalid item", ds_hmp_remove(hmp, NULL) == NULL);
|
||||
it("removes an item", a == ds_hmp_remove(hmp, a->str));
|
||||
ds_hmp_free(&hmp, NULL);
|
||||
ds_hmp_t *hmp = ds_hmp_init(101);
|
||||
it("inserts an item", ds_hmp_insert(hmp, a->str, a) == 0);
|
||||
it("generates a hash", _ds_hmp_gen_hash("a") == 177670);
|
||||
it("removes a non-existent item", ds_hmp_remove(hmp, "???") == NULL);
|
||||
it("removes an invalid item", ds_hmp_remove(hmp, NULL) == NULL);
|
||||
it("removes an item", a == ds_hmp_remove(hmp, a->str));
|
||||
ds_hmp_free(&hmp, NULL);
|
||||
|
||||
free(a);
|
||||
);
|
||||
|
||||
test("stack",
|
||||
char *a = "a";
|
||||
char *b = "b";
|
||||
char *c = "c";
|
||||
|
||||
ds_stack_t *stack = ds_stack_init();
|
||||
it("pushes an item", ds_stack_push(stack, a) == 0);
|
||||
it("pops an item", ds_stack_pop(stack) == a);
|
||||
|
||||
ds_stack_push(stack, b);
|
||||
ds_stack_push(stack, c);
|
||||
|
||||
it("peeks ahead", ds_stack_peek(stack, 0) == c);
|
||||
it("peeks past the stack", ds_stack_peek(stack, INT_MAX) == NULL);
|
||||
|
||||
ds_stack_pop(stack);
|
||||
ds_stack_pop(stack);
|
||||
|
||||
free(stack);
|
||||
);
|
||||
free(a);
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue