src/labeled_int_list.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Thu, 04 Jun 2020 11:18:45 +0200
changeset 4729 3df9a2a67597
parent 3019 220ebfbe592c
child 4792 7056435ab9e7
permissions -rw-r--r--
forgot test files
krista@2964
     1
// This file is under GNU General Public License 3.0
krista@2964
     2
// see LICENSE.txt
krista@2964
     3
krista@2964
     4
#include <stdbool.h>
krista@2964
     5
#include <stdlib.h>
krista@2964
     6
#include <assert.h>
krista@2964
     7
#include <string.h>
krista@2964
     8
krista@2964
     9
#include "platform.h"
krista@2964
    10
#include "labeled_int_list.h"
krista@2964
    11
krista@3004
    12
DYNAMIC_API labeled_int_list_t *new_labeled_int_list(int value, const char* label)
krista@2964
    13
{
krista@2964
    14
    assert(label);
krista@2964
    15
    if (!label)
krista@2964
    16
        return NULL;
krista@2964
    17
        
krista@2964
    18
    labeled_int_list_t * labeled_int_list = calloc(1, sizeof(labeled_int_list_t));
krista@2964
    19
    assert(labeled_int_list);
krista@2964
    20
    if (labeled_int_list == NULL)
krista@2964
    21
        return NULL;
krista@2964
    22
krista@2964
    23
    labeled_int_list->value = value;
krista@2964
    24
    labeled_int_list->label = strdup(label);
krista@2964
    25
    if (!labeled_int_list->label) {
krista@2964
    26
        free(labeled_int_list);
krista@2964
    27
        labeled_int_list = NULL;
krista@2964
    28
    }
krista@2964
    29
    return labeled_int_list;
krista@2964
    30
}
krista@2964
    31
krista@3004
    32
DYNAMIC_API void free_labeled_int_list(labeled_int_list_t *labeled_int_list)
krista@2964
    33
{
krista@2964
    34
    labeled_int_list_t *curr = labeled_int_list;
krista@2964
    35
krista@2964
    36
    while (curr) {
krista@2964
    37
        labeled_int_list_t *next = curr->next;
krista@2964
    38
        free(curr->label);
krista@2964
    39
        free(curr);
krista@2964
    40
        curr = next;
krista@2964
    41
    }
krista@2964
    42
}
krista@2964
    43
krista@3004
    44
DYNAMIC_API labeled_int_list_t *labeled_int_list_dup(const labeled_int_list_t *src)
krista@2964
    45
{
krista@2964
    46
    assert(src);
krista@2964
    47
    if (src == NULL)
krista@2964
    48
        return NULL;
krista@2964
    49
    
krista@2964
    50
    labeled_int_list_t *labeled_int_list = NULL;
krista@2964
    51
krista@2964
    52
    labeled_int_list = new_labeled_int_list(src->value, src->label);
krista@2964
    53
    if (labeled_int_list == NULL)
krista@2964
    54
        goto enomem;
krista@2964
    55
krista@2964
    56
    labeled_int_list_t* src_curr = src->next;
krista@2964
    57
    labeled_int_list_t** dst_curr_ptr = &labeled_int_list->next;
krista@2964
    58
krista@2964
    59
    // list
krista@2964
    60
    while (src_curr) {
krista@2964
    61
        *dst_curr_ptr = new_labeled_int_list(src_curr->value, src_curr->label);
krista@2964
    62
        if (*dst_curr_ptr == NULL)
krista@2964
    63
            goto enomem;
krista@2964
    64
krista@2964
    65
        src_curr = src_curr->next;
krista@2964
    66
        dst_curr_ptr = &((*dst_curr_ptr)->next);
krista@2964
    67
    }
krista@2964
    68
krista@2964
    69
    return labeled_int_list;
krista@2964
    70
krista@2964
    71
enomem:
krista@2964
    72
    free_labeled_int_list(labeled_int_list);
krista@2964
    73
    return NULL;
krista@2964
    74
}
krista@2964
    75
krista@3004
    76
DYNAMIC_API labeled_int_list_t *labeled_int_list_add(labeled_int_list_t *labeled_int_list, int value, const char* label)
krista@2964
    77
{
krista@2964
    78
    if (!label)
krista@2964
    79
        return NULL;
krista@2964
    80
        
krista@2964
    81
    if (!labeled_int_list)
krista@2964
    82
        return new_labeled_int_list(value, label);
krista@2964
    83
krista@2964
    84
    if (!labeled_int_list->label) { // empty list
krista@2964
    85
        assert(!labeled_int_list->next);
krista@2964
    86
        if (labeled_int_list->next)
krista@2964
    87
            return NULL; // invalid list
krista@2964
    88
krista@2964
    89
        labeled_int_list->value = value;
krista@2964
    90
        labeled_int_list->label = strdup(label);
krista@2964
    91
        if (!labeled_int_list->label) {
krista@2964
    92
            free(labeled_int_list);
krista@2964
    93
            labeled_int_list = NULL;
krista@2964
    94
        }
krista@2964
    95
krista@2964
    96
        return labeled_int_list;
krista@2964
    97
    }
krista@2964
    98
krista@2964
    99
    labeled_int_list_t* list_curr = labeled_int_list;
krista@2964
   100
krista@2964
   101
    while (list_curr->next)
krista@2964
   102
        list_curr = list_curr->next;
krista@2964
   103
krista@2964
   104
    list_curr->next = new_labeled_int_list(value, label);
krista@2964
   105
krista@2964
   106
    assert(list_curr->next);
krista@2964
   107
    if (!list_curr->next)
krista@2964
   108
        return NULL;
krista@2964
   109
krista@2964
   110
    return list_curr->next;
krista@2964
   111
}
krista@2964
   112
krista@3004
   113
DYNAMIC_API int labeled_int_list_length(const labeled_int_list_t *labeled_int_list)
krista@2964
   114
{
krista@2964
   115
    int len = 0;
krista@2964
   116
krista@2964
   117
    for (const labeled_int_list_t *_li = labeled_int_list; _li && _li->label; _li = _li->next)
krista@2964
   118
        len++;
krista@2964
   119
krista@2964
   120
    return len;
vb@3019
   121
}
vb@3019
   122