#include "lichen.h" #include #include void li_xorshift32_seed(struct li_xorshift32_t *xor, uint32_t seed) { xor->state = seed ? seed : 1; xor->generator.rand = li_xorshift32; xor->generator.state = &(xor->state); } uint32_t li_xorshift32(void *s) { uint64_t x = *((uint64_t*)s); x ^= x >> 12; x ^= x << 25; x ^= x >> 27; x *= 0x2545F4914F6CDD1DULL; *((uint64_t*)s) = x; // return just top 32 bits return x >> 32; } li_llnode_t * li_alloc_llnode() { li_llnode_t *n = malloc(sizeof(li_llnode_t)); if (n == NULL) { fprintf(stderr, "failed to allocate linked-list node\n"); return NULL; } else { n->tag = 0; n->data = 0; n->next = NULL; return n; } } li_llnode_t * li_copy_llnode(li_llnode_t *n) { li_llnode_t *m = li_alloc_llnode(); if (m == NULL) { return NULL; } memcpy(m, n, sizeof(li_llnode_t)); return m; } void li_free_llnode(li_llnode_t *n, void (*free_data)(void*)) { if (n != NULL) { free_data(n->data); li_free_llnode(n->next, free_data); } free(n); } struct li_ll_t * li_alloc_ll() { struct li_ll_t *list = malloc(sizeof(struct li_ll_t)); if (list == NULL) { fprintf(stderr, "failed to allocate linked list\n"); return NULL; } list->tag = 0; list->count = 0; list->head = NULL; list->end = NULL; return list; } void li_free_ll(struct li_ll_t *list, void (*free_data)(void*)) { if (list != NULL) { li_free_llnode(list->head, free_data); } free(list); } int li_ll_append(struct li_ll_t *list, void *data) { li_llnode_t *n = li_alloc_llnode(); if (n == NULL) { return 1; } n->data = data; if (list->end != NULL) { list->end->next = n; list->end = n; } else { list->head = n; list->end = n; } list->count += 1; return 0; } int li_ll_prepend(struct li_ll_t *list, void *data) { li_llnode_t *n = li_alloc_llnode(); if (n == NULL) { return 1; } n->data = data; if (list->head != NULL) { n->next = list->head; list->head = n; } else { list->head = n; list->end = n; } list->count += 1; return 0; } int li_copy_list(struct li_ll_t **dst, struct li_ll_t *src, void *(*copy_data)(void*)) { *dst = li_alloc_ll(); if (*dst == NULL) { return 1; } (*dst)->tag = src->tag; for (li_llnode_t *n = src->head; n != NULL; n = n->next) { void *dup = copy_data(n->data); if (dup == NULL) { return 1; } if (li_ll_append(*dst, dup) != 0) { return 1; } } return 0; }