From a336148cd2b0c529515e7b0d74afae9e0660cf6c Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 10 May 2012 00:30:03 +0100 Subject: [PATCH] Using GSList for contact list --- command.c | 2 +- contact_list.c | 175 +++++++++++++------------------------------- contact_list.h | 8 +- test_contact_list.c | 117 ++++++++++++++--------------- windows.c | 9 ++- windows.h | 2 +- 6 files changed, 123 insertions(+), 190 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 #include +#include + #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,69 +94,60 @@ 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) +GSList * get_contact_list(void) { - struct contact_node_t *copy = NULL; - struct contact_node_t *curr = _contact_list; - - copy = _copy_contact_list(curr); + GSList *copy = NULL; + GSList *curr = _contact_list; + + 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))); + + curr = g_slist_next(curr); + } return copy; } -struct contact_node_t * _copy_contact_list(struct contact_node_t *node) -{ - 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)); - - copy->next = _copy_contact_list(node->next); - - return copy; - } -} - char * find_contact(char *search_str) { char *found = NULL; @@ -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 + #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 #include +#include #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 #include +#include #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);