src/stringlist.c
author Krista Bennett <krista@pep-project.org>
Fri, 04 May 2018 16:30:21 +0200
branchlocal_cpptest
changeset 2652 43b913f99a27
parent 1694 032e59ccdd93
child 2963 a80bc5f9167e
permissions -rw-r--r--
Shelving broken things to break other things
vb@1513
     1
// This file is under GNU General Public License 3.0
vb@1513
     2
// see LICENSE.txt
vb@1513
     3
vb@125
     4
#include "pEp_internal.h"
vb@125
     5
vb@98
     6
#include <stdlib.h>
vb@98
     7
#include <string.h>
vb@98
     8
#include <assert.h>
vb@98
     9
vb@98
    10
#include "stringlist.h"
vb@98
    11
vb@98
    12
vb@98
    13
DYNAMIC_API stringlist_t *new_stringlist(const char *value)
vb@98
    14
{
vb@107
    15
    stringlist_t *result = calloc(1, sizeof(stringlist_t));
vb@109
    16
    assert(result);
vb@109
    17
vb@98
    18
    if (result && value) {
vb@98
    19
        result->value = strdup(value);
vb@98
    20
        assert(result->value);
vb@98
    21
        if (result->value == 0) {
vb@98
    22
            free(result);
vb@98
    23
            return NULL;
vb@98
    24
        }
vb@98
    25
    }
vb@109
    26
vb@98
    27
    return result;
vb@98
    28
}
vb@98
    29
vb@98
    30
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
vb@98
    31
{
vb@98
    32
    assert(src);
vb@98
    33
    if (src == NULL)
vb@98
    34
        return NULL;
vb@98
    35
vb@98
    36
    stringlist_t *dst = new_stringlist(src->value);
vb@98
    37
    if (dst == NULL)
vb@98
    38
        return NULL;
vb@98
    39
krista@825
    40
    stringlist_t* src_curr = src->next;
krista@825
    41
    stringlist_t** dst_curr_ptr = &dst->next;
krista@825
    42
    
krista@825
    43
    while (src_curr) {
krista@825
    44
        *dst_curr_ptr = new_stringlist(src_curr->value);
krista@895
    45
        if (*dst_curr_ptr == NULL) {
krista@895
    46
            free_stringlist(dst);
krista@895
    47
            return NULL;
krista@895
    48
        }
krista@825
    49
        src_curr = src_curr->next;
krista@825
    50
        dst_curr_ptr = &((*dst_curr_ptr)->next);
vb@98
    51
    }
vb@98
    52
vb@98
    53
    return dst;
vb@98
    54
}
vb@98
    55
edouard@1694
    56
static bool _stringlist_add_first(
edouard@1694
    57
        stringlist_t *stringlist,
edouard@1694
    58
        stringlist_t **result,
edouard@1694
    59
        const char *value
edouard@1694
    60
    )
edouard@1694
    61
{  
edouard@1694
    62
    // empty list (no nodes)
edouard@1694
    63
    if (stringlist == NULL) {
edouard@1694
    64
        *result = new_stringlist(value);
edouard@1694
    65
        return true;
edouard@1694
    66
    }
edouard@1694
    67
edouard@1694
    68
    // empty list (one node, no value)
edouard@1694
    69
    if (stringlist->value == NULL) {
edouard@1694
    70
        if (stringlist->next) {
edouard@1694
    71
            *result = NULL; // invalid list
edouard@1694
    72
            return true;
edouard@1694
    73
        } 
edouard@1694
    74
            
edouard@1694
    75
        stringlist->value = strdup(value);
edouard@1694
    76
        assert(stringlist->value);
edouard@1694
    77
        
edouard@1694
    78
        if (stringlist->value == NULL) {
edouard@1694
    79
            *result = NULL;
edouard@1694
    80
            return true;
edouard@1694
    81
        }
edouard@1694
    82
        
edouard@1694
    83
        *result = stringlist;
edouard@1694
    84
        return true;
edouard@1694
    85
    }
edouard@1694
    86
    return false;
edouard@1694
    87
}
edouard@1694
    88
vb@113
    89
DYNAMIC_API stringlist_t *stringlist_add(
vb@113
    90
        stringlist_t *stringlist,
vb@113
    91
        const char *value
vb@113
    92
    )
krista@827
    93
{  
vb@98
    94
    assert(value);
krista@845
    95
    if (value == NULL)
krista@845
    96
        return NULL;
vb@98
    97
edouard@1694
    98
    stringlist_t *result = NULL;
edouard@1694
    99
    if(_stringlist_add_first(stringlist, &result, value))
edouard@1694
   100
        return result;
krista@843
   101
    
krista@827
   102
    stringlist_t* list_curr = stringlist;
krista@843
   103
krista@827
   104
    while (list_curr->next)
krista@827
   105
        list_curr = list_curr->next;
krista@843
   106
     
krista@827
   107
    list_curr->next = new_stringlist(value);
vb@98
   108
krista@827
   109
    assert(list_curr->next);
krista@827
   110
    if (list_curr->next == NULL)
vb@98
   111
        return NULL;
vb@98
   112
krista@827
   113
    return list_curr->next;
vb@98
   114
}
vb@98
   115
edouard@1694
   116
DYNAMIC_API stringlist_t *stringlist_add_unique(
edouard@1694
   117
        stringlist_t *stringlist,
edouard@1694
   118
        const char *value
edouard@1694
   119
    )
edouard@1694
   120
{  
edouard@1694
   121
    assert(value);
edouard@1694
   122
    if (value == NULL)
edouard@1694
   123
        return NULL;
edouard@1694
   124
edouard@1694
   125
    stringlist_t *result = NULL;
edouard@1694
   126
    if(_stringlist_add_first(stringlist, &result, value))
edouard@1694
   127
        return result;
edouard@1694
   128
    
edouard@1694
   129
    stringlist_t* list_curr = stringlist;
edouard@1694
   130
edouard@1694
   131
    bool found = false;
edouard@1694
   132
    while (list_curr->next) {
edouard@1694
   133
        if(strcmp(list_curr->value,value)==0)
edouard@1694
   134
            found = true;
edouard@1694
   135
        list_curr = list_curr->next;
edouard@1694
   136
    }
edouard@1694
   137
     
edouard@1694
   138
    if (!found) {
edouard@1694
   139
        list_curr->next = new_stringlist(value);
edouard@1694
   140
edouard@1694
   141
        assert(list_curr->next);
edouard@1694
   142
        if (list_curr->next == NULL)
edouard@1694
   143
            return NULL;
edouard@1694
   144
edouard@1694
   145
        return list_curr->next;
edouard@1694
   146
    } else {
edouard@1694
   147
        return list_curr;
edouard@1694
   148
    }
edouard@1694
   149
}
edouard@1694
   150
edouard@1694
   151
vb@113
   152
DYNAMIC_API stringlist_t *stringlist_append(
vb@113
   153
        stringlist_t *stringlist,
vb@113
   154
        stringlist_t *second
vb@113
   155
    )
vb@98
   156
{
vb@98
   157
    assert(stringlist);
krista@836
   158
    if (stringlist == NULL)
krista@836
   159
        return NULL;
vb@98
   160
krista@843
   161
    // Second list is empty
vb@98
   162
    if (second == NULL || second->value == NULL)
vb@98
   163
        return stringlist;
vb@98
   164
vb@98
   165
    stringlist_t *_s = stringlist;
vb@98
   166
    stringlist_t *_s2;
vb@98
   167
    for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
vb@98
   168
        _s = stringlist_add(_s, _s2->value);
vb@98
   169
        if (_s == NULL)
vb@98
   170
            return NULL;
vb@98
   171
    }
vb@98
   172
    return _s;
vb@98
   173
}
vb@98
   174
vb@98
   175
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist)
vb@98
   176
{
vb@301
   177
    int len = 0;
vb@98
   178
vb@301
   179
    const stringlist_t *_sl;
vb@301
   180
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next)
vb@301
   181
        len++;
vb@98
   182
vb@98
   183
    return len;
vb@98
   184
}
vb@98
   185
vb@523
   186
DYNAMIC_API stringlist_t *stringlist_delete(
vb@523
   187
        stringlist_t *stringlist,
vb@523
   188
        const char *value
vb@523
   189
    )
vb@523
   190
{
vb@523
   191
    assert(stringlist);
vb@523
   192
    assert(value);
vb@523
   193
vb@523
   194
    if (stringlist->value == NULL) {
vb@523
   195
        free_stringlist(stringlist);
vb@523
   196
        return NULL;
vb@523
   197
    }
vb@523
   198
vb@523
   199
    if (value == NULL)
vb@523
   200
        return stringlist;
vb@523
   201
vb@523
   202
    stringlist_t *_sl;
vb@523
   203
    stringlist_t *last = NULL;
vb@523
   204
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next) {
vb@523
   205
        if (strcmp(_sl->value, value) == 0) {
vb@523
   206
            if (last == NULL)
vb@523
   207
                stringlist = stringlist->next;
vb@523
   208
            else
vb@523
   209
                last->next = _sl->next;
vb@523
   210
            _sl->next = NULL;
vb@523
   211
            free_stringlist(_sl);
vb@523
   212
            break;
vb@523
   213
        }
vb@523
   214
        last = _sl;
vb@523
   215
    }
vb@523
   216
    return stringlist;
vb@523
   217
}
vb@523
   218
vb@98
   219
DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
vb@98
   220
{
krista@1615
   221
    stringlist_t *curr = stringlist;
krista@828
   222
    
krista@828
   223
    while (curr) {
roker@1559
   224
        stringlist_t *next = curr->next;
krista@828
   225
        free(curr->value);
krista@1615
   226
        curr->value = NULL;
krista@828
   227
        free(curr);
krista@828
   228
        curr = next;
vb@98
   229
    }
vb@98
   230
}