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