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).
     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     if (stringlist->next != NULL)
    61         return stringlist_add(stringlist->next, value);
    62     if (stringlist->value == NULL) {
    63         stringlist->value = strdup(value);
    64         assert(stringlist->value);
    65         if (stringlist->value == NULL)
    66             return NULL;
    67         return stringlist;
    68     }
    69 
    70     stringlist->next = new_stringlist(value);
    71     assert(stringlist->next);
    72     if (stringlist->next == NULL)
    73         return NULL;
    74 
    75     return stringlist->next;
    76 }
    77 
    78 DYNAMIC_API stringlist_t *stringlist_append(
    79         stringlist_t *stringlist,
    80         stringlist_t *second
    81     )
    82 {
    83     assert(stringlist);
    84 
    85     if (second == NULL || second->value == NULL)
    86         return stringlist;
    87 
    88     stringlist_t *_s = stringlist;
    89     stringlist_t *_s2;
    90     for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
    91         _s = stringlist_add(_s, _s2->value);
    92         if (_s == NULL)
    93             return NULL;
    94     }
    95     return _s;
    96 }
    97 
    98 DYNAMIC_API int stringlist_length(const stringlist_t *stringlist)
    99 {
   100     int len = 0;
   101 
   102     const stringlist_t *_sl;
   103     for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next)
   104         len++;
   105 
   106     return len;
   107 }
   108 
   109 DYNAMIC_API stringlist_t *stringlist_delete(
   110         stringlist_t *stringlist,
   111         const char *value
   112     )
   113 {
   114     assert(stringlist);
   115     assert(value);
   116 
   117     if (stringlist->value == NULL) {
   118         free_stringlist(stringlist);
   119         return NULL;
   120     }
   121 
   122     if (value == NULL)
   123         return stringlist;
   124 
   125     stringlist_t *_sl;
   126     stringlist_t *last = NULL;
   127     for (_sl = stringlist; _sl && _sl->value; _sl = _sl->next) {
   128         if (strcmp(_sl->value, value) == 0) {
   129             if (last == NULL)
   130                 stringlist = stringlist->next;
   131             else
   132                 last->next = _sl->next;
   133             _sl->next = NULL;
   134             free_stringlist(_sl);
   135             break;
   136         }
   137         last = _sl;
   138     }
   139     return stringlist;
   140 }
   141 
   142 DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
   143 {
   144     if (stringlist) {
   145         free_stringlist(stringlist->next);
   146         free(stringlist->value);
   147         free(stringlist);
   148     }
   149 }
   150