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