collection/gru_list_test.c

GRU linked list example

#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "collection/gru_list.h"
#include "collection/gru_node.h"

void check_val(const void *nodedata, void *data) {
    bool *exist = (bool *) data;
    uint32_t value = (*(uint32_t *) nodedata);

    if (value == 32) {
        *exist = true;
    }
}

static int comprehensive_test(int argc, char **argv) {
    gru_status_t status = gru_status_new();
    uint32_t list_size = 256;

    gru_list_t *list = gru_list_new(&status);

    if (!list) {
        printf("Unable to create a new list: %s\n", status.message);

        return EXIT_FAILURE;
    }

#if !defined(_WIN32) && !defined(_WIN64)
    uint32_t tmp[list_size];
#else
    uint32_t tmp[256];
#endif
    for (uint32_t i = 0; i < list_size; i++) {
        tmp[i] = i;
        gru_list_append(list, &tmp[i]);
    }

    uint32_t count = gru_list_count(list);
    if (count != 256) {
        printf("Unexpected list size: %i != %i\n", count, list_size);

        goto e_exit;
    }

    const gru_node_t *node64 = gru_list_get(list, 64);
    if (node64 == NULL) {
        printf("The node does not exist\n");

        goto e_exit;
    }

    uint32_t value = gru_node_get_data(uint32_t, node64);

    if (value != 64) {
        printf(
            "The value of the node does not match the expected: %i != %i\n", value, 64);

        goto e_exit;
    }

    uint32_t new_value = 444;
    gru_node_t *node = gru_list_insert(list, &new_value, 200);
    count = gru_list_count(list);
    if (count != 257) {
        printf("Unexpected list size: %" PRId32 "  != %" PRIu32 "\n", count, list_size + 1);

        goto e_exit;
    }

    node = gru_list_remove(list, 200);
    gru_node_destroy(&node);

    node = gru_list_remove(list, 200);
    gru_node_destroy(&node);

    node = gru_list_remove(list, 200);
    gru_node_destroy(&node);

    count = gru_list_count(list);
    if (count != 254) {
        printf("Unexpected list size: %i != %i\n", count, 254);

        goto e_exit;
    }

    bool exist = false;
    gru_list_for_each(list, check_val, &exist);
    if (!exist) {
        printf("Value 32 should be present on the list");

        goto e_exit;
    }

    gru_list_destroy(&list);
    if (list != NULL) {
        printf("List incorrectly destroyed\n");

        goto e_exit;
    }

    return EXIT_SUCCESS;

e_exit:
    gru_list_destroy(&list);
    if (list != NULL) {
        printf("List incorrectly destroyed\n");
    }

    return EXIT_FAILURE;
}

static int add_remove_test() {
    gru_status_t status = gru_status_new();
    uint32_t list_size = 15;

    gru_list_t *list = gru_list_new(&status);

    if (!list) {
        fprintf(stderr, "Unable to create a new list: %s\n", status.message);

        return EXIT_FAILURE;
    }

#if !defined(_WIN32) && !defined(_WIN64)
    uint32_t tmp[list_size];
#else
    uint32_t tmp[256];
#endif
    for (uint32_t i = 0; i < list_size; i++) {
        tmp[i] = i;
        gru_list_append(list, &tmp[i]);
    }

    gru_node_t *orphan = gru_list_remove(list, 0);
    if (list->root == orphan) {
        fprintf(stderr, "Removing the first node, should have updated the root\n");

        goto e_exit;
    }
    gru_node_destroy(&orphan);

    gru_node_t *sec = (gru_node_t *) gru_list_get(list, 1);
    if (!gru_list_remove_node(list, sec)) {
        fprintf(stderr, "Unable to remove specific node\n");

        goto e_exit;
    }
    gru_node_destroy(&sec);

    if (gru_list_count(list) != list_size - 2) {
        fprintf(stderr, "Invalid node count\n");

        goto e_exit;
    }

    for (uint32_t i = 0; i < (list_size - 2); i++) {
        gru_node_t *n1 = gru_list_remove(list, 0);
        if (!n1) {
            fprintf(stderr, "There should still be a node at position 0\n");
            goto e_exit;
        }
        gru_node_destroy(&n1);
    }

    gru_list_destroy(&list);
    if (list != NULL) {
        printf("List incorrectly destroyed\n");
    }
    return EXIT_SUCCESS;

e_exit:
    gru_list_destroy(&list);
    if (list != NULL) {
        printf("List incorrectly destroyed\n");
    }

    return EXIT_FAILURE;
}

int main(int argc, char **argv) {
    if (argc < 2) {
        return EXIT_FAILURE;
    } else {
        if (strncmp(argv[1], "comprehensive", 4) == 0) {
            return comprehensive_test((argc - 1), &argv[1]);
        } else if (strncmp(argv[1], "addremove", 4) == 0) {
            return add_remove_test();
        } else {
            return EXIT_FAILURE;
        }
    }

    return EXIT_SUCCESS;
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 7 Jan 2019 for GRU - Generic Reusable Utilities by  doxygen 1.6.1