about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-05-10 00:30:03 +0100
committerJames Booth <boothj5@gmail.com>2012-05-10 00:30:03 +0100
commita336148cd2b0c529515e7b0d74afae9e0660cf6c (patch)
treeeae5b857545e67e84640b7816f2ced3ad1404e35
parentb2385010b5b81bd66b840802eb36b5a0945eba8b (diff)
downloadprofani-tty-a336148cd2b0c529515e7b0d74afae9e0660cf6c.tar.gz
Using GSList for contact list
-rw-r--r--command.c2
-rw-r--r--contact_list.c173
-rw-r--r--contact_list.h8
-rw-r--r--test_contact_list.c117
-rw-r--r--windows.c9
-rw-r--r--windows.h2
6 files changed, 122 insertions, 189 deletions
diff --git a/command.c b/command.c
index 1de58310..772d171f 100644
--- a/command.c
+++ b/command.c
@@ -170,7 +170,7 @@ static gboolean _cmd_who(void)
     if (conn_status != JABBER_CONNECTED) {
         cons_not_connected();
     } else {
-        struct contact_node_t *list = get_contact_list();
+        GSList *list = get_contact_list();
         cons_show_online_contacts(list);
     }
 
diff --git a/contact_list.c b/contact_list.c
index 1715e594..9b38373c 100644
--- a/contact_list.c
+++ b/contact_list.c
@@ -24,52 +24,32 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <glib.h>
+
 #include "contact.h"
 #include "contact_list.h"
 
 // internal contact list
-static struct contact_node_t * _contact_list = NULL;
+static GSList * _contact_list = NULL;
 
 // state of current tab completion, currrent node 
-static struct contact_node_t * _last_found = NULL;
+static GSList * _last_found = NULL;
 // and current search pattern
 static char * _search_str = NULL;
 
-static char * _search_contact_list_from(struct contact_node_t * curr);
-static struct contact_node_t * _make_contact_node(const char * const name, 
-    const char * const show, const char * const status);
-static struct contact_node_t * _copy_contact_list(struct contact_node_t *node);
-static void _insert_contact(struct contact_node_t *curr, 
-    struct contact_node_t *prev, const char * const name, 
-    const char * const show, const char * const status);
+static char * _search_contact_list_from(GSList * curr);
 
 void contact_list_clear(void)
 {
-    struct contact_node_t *curr = _contact_list;
-    
-    if (curr) {
-        while(curr) {
-            PContact contact = curr->contact;
-            p_contact_free(contact);
-            curr = curr->next;
-        }
-
-        free(_contact_list);
-        _contact_list = NULL;
+    g_slist_free_full(_contact_list, (GDestroyNotify)p_contact_free);
+    _contact_list = NULL;
         
-        reset_search_attempts();
-    }
+    reset_search_attempts();
 }
 
-void destroy_list(struct contact_node_t *list)
+void destroy_list(GSList *list)
 {
-    while(list) {
-        PContact contact = list->contact;
-        p_contact_free(contact);
-        list = list->next;
-    }
-
-    free(list);
+    g_slist_free_full(list, (GDestroyNotify)p_contact_free);
     list = NULL;
 }
 
@@ -84,34 +64,26 @@ void reset_search_attempts(void)
 
 int contact_list_remove(const char * const name)
 {
+    // reset last found if it points at the node to be removed
+    if (_last_found != NULL)
+        if (strcmp(p_contact_name(_last_found->data), name) == 0)
+            _last_found = NULL;
+    
     if (!_contact_list) {
         return 0;
     } else {
-        struct contact_node_t *curr = _contact_list;
-        struct contact_node_t *prev = NULL;
+        GSList *curr = _contact_list;
         
         while(curr) {
-            PContact contact = curr->contact;
+            PContact contact = curr->data;
             if (strcmp(p_contact_name(contact), name) == 0) {
-                if (prev)
-                    prev->next = curr->next;
-                else
-                    _contact_list = curr->next;
-
-                // reset last found if it points at the node to be removed
-                if (_last_found != NULL)
-                    if (strcmp(p_contact_name(_last_found->contact), 
-                                p_contact_name(contact)) == 0)
-                        _last_found = NULL;
-
+                _contact_list = g_slist_remove(_contact_list, contact);
                 p_contact_free(contact);
-                free(curr);
 
                 return 1;
             }
 
-            prev = curr;
-            curr = curr->next;
+            curr = g_slist_next(curr);
         }
 
         return 0;
@@ -122,67 +94,58 @@ int contact_list_add(const char * const name, const char * const show,
     const char * const status)
 {
 
+    // empty list, create new
     if (!_contact_list) {
-        _contact_list = _make_contact_node(name, show, status);
+        _contact_list = g_slist_append(_contact_list, 
+            p_contact_new(name, show, status));
         
         return 1;
     } else {
-        struct contact_node_t *curr = _contact_list;
-        struct contact_node_t *prev = NULL;
+        GSList *curr = _contact_list;
 
         while(curr) {
-            PContact curr_contact = curr->contact;
+            PContact curr_contact = curr->data;
 
             // insert    
             if (strcmp(p_contact_name(curr_contact), name) > 0) {
-                _insert_contact(curr, prev, name, show, status);
+                _contact_list = g_slist_insert_before(_contact_list,
+                    curr, p_contact_new(name, show, status));
                 return 0;
             // update
             } else if (strcmp(p_contact_name(curr_contact), name) == 0) {
-                p_contact_free(curr->contact);
-                curr->contact = p_contact_new(name, show, status);
+                p_contact_free(curr->data);
+                curr->data = p_contact_new(name, show, status);
                 return 0;
             }
 
-            // move on
-            prev = curr;
-            curr = curr->next;
+            curr = g_slist_next(curr);
         }
 
-        curr = _make_contact_node(name, show, status);    
+        // hit end, append
+        _contact_list = g_slist_append(_contact_list, 
+            p_contact_new(name, show, status));
         
-        if (prev)
-            prev->next = curr;
-
         return 1;
     }
 }
 
-struct contact_node_t * get_contact_list(void)
-{
-    struct contact_node_t *copy = NULL;
-    struct contact_node_t *curr = _contact_list;
-    
-    copy = _copy_contact_list(curr);
-
-    return copy;
-}
-
-struct contact_node_t * _copy_contact_list(struct contact_node_t *node)
+GSList * get_contact_list(void)
 {
-    if (node == NULL) {
-        return NULL;
-    } else {
-        PContact curr_contact = node->contact;
-        struct contact_node_t *copy = 
-            _make_contact_node(p_contact_name(curr_contact), 
-                               p_contact_show(curr_contact), 
-                               p_contact_status(curr_contact));
+    GSList *copy = NULL;
+    GSList *curr = _contact_list;
 
-        copy->next = _copy_contact_list(node->next);
+    while(curr) {
+        PContact curr_contact = curr->data;
+        
+        copy = g_slist_append(copy, 
+            p_contact_new(p_contact_name(curr_contact),
+                          p_contact_show(curr_contact),
+                          p_contact_status(curr_contact)));
 
-        return copy;
+        curr = g_slist_next(curr);
     }
+
+    return copy;
 }
 
 char * find_contact(char *search_str)
@@ -204,7 +167,7 @@ char * find_contact(char *search_str)
     // subsequent search attempt
     } else {
         // search from here+1 to end 
-        found = _search_contact_list_from(_last_found->next);
+        found = _search_contact_list_from(g_slist_next(_last_found));
         if (found != NULL)
             return found;
 
@@ -219,22 +182,15 @@ char * find_contact(char *search_str)
     }
 }
 
-int get_size(struct contact_node_t *list)
+int get_size(GSList *list)
 {
-    int size = 0;
-
-    while(list) {
-        size++;
-        list = list->next;
-    }
-
-    return size;
+    return g_slist_length(list);
 }
 
-static char * _search_contact_list_from(struct contact_node_t * curr)
+static char * _search_contact_list_from(GSList * curr)
 {
     while(curr) {
-        PContact curr_contact = curr->contact;
+        PContact curr_contact = curr->data;
         
         // match found
         if (strncmp(p_contact_name(curr_contact), 
@@ -252,35 +208,8 @@ static char * _search_contact_list_from(struct contact_node_t * curr)
             return result;
         }
 
-        curr = curr->next;
+        curr = g_slist_next(curr);
     }
 
     return NULL;
 }
-
-static struct contact_node_t * _make_contact_node(const char * const name, 
-    const char * const show, const char * const status)
-{
-    struct contact_node_t *new = 
-        (struct contact_node_t *) malloc(sizeof(struct contact_node_t));
-    new->contact = p_contact_new(name, show, status);
-    new->next = NULL;
-
-    return new;
-}
-
-static void _insert_contact(struct contact_node_t *curr, 
-    struct contact_node_t *prev, const char * const name,
-    const char * const show, const char * const status)
-{
-    if (prev) {
-        struct contact_node_t *new = _make_contact_node(name, show, status);
-        new->next = curr;
-        prev->next = new;
-    } else {
-        struct contact_node_t *new = _make_contact_node(name, show, status);
-        new->next = _contact_list;
-        _contact_list = new;
-    }
-}
-
diff --git a/contact_list.h b/contact_list.h
index 491552a7..12c827de 100644
--- a/contact_list.h
+++ b/contact_list.h
@@ -23,6 +23,8 @@
 #ifndef CONTACT_LIST_H
 #define CONTACT_LIST_H
 
+#include <glib.h>
+
 #include "contact.h"
 
 struct contact_node_t {
@@ -35,9 +37,9 @@ void reset_search_attempts(void);
 int contact_list_add(const char * const name, const char * const show,
     const char * const status);
 int contact_list_remove(const char * const name);
-struct contact_node_t * get_contact_list(void);
+GSList * get_contact_list(void);
 char * find_contact(char *search_str);
-int get_size(struct contact_node_t *list);
-void destroy_list(struct contact_node_t *list);
+int get_size(GSList *list);
+void destroy_list(GSList *list);
 
 #endif
diff --git a/test_contact_list.c b/test_contact_list.c
index 106f6438..66be1dfb 100644
--- a/test_contact_list.c
+++ b/test_contact_list.c
@@ -3,6 +3,7 @@
 #include <string.h>
 
 #include <head-unit.h>
+#include <glib.h>
 
 #include "contact.h"
 #include "contact_list.h"
@@ -19,7 +20,7 @@ static void aftertest(void)
 
 static void empty_list_when_none_added(void)
 {
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     assert_is_null(list);
     destroy_list(list);
 }
@@ -27,7 +28,7 @@ static void empty_list_when_none_added(void)
 static void contains_one_element(void)
 {
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     assert_int_equals(1, get_size(list));
     destroy_list(list);
 }
@@ -35,8 +36,8 @@ static void contains_one_element(void)
 static void first_element_correct(void)
 {
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
 
     assert_string_equals("James", p_contact_name(james));
     destroy_list(list);
@@ -46,7 +47,7 @@ static void contains_two_elements(void)
 {
     contact_list_add("James", NULL, NULL);
     contact_list_add("Dave", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(2, get_size(list));
     destroy_list(list);
@@ -56,10 +57,10 @@ static void first_and_second_elements_correct(void)
 {
     contact_list_add("James", NULL, NULL);
     contact_list_add("Dave", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
-    PContact dave = list->contact;
-    PContact james = (list->next)->contact;
+    PContact dave = list->data;
+    PContact james = (g_slist_next(list))->data;
     
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("Dave", p_contact_name(dave));
@@ -71,7 +72,7 @@ static void contains_three_elements(void)
     contact_list_add("James", NULL, NULL);
     contact_list_add("Bob", NULL, NULL);
     contact_list_add("Dave", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(3, get_size(list));
     destroy_list(list);
@@ -82,10 +83,10 @@ static void first_three_elements_correct(void)
     contact_list_add("Bob", NULL, NULL);
     contact_list_add("Dave", NULL, NULL);
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact bob = list->contact;
-    PContact dave = (list->next)->contact;
-    PContact james = ((list->next)->next)->contact;
+    GSList *list = get_contact_list();
+    PContact bob = list->data;
+    PContact dave = (g_slist_next(list))->data;
+    PContact james = (g_slist_next(g_slist_next(list)))->data;
     
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("Dave", p_contact_name(dave));
@@ -99,10 +100,10 @@ static void add_twice_at_beginning_adds_once(void)
     contact_list_add("James", NULL, NULL);
     contact_list_add("Dave", NULL, NULL);
     contact_list_add("Bob", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact bob = list->contact;
-    PContact dave = (list->next)->contact;
-    PContact james = ((list->next)->next)->contact;
+    GSList *list = get_contact_list();
+    PContact bob = list->data;
+    PContact dave = (g_slist_next(list))->data;
+    PContact james = (g_slist_next(g_slist_next(list)))->data;
     
     assert_int_equals(3, get_size(list));    
     assert_string_equals("James", p_contact_name(james));
@@ -117,10 +118,10 @@ static void add_twice_in_middle_adds_once(void)
     contact_list_add("Dave", NULL, NULL);
     contact_list_add("James", NULL, NULL);
     contact_list_add("Bob", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact bob = list->contact;
-    PContact dave = (list->next)->contact;
-    PContact james = ((list->next)->next)->contact;
+    GSList *list = get_contact_list();
+    PContact bob = list->data;
+    PContact dave = (g_slist_next(list))->data;
+    PContact james = (g_slist_next(g_slist_next(list)))->data;
     
     assert_int_equals(3, get_size(list));    
     assert_string_equals("James", p_contact_name(james));
@@ -135,10 +136,10 @@ static void add_twice_at_end_adds_once(void)
     contact_list_add("Dave", NULL, NULL);
     contact_list_add("Bob", NULL, NULL);
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact bob = list->contact;
-    PContact dave = (list->next)->contact;
-    PContact james = ((list->next)->next)->contact;
+    GSList *list = get_contact_list();
+    PContact bob = list->data;
+    PContact dave = (g_slist_next(list))->data;
+    PContact james = (g_slist_next(g_slist_next(list)))->data;
     
     assert_int_equals(3, get_size(list));    
     assert_string_equals("James", p_contact_name(james));
@@ -150,7 +151,7 @@ static void add_twice_at_end_adds_once(void)
 static void remove_when_none_does_nothing(void)
 {
     contact_list_remove("James");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(0, get_size(list));
     destroy_list(list);
@@ -160,7 +161,7 @@ static void remove_when_one_removes(void)
 {
     contact_list_add("James", NULL, NULL);
     contact_list_remove("James");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(0, get_size(list));
     destroy_list(list);
@@ -172,10 +173,10 @@ static void remove_first_when_two(void)
     contact_list_add("Dave", NULL, NULL);
 
     contact_list_remove("James");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(1, get_size(list));
-    PContact dave = list->contact;
+    PContact dave = list->data;
     assert_string_equals("Dave", p_contact_name(dave));
     destroy_list(list);
 }
@@ -186,10 +187,10 @@ static void remove_second_when_two(void)
     contact_list_add("Dave", NULL, NULL);
 
     contact_list_remove("Dave");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(1, get_size(list));
-    PContact james = list->contact;
+    PContact james = list->data;
     assert_string_equals("James", p_contact_name(james));
     destroy_list(list);
 }
@@ -201,11 +202,11 @@ static void remove_first_when_three(void)
     contact_list_add("Bob", NULL, NULL);
 
     contact_list_remove("James");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(2, get_size(list));
-    PContact bob = list->contact;
-    PContact dave = (list->next)->contact;
+    PContact bob = list->data;
+    PContact dave = (g_slist_next(list))->data;
     
     assert_string_equals("Dave", p_contact_name(dave));
     assert_string_equals("Bob", p_contact_name(bob));
@@ -219,11 +220,11 @@ static void remove_second_when_three(void)
     contact_list_add("Bob", NULL, NULL);
 
     contact_list_remove("Dave");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(2, get_size(list));
-    PContact bob = list->contact;
-    PContact james = (list->next)->contact;
+    PContact bob = list->data;
+    PContact james = (g_slist_next(list))->data;
     
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("Bob", p_contact_name(bob));
@@ -237,11 +238,11 @@ static void remove_third_when_three(void)
     contact_list_add("Bob", NULL, NULL);
 
     contact_list_remove("Bob");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
     
     assert_int_equals(2, get_size(list));
-    PContact dave = list->contact;
-    PContact james = (list->next)->contact;
+    PContact dave = list->data;
+    PContact james = (g_slist_next(list))->data;
     
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("Dave", p_contact_name(dave));
@@ -251,8 +252,8 @@ static void remove_third_when_three(void)
 static void test_show_when_value(void)
 {
     contact_list_add("James", "away", NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
     
     assert_string_equals("away", p_contact_show(james));
     destroy_list(list);
@@ -261,8 +262,8 @@ static void test_show_when_value(void)
 static void test_show_online_when_no_value(void)
 {
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
     
     assert_string_equals("online", p_contact_show(james));
     destroy_list(list);
@@ -271,8 +272,8 @@ static void test_show_online_when_no_value(void)
 static void test_show_online_when_empty_string(void)
 {
     contact_list_add("James", "", NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
     
     assert_string_equals("online", p_contact_show(james));
     destroy_list(list);
@@ -281,8 +282,8 @@ static void test_show_online_when_empty_string(void)
 static void test_status_when_value(void)
 {
     contact_list_add("James", NULL, "I'm not here right now");
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
     
     assert_string_equals("I'm not here right now", p_contact_status(james));
     destroy_list(list);
@@ -291,8 +292,8 @@ static void test_status_when_value(void)
 static void test_status_when_no_value(void)
 {
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
-    PContact james = list->contact;
+    GSList *list = get_contact_list();
+    PContact james = list->data;
     
     assert_is_null(p_contact_status(james));
     destroy_list(list);
@@ -302,10 +303,10 @@ static void update_show(void)
 {
     contact_list_add("James", "away", NULL);
     contact_list_add("James", "dnd", NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(1, get_size(list));
-    PContact james = list->contact;
+    PContact james = list->data;
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("dnd", p_contact_show(james));
     destroy_list(list);
@@ -315,10 +316,10 @@ static void set_show_to_null(void)
 {
     contact_list_add("James", "away", NULL);
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(1, get_size(list));
-    PContact james = list->contact;
+    PContact james = list->data;
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("online", p_contact_show(james));
     destroy_list(list);
@@ -328,10 +329,10 @@ static void update_status(void)
 {
     contact_list_add("James", NULL, "I'm not here right now");
     contact_list_add("James", NULL, "Gone to lunch");
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(1, get_size(list));
-    PContact james = list->contact;
+    PContact james = list->data;
     assert_string_equals("James", p_contact_name(james));
     assert_string_equals("Gone to lunch", p_contact_status(james));
     destroy_list(list);
@@ -341,10 +342,10 @@ static void set_status_to_null(void)
 {
     contact_list_add("James", NULL, "Gone to lunch");
     contact_list_add("James", NULL, NULL);
-    struct contact_node_t *list = get_contact_list();
+    GSList *list = get_contact_list();
 
     assert_int_equals(1, get_size(list));
-    PContact james = list->contact;
+    PContact james = list->data;
     assert_string_equals("James", p_contact_name(james));
     assert_is_null(p_contact_status(james));
     destroy_list(list);
diff --git a/windows.c b/windows.c
index 7af787d8..db3a6a84 100644
--- a/windows.c
+++ b/windows.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 
 #include <ncurses.h>
+#include <glib.h>
 
 #include "windows.h"
 #include "util.h"
@@ -294,15 +295,15 @@ void cons_help(void)
         dirty = TRUE;
 }
 
-void cons_show_online_contacts(struct contact_node_t *list)
+void cons_show_online_contacts(GSList *list)
 {
     _win_show_time(_cons_win);
     wprintw(_cons_win, "Online contacts:\n");
 
-    struct contact_node_t *curr = list;
+    GSList *curr = list;
 
     while(curr) {
-        PContact contact = curr->contact;
+        PContact contact = curr->data;
         _win_show_time(_cons_win);
         wattron(_cons_win, COLOR_PAIR(2));
         wprintw(_cons_win, "%s", p_contact_name(contact));
@@ -313,7 +314,7 @@ void cons_show_online_contacts(struct contact_node_t *list)
         wprintw(_cons_win, "\n");
         wattroff(_cons_win, COLOR_PAIR(2));
 
-        curr = curr->next;
+        curr = g_slist_next(curr);
     }
 }
 
diff --git a/windows.h b/windows.h
index ee051783..c264bd0e 100644
--- a/windows.h
+++ b/windows.h
@@ -79,7 +79,7 @@ void cons_bad_message(void);
 void cons_show(const char * const cmd);
 void cons_bad_show(const char * const cmd);
 void cons_highlight_show(const char * const cmd);
-void cons_show_online_contacts(struct contact_node_t * list);
+void cons_show_online_contacts(GSList * list);
 
 // status bar actions
 void status_bar_refresh(void);