src/stringlist.c
author Krista Grothoff <krista@pep-project.org>
Tue, 12 Jul 2016 14:26:50 +0200
changeset 845 d4bb3516e01c
parent 843 b1695eef237b
child 895 79a4cc341524
permissions -rw-r--r--
fix #104 (continued): if after assert value in stringlist_add
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
        }
vb@98
    22
    }
krista@843
    23
    
krista@843
    24
    result->next = NULL; // needed for one-element lists
vb@109
    25
vb@98
    26
    return result;
vb@98
    27
}
vb@98
    28
vb@98
    29
DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
vb@98
    30
{
vb@98
    31
    assert(src);
vb@98
    32
    if (src == NULL)
vb@98
    33
        return NULL;
vb@98
    34
vb@98
    35
    stringlist_t *dst = new_stringlist(src->value);
vb@98
    36
    if (dst == NULL)
vb@98
    37
        return NULL;
vb@98
    38
krista@825
    39
    stringlist_t* src_curr = src->next;
krista@825
    40
    stringlist_t** dst_curr_ptr = &dst->next;
krista@825
    41
    
krista@825
    42
    while (src_curr) {
krista@825
    43
        *dst_curr_ptr = new_stringlist(src_curr->value);
krista@825
    44
        src_curr = src_curr->next;
krista@825
    45
        dst_curr_ptr = &((*dst_curr_ptr)->next);
vb@98
    46
    }
vb@98
    47
vb@98
    48
    return dst;
vb@98
    49
}
vb@98
    50
vb@113
    51
DYNAMIC_API stringlist_t *stringlist_add(
vb@113
    52
        stringlist_t *stringlist,
vb@113
    53
        const char *value
vb@113
    54
    )
krista@827
    55
{  
vb@98
    56
    assert(value);
krista@845
    57
    if (value == NULL)
krista@845
    58
        return NULL;
vb@98
    59
krista@843
    60
    // empty list (no nodes)
vb@98
    61
    if (stringlist == NULL)
vb@98
    62
        return new_stringlist(value);
vb@98
    63
krista@843
    64
    // empty list (one node, no value)
krista@843
    65
    if (stringlist->value == NULL) {
krista@843
    66
        if (stringlist->next) 
krista@843
    67
            return NULL; // invalid list
krista@843
    68
            
krista@843
    69
        stringlist->value = strdup(value);
krista@843
    70
        assert(stringlist->value);
krista@843
    71
        
krista@843
    72
        if (stringlist->value == NULL)
krista@843
    73
            return NULL;
krista@843
    74
        
krista@843
    75
        return stringlist;
krista@843
    76
    }
krista@843
    77
    
krista@827
    78
    stringlist_t* list_curr = stringlist;
krista@843
    79
krista@827
    80
    while (list_curr->next)
krista@827
    81
        list_curr = list_curr->next;
krista@843
    82
     
krista@827
    83
    list_curr->next = new_stringlist(value);
vb@98
    84
krista@827
    85
    assert(list_curr->next);
krista@827
    86
    if (list_curr->next == NULL)
vb@98
    87
        return NULL;
vb@98
    88
krista@827
    89
    return list_curr->next;
vb@98
    90
}
vb@98
    91
vb@113
    92
DYNAMIC_API stringlist_t *stringlist_append(
vb@113
    93
        stringlist_t *stringlist,
vb@113
    94
        stringlist_t *second
vb@113
    95
    )
vb@98
    96
{
vb@98
    97
    assert(stringlist);
krista@836
    98
    if (stringlist == NULL)
krista@836
    99
        return NULL;
vb@98
   100
krista@843
   101
    // Second list is empty
vb@98
   102
    if (second == NULL || second->value == NULL)
vb@98
   103
        return stringlist;
vb@98
   104
vb@98
   105
    stringlist_t *_s = stringlist;
vb@98
   106
    stringlist_t *_s2;
vb@98
   107
    for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
vb@98
   108
        _s = stringlist_add(_s, _s2->value);
vb@98
   109
        if (_s == NULL)
vb@98
   110
            return NULL;
vb@98
   111
    }
vb@98
   112
    return _s;
vb@98
   113
}
vb@98
   114
vb@98
   115
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist)
vb@98
   116
{
vb@301
   117
    int len = 0;
vb@98
   118
vb@301
   119
    const stringlist_t *_sl;
vb@301
   120
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next)
vb@301
   121
        len++;
vb@98
   122
vb@98
   123
    return len;
vb@98
   124
}
vb@98
   125
vb@523
   126
DYNAMIC_API stringlist_t *stringlist_delete(
vb@523
   127
        stringlist_t *stringlist,
vb@523
   128
        const char *value
vb@523
   129
    )
vb@523
   130
{
vb@523
   131
    assert(stringlist);
vb@523
   132
    assert(value);
vb@523
   133
vb@523
   134
    if (stringlist->value == NULL) {
vb@523
   135
        free_stringlist(stringlist);
vb@523
   136
        return NULL;
vb@523
   137
    }
vb@523
   138
vb@523
   139
    if (value == NULL)
vb@523
   140
        return stringlist;
vb@523
   141
vb@523
   142
    stringlist_t *_sl;
vb@523
   143
    stringlist_t *last = NULL;
vb@523
   144
    for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next) {
vb@523
   145
        if (strcmp(_sl->value, value) == 0) {
vb@523
   146
            if (last == NULL)
vb@523
   147
                stringlist = stringlist->next;
vb@523
   148
            else
vb@523
   149
                last->next = _sl->next;
vb@523
   150
            _sl->next = NULL;
vb@523
   151
            free_stringlist(_sl);
vb@523
   152
            break;
vb@523
   153
        }
vb@523
   154
        last = _sl;
vb@523
   155
    }
vb@523
   156
    return stringlist;
vb@523
   157
}
vb@523
   158
vb@98
   159
DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
vb@98
   160
{
krista@828
   161
    stringlist_t *curr;
krista@828
   162
    stringlist_t *next;
krista@828
   163
    
krista@828
   164
    curr = stringlist;
krista@828
   165
    
krista@828
   166
    while (curr) {
krista@828
   167
        next = curr->next;
krista@828
   168
        free(curr->value);
krista@828
   169
        free(curr);
krista@828
   170
        curr = next;
vb@98
   171
    }
vb@98
   172
}
vb@98
   173