src/stringlist.c
author Krista Grothoff <krista@pep-project.org>
Mon, 11 Jul 2016 02:53:09 +0200
changeset 825 c5b5500a978d
parent 523 afaf34a57cc6
child 827 37f1b63ecf97
permissions -rw-r--r--
fix #11: made stringlist_dup iterative, added NULL to new_stringlist for next ptr (this wasn't set for one-element lists).
vb@125
     1
#include "pEp_internal.h"
vb@125
     2
vb@98
     3
#include <stdlib.h>
vb@98
     4
#include <string.h>
vb@98
     5
#include <assert.h>
vb@98
     6
vb@98
     7
#include "stringlist.h"
vb@98
     8
vb@98
     9
vb@98
    10
DYNAMIC_API stringlist_t *new_stringlist(const char *value)
vb@98
    11
{
vb@107
    12
    stringlist_t *result = calloc(1, sizeof(stringlist_t));
vb@109
    13
    assert(result);
vb@109
    14
vb@98
    15
    if (result && value) {
vb@98
    16
        result->value = strdup(value);
vb@98
    17
        assert(result->value);
vb@98
    18
        if (result->value == 0) {
vb@98
    19
            free(result);
vb@98
    20
            return NULL;
vb@98
    21
        }
krista@825
    22
        result->next = NULL; // needed for one-element lists
vb@98
    23
    }
vb@109
    24
vb@98
    25
    return result;
vb@98
    26
}
vb@98
    27
vb@98
    28
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
vb@98
    29
{
vb@98
    30
    assert(src);
vb@98
    31
    if (src == NULL)
vb@98
    32
        return NULL;
vb@98
    33
vb@98
    34
    stringlist_t *dst = new_stringlist(src->value);
vb@98
    35
    if (dst == NULL)
vb@98
    36
        return NULL;
vb@98
    37
krista@825
    38
    stringlist_t* src_curr = src->next;
krista@825
    39
    stringlist_t** dst_curr_ptr = &dst->next;
krista@825
    40
    
krista@825
    41
    while (src_curr) {
krista@825
    42
        *dst_curr_ptr = new_stringlist(src_curr->value);
krista@825
    43
        src_curr = src_curr->next;
krista@825
    44
        dst_curr_ptr = &((*dst_curr_ptr)->next);
vb@98
    45
    }
vb@98
    46
vb@98
    47
    return dst;
vb@98
    48
}
vb@98
    49
vb@113
    50
DYNAMIC_API stringlist_t *stringlist_add(
vb@113
    51
        stringlist_t *stringlist,
vb@113
    52
        const char *value
vb@113
    53
    )
vb@98
    54
{
vb@98
    55
    assert(value);
vb@98
    56
vb@98
    57
    if (stringlist == NULL)
vb@98
    58
        return new_stringlist(value);
vb@98
    59
vb@98
    60
    if (stringlist->next != NULL)
vb@98
    61
        return stringlist_add(stringlist->next, value);
vb@98
    62
    if (stringlist->value == NULL) {
vb@98
    63
        stringlist->value = strdup(value);
vb@98
    64
        assert(stringlist->value);
vb@98
    65
        if (stringlist->value == NULL)
vb@98
    66
            return NULL;
vb@98
    67
        return stringlist;
vb@98
    68
    }
vb@98
    69
vb@98
    70
    stringlist->next = new_stringlist(value);
vb@98
    71
    assert(stringlist->next);
vb@98
    72
    if (stringlist->next == NULL)
vb@98
    73
        return NULL;
vb@98
    74
vb@98
    75
    return stringlist->next;
vb@98
    76
}
vb@98
    77
vb@113
    78
DYNAMIC_API stringlist_t *stringlist_append(
vb@113
    79
        stringlist_t *stringlist,
vb@113
    80
        stringlist_t *second
vb@113
    81
    )
vb@98
    82
{
vb@98
    83
    assert(stringlist);
vb@98
    84
vb@98
    85
    if (second == NULL || second->value == NULL)
vb@98
    86
        return stringlist;
vb@98
    87
vb@98
    88
    stringlist_t *_s = stringlist;
vb@98
    89
    stringlist_t *_s2;
vb@98
    90
    for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
vb@98
    91
        _s = stringlist_add(_s, _s2->value);
vb@98
    92
        if (_s == NULL)
vb@98
    93
            return NULL;
vb@98
    94
    }
vb@98
    95
    return _s;
vb@98
    96
}
vb@98
    97
vb@98
    98
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist)
vb@98
    99
{
vb@301
   100
    int len = 0;
vb@98
   101
vb@301
   102
    const stringlist_t *_sl;
vb@301
   103
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next)
vb@301
   104
        len++;
vb@98
   105
vb@98
   106
    return len;
vb@98
   107
}
vb@98
   108
vb@523
   109
DYNAMIC_API stringlist_t *stringlist_delete(
vb@523
   110
        stringlist_t *stringlist,
vb@523
   111
        const char *value
vb@523
   112
    )
vb@523
   113
{
vb@523
   114
    assert(stringlist);
vb@523
   115
    assert(value);
vb@523
   116
vb@523
   117
    if (stringlist->value == NULL) {
vb@523
   118
        free_stringlist(stringlist);
vb@523
   119
        return NULL;
vb@523
   120
    }
vb@523
   121
vb@523
   122
    if (value == NULL)
vb@523
   123
        return stringlist;
vb@523
   124
vb@523
   125
    stringlist_t *_sl;
vb@523
   126
    stringlist_t *last = NULL;
vb@523
   127
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next) {
vb@523
   128
        if (strcmp(_sl->value, value) == 0) {
vb@523
   129
            if (last == NULL)
vb@523
   130
                stringlist = stringlist->next;
vb@523
   131
            else
vb@523
   132
                last->next = _sl->next;
vb@523
   133
            _sl->next = NULL;
vb@523
   134
            free_stringlist(_sl);
vb@523
   135
            break;
vb@523
   136
        }
vb@523
   137
        last = _sl;
vb@523
   138
    }
vb@523
   139
    return stringlist;
vb@523
   140
}
vb@523
   141
vb@98
   142
DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
vb@98
   143
{
vb@98
   144
    if (stringlist) {
vb@98
   145
        free_stringlist(stringlist->next);
vb@98
   146
        free(stringlist->value);
vb@98
   147
        free(stringlist);
vb@98
   148
    }
vb@98
   149
}
vb@98
   150