src/stringpair.c
author Krista Grothoff <krista@pep-project.org>
Tue, 12 Jul 2016 13:32:55 +0200
changeset 843 b1695eef237b
parent 836 8e7dac747b49
child 895 79a4cc341524
permissions -rw-r--r--
fix #104: fixed incorrect/confusing behaviour in stringlist_add/append stringpair_list_add/append.
     1 #include "pEp_internal.h"
     2 
     3 #include <stdlib.h>
     4 #include <assert.h>
     5 #include <string.h>
     6 
     7 #include "stringpair.h"
     8 
     9 DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
    10 {
    11     stringpair_t *pair = NULL;
    12 
    13     assert(key);
    14     assert(value),
    15 
    16     pair = calloc(1, sizeof(stringpair_t));
    17     assert(pair);
    18     if (pair == NULL)
    19         goto enomem;
    20 
    21     pair->key = strdup(key);
    22     assert(pair->key);
    23     if (pair->key == NULL)
    24         goto enomem;
    25 
    26     pair->value = strdup(value);
    27     assert(pair->value);
    28     if (pair->value == NULL)
    29         goto enomem;
    30 
    31     return pair;
    32 
    33 enomem:
    34     free_stringpair(pair);
    35     return NULL;
    36 }
    37 
    38 DYNAMIC_API void free_stringpair(stringpair_t * pair)
    39 {
    40     if (pair) {
    41         free(pair->key);
    42         free(pair->value);
    43         free(pair);
    44     }
    45 }
    46 
    47 DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
    48 {
    49     assert(src);
    50     if (src == NULL)
    51         return NULL;
    52     
    53     return new_stringpair(src->key, src->value);
    54 }
    55 
    56 DYNAMIC_API stringpair_list_t *new_stringpair_list(stringpair_t *value)
    57 {
    58     stringpair_list_t *result = calloc(1, sizeof(stringpair_list_t));
    59     assert(result);
    60 
    61     if (result && value)
    62         result->value = value;
    63 
    64     result->next = NULL;
    65     
    66     return result;
    67 }
    68 
    69 DYNAMIC_API stringpair_list_t *stringpair_list_dup(
    70         const stringpair_list_t *src
    71     )
    72 {
    73     assert(src);
    74     if (src == NULL)
    75         return NULL;
    76 
    77     stringpair_t* copy_pair = stringpair_dup(src->value);
    78     
    79     stringpair_list_t *dst = new_stringpair_list(copy_pair);
    80     if (dst == NULL)
    81         return NULL;
    82 
    83     stringpair_list_t* src_curr = src->next;
    84     stringpair_list_t** dst_curr_ptr = &dst->next;
    85 
    86     while (src_curr) {
    87         copy_pair = stringpair_dup(src_curr->value);
    88         *dst_curr_ptr = new_stringpair_list(copy_pair);
    89         src_curr = src_curr->next;
    90         dst_curr_ptr = &((*dst_curr_ptr)->next);
    91     }
    92 
    93     return dst;
    94     
    95 }
    96 
    97 DYNAMIC_API stringpair_list_t *stringpair_list_add(
    98         stringpair_list_t *stringpair_list,
    99         stringpair_t *value
   100     )
   101 {
   102     assert(value);
   103 
   104     // empty list (no nodes)
   105     if (stringpair_list == NULL)
   106         return new_stringpair_list(value);
   107 
   108     // empty list (one node, no value)
   109     if (stringpair_list->value == NULL) {
   110         if (stringpair_list->next)
   111             return NULL; // invalid list
   112             
   113         stringpair_list->value = value;
   114         assert(stringpair_list->value);
   115         
   116         if (stringpair_list->value == NULL)
   117             return NULL;
   118         
   119         return stringpair_list;
   120     }
   121     
   122     stringpair_list_t* list_curr = stringpair_list;
   123     
   124     while (list_curr->next)
   125         list_curr = list_curr->next;
   126      
   127     list_curr->next = new_stringpair_list(value);
   128 
   129     assert(list_curr->next);
   130     if (list_curr->next == NULL)
   131         return NULL;
   132 
   133     return list_curr->next;
   134     
   135 }
   136 
   137 DYNAMIC_API stringpair_list_t *stringpair_list_append(
   138         stringpair_list_t *stringpair_list,
   139         stringpair_list_t *second
   140     )
   141 {
   142     assert(stringpair_list);
   143     if (stringpair_list == NULL)
   144         return NULL;
   145 
   146     // second list is empty
   147     if (second == NULL || second->value == NULL)
   148         return stringpair_list;
   149 
   150     stringpair_list_t *_s = stringpair_list;
   151     stringpair_list_t *_s2;
   152     for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
   153         stringpair_t *_sp = stringpair_dup(_s2->value);
   154         if (_sp == NULL)
   155             return NULL;
   156         _s = stringpair_list_add(_s, _sp);
   157         if (_s == NULL){
   158             free_stringpair(_sp);
   159             return NULL;
   160         }
   161     }
   162     return _s;
   163 }
   164 
   165 DYNAMIC_API int stringpair_list_length(
   166         const stringpair_list_t *stringpair_list
   167     )
   168 {
   169     int len = 0;
   170 
   171     const stringpair_list_t *_sl;
   172     for (_sl = stringpair_list; _sl && _sl->value; _sl = _sl->next)
   173         len++;
   174 
   175     return len;
   176 }
   177 
   178 DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
   179 {
   180     if (stringpair_list) {
   181         free_stringpair_list(stringpair_list->next);
   182         free_stringpair(stringpair_list->value);
   183         free(stringpair_list);
   184     }
   185 }
   186 
   187 DYNAMIC_API stringpair_list_t *stringpair_list_find(
   188         stringpair_list_t *stringpair_list,
   189         const char *key
   190     )
   191 {
   192     assert(key);
   193 
   194     stringpair_list_t *_l;
   195     for (_l = stringpair_list; _l; _l = _l->next) {
   196         if (strcoll(key, _l->value->key) == 0)
   197             return _l;
   198     }
   199 
   200     return NULL;
   201 }
   202