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