From 0e9451f5e8fe5a14d8ca73a71f557e3f680fe0bd Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 18:01:13 +0000 Subject: [PATCH 01/10] Allocate memory for additional /who completion --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index e9f40409..cd62c742 100644 --- a/src/command.c +++ b/src/command.c @@ -442,7 +442,7 @@ cmd_init(void) p_autocomplete_add(who_ac, (gchar *)strdup(pcmd->cmd+1)); } - p_autocomplete_add(who_ac, "offline"); + p_autocomplete_add(who_ac, strdup("offline")); history_init(); } From 15cdc69f310886a213c104595d83109744ca2f65 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 18:51:13 +0000 Subject: [PATCH 02/10] Added basic subscriptions --- src/command.c | 36 ++++++++++++++++++++++++++++++++++++ src/jabber.c | 27 +++++++++++++++++++++++++++ src/jabber.h | 1 + 3 files changed, 64 insertions(+) diff --git a/src/command.c b/src/command.c index e9f40409..7892e78a 100644 --- a/src/command.c +++ b/src/command.c @@ -82,6 +82,7 @@ static gboolean _cmd_prefs(const char * const inp, struct cmd_help_t help); static gboolean _cmd_who(const char * const inp, struct cmd_help_t help); static gboolean _cmd_connect(const char * const inp, struct cmd_help_t help); static gboolean _cmd_disconnect(const char * const inp, struct cmd_help_t help); +static gboolean _cmd_sub(const char * const inp, struct cmd_help_t help); static gboolean _cmd_msg(const char * const inp, struct cmd_help_t help); static gboolean _cmd_tiny(const char * const inp, struct cmd_help_t help); static gboolean _cmd_close(const char * const inp, struct cmd_help_t help); @@ -178,6 +179,16 @@ static struct cmd_t main_commands[] = "Example : /msg boothj5@gmail.com Hey, here's a message!", NULL } } }, + { "/sub", + _cmd_sub, + { "/sub user@host", "Subscribe to presence notifications of user.", + { "/sub user@host", + "------------------", + "Send a subscription request to the user to be informed of their presence.", + "", + "Example: /sub myfriend@jabber.org", + NULL } } }, + { "/tiny", _cmd_tiny, { "/tiny url", "Send url as tinyurl in current chat.", @@ -691,6 +702,31 @@ _cmd_connect(const char * const inp, struct cmd_help_t help) return result; } +static gboolean +_cmd_sub(const char * const inp, struct cmd_help_t help) +{ + gboolean result = FALSE; + jabber_conn_status_t conn_status = jabber_get_connection_status(); + + if (conn_status != JABBER_CONNECTED) { + cons_show("You are currently not connected."); + result = TRUE; + } else if (strlen(inp) < 6) { + cons_show("Usage: %s", help.usage); + result = TRUE; + } else { + char *user, *lower; + user = strndup(inp+5, strlen(inp)-5); + lower = g_utf8_strdown(user, -1); + + jabber_subscribe(lower); + + result = TRUE; + } + + return result; +} + static gboolean _cmd_disconnect(const char * const inp, struct cmd_help_t help) { diff --git a/src/jabber.c b/src/jabber.c index 4913618e..f3e3fa27 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -184,6 +184,19 @@ jabber_roster_request(void) xmpp_stanza_release(iq); } +void +jabber_subscribe(const char * const recipient) +{ + xmpp_stanza_t *presence; + + presence = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(presence, "presence"); + xmpp_stanza_set_type(presence, "subscribe"); + xmpp_stanza_set_attribute(presence, "to", recipient); + xmpp_send(jabber_conn.conn, presence); + xmpp_stanza_release(presence); +} + void jabber_update_presence(jabber_presence_t status, const char * const msg) { @@ -435,6 +448,20 @@ _presence_handler(xmpp_conn_t * const conn, char *short_from = strtok(from, "/"); char *type = xmpp_stanza_get_attribute(stanza, "type"); + if (type != NULL) { + if (strcmp(type, "subscribe") == 0) { + xmpp_stanza_t *presence; + + presence = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(presence, "presence"); + xmpp_stanza_set_type(presence, "subscribed"); + xmpp_stanza_set_attribute(presence, "to", short_from); + xmpp_send(jabber_conn.conn, presence); + xmpp_stanza_release(presence); + return 1; + } + } + char *show_str, *status_str; xmpp_stanza_t *show = xmpp_stanza_get_child_by_name(stanza, "show"); diff --git a/src/jabber.h b/src/jabber.h index d12d00b3..f1ca99e5 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -46,6 +46,7 @@ jabber_conn_status_t jabber_connect(const char * const user, void jabber_disconnect(void); void jabber_roster_request(void); void jabber_process_events(void); +void jabber_subscribe(const char * const recipient); void jabber_send(const char * const msg, const char * const recipient); void jabber_update_presence(jabber_presence_t status, const char * const msg); const char * jabber_get_jid(void); From d13794bf60747323c434ee8b25523bc12c2f540d Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 20:52:30 +0000 Subject: [PATCH 03/10] Load roster before sending presence --- src/command.c | 41 ++++++++++++----------- src/contact.c | 68 +++++++++++++++++++++++++++---------- src/contact.h | 8 +++-- src/contact_list.c | 10 +++--- src/contact_list.h | 5 +-- src/jabber.c | 83 +++++++++++++++++++++++----------------------- src/jabber.h | 1 - src/profanity.c | 32 ++---------------- src/profanity.h | 5 --- src/windows.c | 30 ++++++++--------- 10 files changed, 144 insertions(+), 139 deletions(-) diff --git a/src/command.c b/src/command.c index c9110e4b..f8c5b1e9 100644 --- a/src/command.c +++ b/src/command.c @@ -718,8 +718,9 @@ _cmd_sub(const char * const inp, struct cmd_help_t help) char *user, *lower; user = strndup(inp+5, strlen(inp)-5); lower = g_utf8_strdown(user, -1); - + jabber_subscribe(lower); + cons_show("Sent subscription request to %s.", user); result = TRUE; } @@ -824,16 +825,16 @@ _cmd_who(const char * const inp, struct cmd_help_t help) // get show strtok(inp_cpy, " "); - char *show = strtok(NULL, " "); + char *presence = strtok(NULL, " "); // bad arg - if ((show != NULL) - && (strcmp(show, "online") != 0) - && (strcmp(show, "offline") != 0) - && (strcmp(show, "away") != 0) - && (strcmp(show, "chat") != 0) - && (strcmp(show, "xa") != 0) - && (strcmp(show, "dnd") != 0)) { + if ((presence != NULL) + && (strcmp(presence, "online") != 0) + && (strcmp(presence, "offline") != 0) + && (strcmp(presence, "away") != 0) + && (strcmp(presence, "chat") != 0) + && (strcmp(presence, "xa") != 0) + && (strcmp(presence, "dnd") != 0)) { cons_show("Usage: %s", help.usage); // valid arg @@ -841,23 +842,23 @@ _cmd_who(const char * const inp, struct cmd_help_t help) GSList *list = get_contact_list(); // no arg, show all contacts - if (show == NULL) { + if (presence == NULL) { cons_show("All contacts:"); cons_show_contacts(list); // online, show all status that indicate online - } else if (strcmp("online", show) == 0) { - cons_show("Contacts (%s):", show); + } else if (strcmp("online", presence) == 0) { + cons_show("Contacts (%s):", presence); GSList *filtered = NULL; while (list != NULL) { PContact contact = list->data; - const char * const contact_show = (p_contact_show(contact)); - if ((strcmp(contact_show, "online") == 0) - || (strcmp(contact_show, "away") == 0) - || (strcmp(contact_show, "dnd") == 0) - || (strcmp(contact_show, "xa") == 0) - || (strcmp(contact_show, "chat") == 0)) { + const char * const contact_presence = (p_contact_presence(contact)); + if ((strcmp(contact_presence, "online") == 0) + || (strcmp(contact_presence, "away") == 0) + || (strcmp(contact_presence, "dnd") == 0) + || (strcmp(contact_presence, "xa") == 0) + || (strcmp(contact_presence, "chat") == 0)) { filtered = g_slist_append(filtered, contact); } list = g_slist_next(list); @@ -867,12 +868,12 @@ _cmd_who(const char * const inp, struct cmd_help_t help) // show specific status } else { - cons_show("Contacts (%s):", show); + cons_show("Contacts (%s):", presence); GSList *filtered = NULL; while (list != NULL) { PContact contact = list->data; - if (strcmp(p_contact_show(contact), show) == 0) { + if (strcmp(p_contact_presence(contact), presence) == 0) { filtered = g_slist_append(filtered, contact); } list = g_slist_next(list); diff --git a/src/contact.c b/src/contact.c index 12a2e500..d217f4c8 100644 --- a/src/contact.c +++ b/src/contact.c @@ -28,22 +28,31 @@ #include "contact.h" struct p_contact_t { + char *jid; char *name; - char *show; + char *presence; char *status; + char *subscription; }; PContact -p_contact_new(const char * const name, const char * const show, - const char * const status) +p_contact_new(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription) { PContact contact = malloc(sizeof(struct p_contact_t)); - contact->name = strdup(name); + contact->jid = strdup(jid); - if (show == NULL || (strcmp(show, "") == 0)) - contact->show = strdup("online"); + if (name != NULL) { + contact->name = strdup(name); + } else { + contact->name = NULL; + } + + if (presence == NULL || (strcmp(presence, "") == 0)) + contact->presence = strdup("online"); else - contact->show = strdup(show); + contact->presence = strdup(presence); if (status != NULL) contact->status = strdup(status); @@ -57,8 +66,15 @@ PContact p_contact_copy(PContact contact) { PContact copy = malloc(sizeof(struct p_contact_t)); - copy->name = strdup(contact->name); - copy->show = strdup(contact->show); + copy->jid = strdup(contact->jid); + + if (contact->name != NULL) { + copy->name = strdup(contact->name); + } else { + copy->name = NULL; + } + + copy->presence = strdup(contact->presence); if (contact->status != NULL) copy->status = strdup(contact->status); @@ -71,12 +87,21 @@ p_contact_copy(PContact contact) void p_contact_free(PContact contact) { - free(contact->name); - - if (contact->show != NULL) { - free(contact->show); - contact->show = NULL; + if (contact->jid != NULL) { + free(contact->jid); + contact->jid = NULL; } + + if (contact->name != NULL) { + free(contact->name); + contact->name = NULL; + } + + if (contact->presence != NULL) { + free(contact->presence); + contact->presence = NULL; + } + if (contact->status != NULL) { free(contact->status); contact->status = NULL; @@ -86,6 +111,12 @@ p_contact_free(PContact contact) contact = NULL; } +const char * +p_contact_jid(const PContact contact) +{ + return contact->jid; +} + const char * p_contact_name(const PContact contact) { @@ -93,9 +124,9 @@ p_contact_name(const PContact contact) } const char * -p_contact_show(const PContact contact) +p_contact_presence(const PContact contact) { - return contact->show; + return contact->presence; } const char * @@ -107,9 +138,10 @@ p_contact_status(const PContact contact) int p_contacts_equal_deep(const PContact c1, const PContact c2) { + int jid_eq = (g_strcmp0(c1->jid, c2->jid) == 0); int name_eq = (g_strcmp0(c1->name, c2->name) == 0); - int show_eq = (g_strcmp0(c1->show, c2->show) == 0); + int presence_eq = (g_strcmp0(c1->presence, c2->presence) == 0); int status_eq = (g_strcmp0(c1->status, c2->status) == 0); - return (name_eq && show_eq && status_eq); + return (jid_eq && name_eq && presence_eq && status_eq); } diff --git a/src/contact.h b/src/contact.h index 8f778ca9..45c9780f 100644 --- a/src/contact.h +++ b/src/contact.h @@ -25,12 +25,14 @@ typedef struct p_contact_t *PContact; -PContact p_contact_new(const char * const name, const char * const show, - const char * const status); +PContact p_contact_new(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription); PContact p_contact_copy(PContact contact); void p_contact_free(PContact contact); +const char * p_contact_jid(PContact contact); const char * p_contact_name(PContact contact); -const char * p_contact_show(PContact contact); +const char * p_contact_presence(PContact contact); const char * p_contact_status(PContact contact); int p_contacts_equal_deep(const PContact c1, const PContact c2); diff --git a/src/contact_list.c b/src/contact_list.c index e266e25e..81611818 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -30,7 +30,7 @@ static PAutocomplete ac; void contact_list_init(void) { - ac = p_obj_autocomplete_new((PStrFunc)p_contact_name, + ac = p_obj_autocomplete_new((PStrFunc)p_contact_jid, (PCopyFunc)p_contact_copy, (PEqualDeepFunc)p_contacts_equal_deep, (GDestroyNotify)p_contact_free); @@ -55,10 +55,12 @@ contact_list_remove(const char * const name) } gboolean -contact_list_add(const char * const name, const char * const show, - const char * const status) +contact_list_add(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription) { - return p_autocomplete_add(ac, p_contact_new(name, show, status)); + return p_autocomplete_add(ac, p_contact_new(jid, name, presence, status, + subscription)); } GSList * diff --git a/src/contact_list.h b/src/contact_list.h index bc239111..e76a2ec9 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -30,8 +30,9 @@ void contact_list_init(void); void contact_list_clear(void); void contact_list_reset_search_attempts(void); -gboolean contact_list_add(const char * const name, const char * const show, - const char * const status); +gboolean contact_list_add(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription); gboolean contact_list_remove(const char * const name); GSList * get_contact_list(void); char * contact_list_find_contact(char *search_str); diff --git a/src/jabber.c b/src/jabber.c index f3e3fa27..f9c4f0c7 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -26,6 +26,7 @@ #include #include "common.h" +#include "contact_list.h" #include "jabber.h" #include "log.h" #include "preferences.h" @@ -49,6 +50,8 @@ static void _xmpp_file_logger(void * const userdata, const char * const msg); static xmpp_log_t * _xmpp_get_file_logger(); +static void _jabber_roster_request(void); + // XMPP event handlers static void _connection_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, const int error, @@ -164,26 +167,6 @@ jabber_send(const char * const msg, const char * const recipient) free(coded_msg3); } -void -jabber_roster_request(void) -{ - xmpp_stanza_t *iq, *query; - - iq = xmpp_stanza_new(jabber_conn.ctx); - xmpp_stanza_set_name(iq, "iq"); - xmpp_stanza_set_type(iq, "get"); - xmpp_stanza_set_id(iq, "roster"); - - query = xmpp_stanza_new(jabber_conn.ctx); - xmpp_stanza_set_name(query, "query"); - xmpp_stanza_set_ns(query, XMPP_NS_ROSTER); - - xmpp_stanza_add_child(iq, query); - xmpp_stanza_release(query); - xmpp_send(jabber_conn.conn, iq); - xmpp_stanza_release(iq); -} - void jabber_subscribe(const char * const recipient) { @@ -192,7 +175,7 @@ jabber_subscribe(const char * const recipient) presence = xmpp_stanza_new(jabber_conn.ctx); xmpp_stanza_set_name(presence, "presence"); xmpp_stanza_set_type(presence, "subscribe"); - xmpp_stanza_set_attribute(presence, "to", recipient); + xmpp_stanza_set_attribute(presence, "to", recipient); xmpp_send(jabber_conn.conn, presence); xmpp_stanza_release(presence); } @@ -266,6 +249,26 @@ jabber_free_resources(void) xmpp_shutdown(); } +static void +_jabber_roster_request(void) +{ + xmpp_stanza_t *iq, *query; + + iq = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(iq, "iq"); + xmpp_stanza_set_type(iq, "get"); + xmpp_stanza_set_id(iq, "roster"); + + query = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(query, "query"); + xmpp_stanza_set_ns(query, XMPP_NS_ROSTER); + + xmpp_stanza_add_child(iq, query); + xmpp_stanza_release(query); + xmpp_send(jabber_conn.conn, iq); + xmpp_stanza_release(iq); +} + static int _message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) @@ -333,20 +336,14 @@ _connection_handler(xmpp_conn_t * const conn, const char *jid = xmpp_conn_get_jid(conn); prof_handle_login_success(jid); - xmpp_stanza_t* pres; xmpp_handler_add(conn, _message_handler, NULL, "message", NULL, ctx); xmpp_handler_add(conn, _presence_handler, NULL, "presence", NULL, ctx); xmpp_id_handler_add(conn, _roster_handler, "roster", ctx); xmpp_timed_handler_add(conn, _ping_timed_handler, PING_INTERVAL, ctx); - pres = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(pres, "presence"); - xmpp_send(conn, pres); - xmpp_stanza_release(pres); - + _jabber_roster_request(); jabber_conn.conn_status = JABBER_CONNECTED; jabber_conn.presence = PRESENCE_ONLINE; - jabber_roster_request(); } else { // received close stream response from server after disconnect @@ -375,6 +372,7 @@ static int _roster_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { + xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; xmpp_stanza_t *query, *item; char *type = xmpp_stanza_get_type(stanza); @@ -382,27 +380,29 @@ _roster_handler(xmpp_conn_t * const conn, log_error("Roster query failed"); else { query = xmpp_stanza_get_child_by_name(stanza, "query"); - GSList *roster = NULL; item = xmpp_stanza_get_children(query); while (item != NULL) { - const char *name = xmpp_stanza_get_attribute(item, "name"); const char *jid = xmpp_stanza_get_attribute(item, "jid"); + const char *name = xmpp_stanza_get_attribute(item, "name"); + const char *sub = xmpp_stanza_get_attribute(item, "subscription"); - jabber_roster_entry *entry = malloc(sizeof(jabber_roster_entry)); + if (sub != NULL) { + if (strcmp(sub, "none") != 0) { - if (name != NULL) { - entry->name = strdup(name); - } else { - entry->name = NULL; + contact_list_add(jid, name, "offline", NULL, sub); + + } } - entry->jid = strdup(jid); - - roster = g_slist_append(roster, entry); item = xmpp_stanza_get_next(item); } - - prof_handle_roster(roster); +/* + xmpp_stanza_t* pres; + pres = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(pres, "presence"); + xmpp_send(conn, pres); + xmpp_stanza_release(pres); +*/ } return 1; @@ -449,13 +449,14 @@ _presence_handler(xmpp_conn_t * const conn, char *type = xmpp_stanza_get_attribute(stanza, "type"); if (type != NULL) { + // allow all subscription requests for now if (strcmp(type, "subscribe") == 0) { xmpp_stanza_t *presence; presence = xmpp_stanza_new(jabber_conn.ctx); xmpp_stanza_set_name(presence, "presence"); xmpp_stanza_set_type(presence, "subscribed"); - xmpp_stanza_set_attribute(presence, "to", short_from); + xmpp_stanza_set_attribute(presence, "to", short_from); xmpp_send(jabber_conn.conn, presence); xmpp_stanza_release(presence); return 1; diff --git a/src/jabber.h b/src/jabber.h index f1ca99e5..726fb1a5 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -44,7 +44,6 @@ void jabber_init(const int disable_tls); jabber_conn_status_t jabber_connect(const char * const user, const char * const passwd); void jabber_disconnect(void); -void jabber_roster_request(void); void jabber_process_events(void); void jabber_subscribe(const char * const recipient); void jabber_send(const char * const msg, const char * const recipient); diff --git a/src/profanity.c b/src/profanity.c index 71c11be0..2953c4ba 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -41,7 +41,6 @@ static log_level_t _get_log_level(char *log_level); static gboolean _process_input(char *inp); static void _create_config_directory(); -static void _free_roster_entry(jabber_roster_entry *entry); static void _init(const int disable_tls, char *log_level); static void _shutdown(void); @@ -166,7 +165,7 @@ prof_handle_failed_login(void) void prof_handle_contact_online(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, show, status); + gboolean result = contact_list_add(contact, NULL, show, status, NULL); if (result) { win_contact_online(contact, show, status); } @@ -176,30 +175,13 @@ prof_handle_contact_online(char *contact, char *show, char *status) void prof_handle_contact_offline(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, "offline", status); + gboolean result = contact_list_add(contact, NULL, "offline", status, NULL); if (result) { win_contact_offline(contact, show, status); } win_page_off(); } -void -prof_handle_roster(GSList *roster) -{ - while (roster != NULL) { - jabber_roster_entry *entry = roster->data; - - // if contact not in contact list add them as offline - if (contact_list_find_contact(entry->jid) == NULL) { - contact_list_add(entry->jid, "offline", NULL); - } - - roster = g_slist_next(roster); - } - - g_slist_free_full(roster, (GDestroyNotify)_free_roster_entry); -} - static void _create_config_directory(void) { @@ -209,16 +191,6 @@ _create_config_directory(void) g_string_free(dir, TRUE); } -static void -_free_roster_entry(jabber_roster_entry *entry) -{ - if (entry->name != NULL) { - free(entry->name); - entry->name = NULL; - } - free(entry->jid); -} - static log_level_t _get_log_level(char *log_level) { diff --git a/src/profanity.h b/src/profanity.h index 430148e2..a67fb2df 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -23,11 +23,6 @@ #ifndef PROFANITY_H #define PROFANITY_H -typedef struct roster_entry_t { - char *name; - char *jid; -} jabber_roster_entry; - void prof_run(const int disable_tls, char *log_level); void prof_handle_login_success(const char *jid); diff --git a/src/windows.c b/src/windows.c index f1c8f0fe..276d1eb8 100644 --- a/src/windows.c +++ b/src/windows.c @@ -427,8 +427,8 @@ win_show_outgoing_msg(const char * const from, const char * const to, } if (contact != NULL) { - if (strcmp(p_contact_show(contact), "offline") == 0) { - const char const *show = p_contact_show(contact); + if (strcmp(p_contact_presence(contact), "offline") == 0) { + const char const *show = p_contact_presence(contact); const char const *status = p_contact_status(contact); _show_status_string(win, to, show, status, "--", "offline"); } @@ -703,41 +703,41 @@ cons_show_contacts(GSList *list) while(curr) { PContact contact = curr->data; - const char *show = p_contact_show(contact); + const char *presence = p_contact_presence(contact); _win_show_time(_cons_win); - if (strcmp(show, "online") == 0) { + if (strcmp(presence, "online") == 0) { wattron(_cons_win, COLOUR_ONLINE); - } else if (strcmp(show, "away") == 0) { + } else if (strcmp(presence, "away") == 0) { wattron(_cons_win, COLOUR_AWAY); - } else if (strcmp(show, "chat") == 0) { + } else if (strcmp(presence, "chat") == 0) { wattron(_cons_win, COLOUR_CHAT); - } else if (strcmp(show, "dnd") == 0) { + } else if (strcmp(presence, "dnd") == 0) { wattron(_cons_win, COLOUR_DND); - } else if (strcmp(show, "xa") == 0) { + } else if (strcmp(presence, "xa") == 0) { wattron(_cons_win, COLOUR_XA); } else { wattron(_cons_win, COLOUR_OFFLINE); } - wprintw(_cons_win, "%s", p_contact_name(contact)); - wprintw(_cons_win, " is %s", show); + wprintw(_cons_win, "%s", p_contact_jid(contact)); + wprintw(_cons_win, " is %s", presence); if (p_contact_status(contact)) wprintw(_cons_win, ", \"%s\"", p_contact_status(contact)); wprintw(_cons_win, "\n"); - if (strcmp(show, "online") == 0) { + if (strcmp(presence, "online") == 0) { wattroff(_cons_win, COLOUR_ONLINE); - } else if (strcmp(show, "away") == 0) { + } else if (strcmp(presence, "away") == 0) { wattroff(_cons_win, COLOUR_AWAY); - } else if (strcmp(show, "chat") == 0) { + } else if (strcmp(presence, "chat") == 0) { wattroff(_cons_win, COLOUR_CHAT); - } else if (strcmp(show, "dnd") == 0) { + } else if (strcmp(presence, "dnd") == 0) { wattroff(_cons_win, COLOUR_DND); - } else if (strcmp(show, "xa") == 0) { + } else if (strcmp(presence, "xa") == 0) { wattroff(_cons_win, COLOUR_XA); } else { wattroff(_cons_win, COLOUR_OFFLINE); From 4e0a631fee54bd5e4fa37127ecdec84a62a72c3f Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 21:16:22 +0000 Subject: [PATCH 04/10] Subscription management --- src/contact.c | 24 ++++++++++++++++- src/contact.h | 1 + src/jabber.c | 8 +----- src/windows.c | 74 ++++++++++++++++++++++++++++++--------------------- 4 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/contact.c b/src/contact.c index d217f4c8..2d58308a 100644 --- a/src/contact.c +++ b/src/contact.c @@ -59,6 +59,11 @@ p_contact_new(const char * const jid, const char * const name, else contact->status = NULL; + if (subscription != NULL) + contact->subscription = strdup(subscription); + else + contact->subscription = NULL; + return contact; } @@ -81,6 +86,11 @@ p_contact_copy(PContact contact) else copy->status = NULL; + if (contact->subscription != NULL) + copy->subscription = strdup(contact->subscription); + else + copy->subscription = NULL; + return copy; } @@ -107,6 +117,11 @@ p_contact_free(PContact contact) contact->status = NULL; } + if (contact->subscription != NULL) { + free(contact->subscription); + contact->subscription = NULL; + } + free(contact); contact = NULL; } @@ -135,6 +150,12 @@ p_contact_status(const PContact contact) return contact->status; } +const char * +p_contact_subscription(const PContact contact) +{ + return contact->subscription; +} + int p_contacts_equal_deep(const PContact c1, const PContact c2) { @@ -142,6 +163,7 @@ p_contacts_equal_deep(const PContact c1, const PContact c2) int name_eq = (g_strcmp0(c1->name, c2->name) == 0); int presence_eq = (g_strcmp0(c1->presence, c2->presence) == 0); int status_eq = (g_strcmp0(c1->status, c2->status) == 0); + int subscription_eq = (g_strcmp0(c1->subscription, c2->subscription) == 0); - return (jid_eq && name_eq && presence_eq && status_eq); + return (jid_eq && name_eq && presence_eq && status_eq && subscription_eq); } diff --git a/src/contact.h b/src/contact.h index 45c9780f..194d867b 100644 --- a/src/contact.h +++ b/src/contact.h @@ -34,6 +34,7 @@ const char * p_contact_jid(PContact contact); const char * p_contact_name(PContact contact); const char * p_contact_presence(PContact contact); const char * p_contact_status(PContact contact); +const char * p_contact_subscription(const PContact contact); int p_contacts_equal_deep(const PContact c1, const PContact c2); #endif diff --git a/src/jabber.c b/src/jabber.c index f9c4f0c7..f1626869 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -386,14 +386,8 @@ _roster_handler(xmpp_conn_t * const conn, const char *jid = xmpp_stanza_get_attribute(item, "jid"); const char *name = xmpp_stanza_get_attribute(item, "name"); const char *sub = xmpp_stanza_get_attribute(item, "subscription"); + contact_list_add(jid, name, "offline", NULL, sub); - if (sub != NULL) { - if (strcmp(sub, "none") != 0) { - - contact_list_add(jid, name, "offline", NULL, sub); - - } - } item = xmpp_stanza_get_next(item); } /* diff --git a/src/windows.c b/src/windows.c index 276d1eb8..c7e49020 100644 --- a/src/windows.c +++ b/src/windows.c @@ -703,44 +703,56 @@ cons_show_contacts(GSList *list) while(curr) { PContact contact = curr->data; + const char *jid = p_contact_jid(contact); + const char *name = p_contact_name(contact); const char *presence = p_contact_presence(contact); + const char *status = p_contact_status(contact); + const char *sub = p_contact_subscription(contact); - _win_show_time(_cons_win); + if (strcmp(sub, "none") != 0) { + _win_show_time(_cons_win); - if (strcmp(presence, "online") == 0) { - wattron(_cons_win, COLOUR_ONLINE); - } else if (strcmp(presence, "away") == 0) { - wattron(_cons_win, COLOUR_AWAY); - } else if (strcmp(presence, "chat") == 0) { - wattron(_cons_win, COLOUR_CHAT); - } else if (strcmp(presence, "dnd") == 0) { - wattron(_cons_win, COLOUR_DND); - } else if (strcmp(presence, "xa") == 0) { - wattron(_cons_win, COLOUR_XA); - } else { - wattron(_cons_win, COLOUR_OFFLINE); - } + if (strcmp(presence, "online") == 0) { + wattron(_cons_win, COLOUR_ONLINE); + } else if (strcmp(presence, "away") == 0) { + wattron(_cons_win, COLOUR_AWAY); + } else if (strcmp(presence, "chat") == 0) { + wattron(_cons_win, COLOUR_CHAT); + } else if (strcmp(presence, "dnd") == 0) { + wattron(_cons_win, COLOUR_DND); + } else if (strcmp(presence, "xa") == 0) { + wattron(_cons_win, COLOUR_XA); + } else { + wattron(_cons_win, COLOUR_OFFLINE); + } - wprintw(_cons_win, "%s", p_contact_jid(contact)); - wprintw(_cons_win, " is %s", presence); + wprintw(_cons_win, "%s", jid); - if (p_contact_status(contact)) - wprintw(_cons_win, ", \"%s\"", p_contact_status(contact)); + if (name != NULL) { + wprintw(_cons_win, " (%s)", name); + } - wprintw(_cons_win, "\n"); + wprintw(_cons_win, " is %s", presence); - if (strcmp(presence, "online") == 0) { - wattroff(_cons_win, COLOUR_ONLINE); - } else if (strcmp(presence, "away") == 0) { - wattroff(_cons_win, COLOUR_AWAY); - } else if (strcmp(presence, "chat") == 0) { - wattroff(_cons_win, COLOUR_CHAT); - } else if (strcmp(presence, "dnd") == 0) { - wattroff(_cons_win, COLOUR_DND); - } else if (strcmp(presence, "xa") == 0) { - wattroff(_cons_win, COLOUR_XA); - } else { - wattroff(_cons_win, COLOUR_OFFLINE); + if (status != NULL) { + wprintw(_cons_win, ", \"%s\"", p_contact_status(contact)); + } + + wprintw(_cons_win, "\n"); + + if (strcmp(presence, "online") == 0) { + wattroff(_cons_win, COLOUR_ONLINE); + } else if (strcmp(presence, "away") == 0) { + wattroff(_cons_win, COLOUR_AWAY); + } else if (strcmp(presence, "chat") == 0) { + wattroff(_cons_win, COLOUR_CHAT); + } else if (strcmp(presence, "dnd") == 0) { + wattroff(_cons_win, COLOUR_DND); + } else if (strcmp(presence, "xa") == 0) { + wattroff(_cons_win, COLOUR_XA); + } else { + wattroff(_cons_win, COLOUR_OFFLINE); + } } curr = g_slist_next(curr); From bc5d8418ad20386b1a270527dce24b7a4b7119ff Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 21:32:26 +0000 Subject: [PATCH 05/10] Send presence after roster recieved --- src/jabber.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/jabber.c b/src/jabber.c index f1626869..af83c037 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -390,13 +390,11 @@ _roster_handler(xmpp_conn_t * const conn, item = xmpp_stanza_get_next(item); } -/* xmpp_stanza_t* pres; pres = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pres, "presence"); xmpp_send(conn, pres); xmpp_stanza_release(pres); -*/ } return 1; From 34238ad6a49917847bbf51f8a02d898f74a0aa2d Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 23:27:56 +0000 Subject: [PATCH 06/10] Handle presence after roster request --- src/contact_list.c | 109 ++++++++++++++++++++++++++++++++++----------- src/contact_list.h | 3 +- src/profanity.c | 22 +++++---- 3 files changed, 99 insertions(+), 35 deletions(-) diff --git a/src/contact_list.c b/src/contact_list.c index 81611818..427d0722 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -22,24 +22,29 @@ #include +#include + #include "contact.h" #include "prof_autocomplete.h" static PAutocomplete ac; +static GHashTable *contacts; + +static gboolean _key_equals(void *key1, void *key2); void contact_list_init(void) { - ac = p_obj_autocomplete_new((PStrFunc)p_contact_jid, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); + ac = p_autocomplete_new(); + contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free, + (GDestroyNotify)p_contact_free); } void contact_list_clear(void) { p_autocomplete_clear(ac); + g_hash_table_remove_all(contacts); } void @@ -48,25 +53,80 @@ contact_list_reset_search_attempts(void) p_autocomplete_reset(ac); } -gboolean -contact_list_remove(const char * const name) -{ - return p_autocomplete_remove(ac, name); -} - -gboolean +void contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription) { - return p_autocomplete_add(ac, p_contact_new(jid, name, presence, status, - subscription)); + PContact contact = g_hash_table_lookup(contacts, jid); + + // contact not yet in list + if (contact == NULL) { + contact = p_contact_new(jid, name, presence, status, subscription); + g_hash_table_insert(contacts, strdup(jid), contact); + + // contact already exists, update non NULL arguments + } else { + char *new_name = NULL; + if (name != NULL) { + new_name = strdup(name); + } else { + if (p_contact_name(contact) != NULL) { + new_name = strdup(p_contact_name(contact)); + } + } + + char *new_presence = NULL; + if (presence != NULL) { + new_presence = strdup(presence); + } else { + if (p_contact_presence(contact) != NULL) { + new_presence = strdup(p_contact_presence(contact)); + } + } + + char *new_status = NULL; + if (status != NULL) { + new_status = strdup(status); + } else { + if (p_contact_status(contact) != NULL) { + new_status = strdup(p_contact_status(contact)); + } + } + + char *new_subscription = NULL; + if (subscription != NULL) { + new_subscription = strdup(subscription); + } else { + if (p_contact_subscription(contact) != NULL) { + new_subscription = strdup(p_contact_subscription(contact)); + } + } + + PContact new_contact = p_contact_new(jid, new_name, new_presence, + new_status, new_subscription); + + g_hash_table_replace(contacts, strdup(jid), new_contact); + } + + p_autocomplete_add(ac, strdup(jid)); } GSList * get_contact_list(void) { - return p_autocomplete_get_list(ac); + GSList *result = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, contacts); + while (g_hash_table_iter_next(&iter, &key, &value)) { + result = g_slist_append(result, value); + } + + // resturn all contact structs + return result; } char * @@ -78,15 +138,14 @@ contact_list_find_contact(char *search_str) PContact contact_list_get_contact(const char const *jid) { - GSList *contacts = get_contact_list(); - - while (contacts != NULL) { - PContact contact = contacts->data; - if (strcmp(p_contact_name(contact), jid) == 0) { - return contact; - } - contacts = g_slist_next(contacts); - } - - return NULL; + return g_hash_table_lookup(contacts, jid); +} + +static +gboolean _key_equals(void *key1, void *key2) +{ + gchar *str1 = (gchar *) key1; + gchar *str2 = (gchar *) key2; + + return (g_strcmp0(str1, str2) == 0); } diff --git a/src/contact_list.h b/src/contact_list.h index e76a2ec9..ac9ab6cd 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -30,10 +30,9 @@ void contact_list_init(void); void contact_list_clear(void); void contact_list_reset_search_attempts(void); -gboolean contact_list_add(const char * const jid, const char * const name, +void contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription); -gboolean contact_list_remove(const char * const name); GSList * get_contact_list(void); char * contact_list_find_contact(char *search_str); PContact contact_list_get_contact(const char const *jid); diff --git a/src/profanity.c b/src/profanity.c index 2953c4ba..dd6aae6e 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -165,21 +165,27 @@ prof_handle_failed_login(void) void prof_handle_contact_online(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, NULL, show, status, NULL); - if (result) { - win_contact_online(contact, show, status); + contact_list_add(contact, NULL, show, status, NULL); + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_online(contact, show, status); + win_page_off(); + } } - win_page_off(); } void prof_handle_contact_offline(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, NULL, "offline", status, NULL); - if (result) { - win_contact_offline(contact, show, status); + contact_list_add(contact, NULL, "offline", status, NULL); + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_offline(contact, show, status); + win_page_off(); + } } - win_page_off(); } static void From a85ba5e2cb07736bd8cc4e8caf264795f8f18eb3 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 23:38:10 +0000 Subject: [PATCH 07/10] Simplified autocompleter --- src/prof_autocomplete.c | 76 +++++++---------------------------------- 1 file changed, 12 insertions(+), 64 deletions(-) diff --git a/src/prof_autocomplete.c b/src/prof_autocomplete.c index 79d44498..b41c5368 100644 --- a/src/prof_autocomplete.c +++ b/src/prof_autocomplete.c @@ -29,59 +29,25 @@ struct p_autocomplete_t { GSList *items; GSList *last_found; gchar *search_str; - PStrFunc str_func; - PCopyFunc copy_func; - PEqualDeepFunc equal_deep_func; - GDestroyNotify free_func; }; static gchar * _search_from(PAutocomplete ac, GSList *curr); -static const char *_str_func_default(const char *orig); -static const char *_copy_func_default(const char *orig); -static int _deep_equals_func_default(const char *o1, const char *o2); PAutocomplete p_autocomplete_new(void) -{ - return p_obj_autocomplete_new(NULL, NULL, NULL, NULL); -} - -PAutocomplete -p_obj_autocomplete_new(PStrFunc str_func, PCopyFunc copy_func, - PEqualDeepFunc equal_deep_func, GDestroyNotify free_func) { PAutocomplete new = malloc(sizeof(struct p_autocomplete_t)); new->items = NULL; new->last_found = NULL; new->search_str = NULL; - if (str_func) - new->str_func = str_func; - else - new->str_func = (PStrFunc)_str_func_default; - - if (copy_func) - new->copy_func = copy_func; - else - new->copy_func = (PCopyFunc)_copy_func_default; - - if (free_func) - new->free_func = free_func; - else - new->free_func = (GDestroyNotify)free; - - if (equal_deep_func) - new->equal_deep_func = equal_deep_func; - else - new->equal_deep_func = (PEqualDeepFunc)_deep_equals_func_default; - return new; } void p_autocomplete_clear(PAutocomplete ac) { - g_slist_free_full(ac->items, ac->free_func); + g_slist_free_full(ac->items, free); ac->items = NULL; p_autocomplete_reset(ac); @@ -109,16 +75,16 @@ p_autocomplete_add(PAutocomplete ac, void *item) while(curr) { // insert - if (g_strcmp0(ac->str_func(curr->data), ac->str_func(item)) > 0) { + if (g_strcmp0(curr->data, item) > 0) { ac->items = g_slist_insert_before(ac->items, curr, item); return TRUE; // update - } else if (g_strcmp0(ac->str_func(curr->data), ac->str_func(item)) == 0) { + } else if (g_strcmp0(curr->data, item) == 0) { // only update if data different - if (!ac->equal_deep_func(curr->data, item)) { - ac->free_func(curr->data); + if (strcmp(curr->data, item) != 0) { + free(curr->data); curr->data = item; return TRUE; } else { @@ -141,7 +107,7 @@ p_autocomplete_remove(PAutocomplete ac, const char * const item) { // reset last found if it points to the item to be removed if (ac->last_found != NULL) - if (g_strcmp0(ac->str_func(ac->last_found->data), item) == 0) + if (g_strcmp0(ac->last_found->data, item) == 0) ac->last_found = NULL; if (!ac->items) { @@ -150,10 +116,10 @@ p_autocomplete_remove(PAutocomplete ac, const char * const item) GSList *curr = ac->items; while(curr) { - if (g_strcmp0(ac->str_func(curr->data), item) == 0) { + if (g_strcmp0(curr->data, item) == 0) { void *current_item = curr->data; ac->items = g_slist_remove(ac->items, curr->data); - ac->free_func(current_item); + free(current_item); return TRUE; } @@ -172,7 +138,7 @@ p_autocomplete_get_list(PAutocomplete ac) GSList *curr = ac->items; while(curr) { - copy = g_slist_append(copy, ac->copy_func(curr->data)); + copy = g_slist_append(copy, strdup(curr->data)); curr = g_slist_next(curr); } @@ -221,17 +187,17 @@ _search_from(PAutocomplete ac, GSList *curr) while(curr) { // match found - if (strncmp(ac->str_func(curr->data), + if (strncmp(curr->data, ac->search_str, strlen(ac->search_str)) == 0) { gchar *result = - (gchar *) malloc((strlen(ac->str_func(curr->data)) + 1) * sizeof(gchar)); + (gchar *) malloc((strlen(curr->data) + 1) * sizeof(gchar)); // set pointer to last found ac->last_found = curr; // return the string, must be free'd by caller - strcpy(result, ac->str_func(curr->data)); + strcpy(result, curr->data); return result; } @@ -240,21 +206,3 @@ _search_from(PAutocomplete ac, GSList *curr) return NULL; } - -static const char * -_str_func_default(const char *orig) -{ - return orig; -} - -static const char * -_copy_func_default(const char *orig) -{ - return strdup(orig); -} - -static int -_deep_equals_func_default(const char *o1, const char *o2) -{ - return (strcmp(o1, o2) == 0); -} From dbb744532482baab8e012af500dbeda29600d2e1 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 29 Oct 2012 01:27:37 +0000 Subject: [PATCH 08/10] Fixed offline bug --- src/jabber.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/jabber.c b/src/jabber.c index af83c037..e2e146e8 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -439,41 +439,28 @@ _presence_handler(xmpp_conn_t * const conn, char *from = xmpp_stanza_get_attribute(stanza, "from"); char *short_from = strtok(from, "/"); char *type = xmpp_stanza_get_attribute(stanza, "type"); - - if (type != NULL) { - // allow all subscription requests for now - if (strcmp(type, "subscribe") == 0) { - xmpp_stanza_t *presence; - - presence = xmpp_stanza_new(jabber_conn.ctx); - xmpp_stanza_set_name(presence, "presence"); - xmpp_stanza_set_type(presence, "subscribed"); - xmpp_stanza_set_attribute(presence, "to", short_from); - xmpp_send(jabber_conn.conn, presence); - xmpp_stanza_release(presence); - return 1; - } - } - char *show_str, *status_str; - xmpp_stanza_t *show = xmpp_stanza_get_child_by_name(stanza, "show"); - if (show != NULL) - show_str = xmpp_stanza_get_text(show); - else - show_str = NULL; - xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, "status"); if (status != NULL) status_str = xmpp_stanza_get_text(status); else status_str = NULL; - if (strcmp(short_jid, short_from) !=0) { - if (type == NULL) { + if ((type != NULL) && (strcmp(type, "unavailable") == 0)) { + if (strcmp(short_jid, short_from) !=0) { + prof_handle_contact_offline(short_from, "offline", status_str); + } + } else { + + xmpp_stanza_t *show = xmpp_stanza_get_child_by_name(stanza, "show"); + if (show != NULL) + show_str = xmpp_stanza_get_text(show); + else + show_str = "online"; + + if (strcmp(short_jid, short_from) !=0) { prof_handle_contact_online(short_from, show_str, status_str); - } else { - prof_handle_contact_offline(short_from, show_str, status_str); } } From a0eda4207cbc25329754944da2dedf9e19fa0150 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 29 Oct 2012 21:44:33 +0000 Subject: [PATCH 09/10] Split contact add and update presence --- src/contact.c | 30 ++++++++++++++++++++ src/contact.h | 2 ++ src/contact_list.c | 70 ++++++++++++++++++---------------------------- src/contact_list.h | 2 ++ src/profanity.c | 30 ++++++++++++-------- 5 files changed, 79 insertions(+), 55 deletions(-) diff --git a/src/contact.c b/src/contact.c index 2d58308a..3b0d1944 100644 --- a/src/contact.c +++ b/src/contact.c @@ -156,6 +156,36 @@ p_contact_subscription(const PContact contact) return contact->subscription; } +void +p_contact_set_presence(const PContact contact, const char * const presence) +{ + if (contact->presence != NULL) { + free(contact->presence); + contact->presence = NULL; + } + + if (presence == NULL) { + contact->presence = NULL; + } else { + contact->presence = strdup(presence); + } +} + +void +p_contact_set_status(const PContact contact, const char * const status) +{ + if (contact->status != NULL) { + free(contact->status); + contact->status = NULL; + } + + if (status == NULL) { + contact->status = NULL; + } else { + contact->status = strdup(status); + } +} + int p_contacts_equal_deep(const PContact c1, const PContact c2) { diff --git a/src/contact.h b/src/contact.h index 194d867b..a4f487e8 100644 --- a/src/contact.h +++ b/src/contact.h @@ -35,6 +35,8 @@ const char * p_contact_name(PContact contact); const char * p_contact_presence(PContact contact); const char * p_contact_status(PContact contact); const char * p_contact_subscription(const PContact contact); +void p_contact_set_presence(const PContact contact, const char * const presence); +void p_contact_set_status(const PContact contact, const char * const status); int p_contacts_equal_deep(const PContact c1, const PContact c2); #endif diff --git a/src/contact_list.c b/src/contact_list.c index 427d0722..3f8ff2ee 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -25,6 +25,7 @@ #include #include "contact.h" +#include "log.h" #include "prof_autocomplete.h" static PAutocomplete ac; @@ -60,58 +61,41 @@ contact_list_add(const char * const jid, const char * const name, { PContact contact = g_hash_table_lookup(contacts, jid); - // contact not yet in list if (contact == NULL) { contact = p_contact_new(jid, name, presence, status, subscription); g_hash_table_insert(contacts, strdup(jid), contact); - - // contact already exists, update non NULL arguments } else { - char *new_name = NULL; - if (name != NULL) { - new_name = strdup(name); - } else { - if (p_contact_name(contact) != NULL) { - new_name = strdup(p_contact_name(contact)); - } - } - - char *new_presence = NULL; - if (presence != NULL) { - new_presence = strdup(presence); - } else { - if (p_contact_presence(contact) != NULL) { - new_presence = strdup(p_contact_presence(contact)); - } - } - - char *new_status = NULL; - if (status != NULL) { - new_status = strdup(status); - } else { - if (p_contact_status(contact) != NULL) { - new_status = strdup(p_contact_status(contact)); - } - } - - char *new_subscription = NULL; - if (subscription != NULL) { - new_subscription = strdup(subscription); - } else { - if (p_contact_subscription(contact) != NULL) { - new_subscription = strdup(p_contact_subscription(contact)); - } - } - - PContact new_contact = p_contact_new(jid, new_name, new_presence, - new_status, new_subscription); - - g_hash_table_replace(contacts, strdup(jid), new_contact); + log_warning("Duplicate roster entry: %s", jid); } p_autocomplete_add(ac, strdup(jid)); } +gboolean +contact_list_update_contact(const char * const jid, const char * const presence, + const char * const status) +{ + gboolean changed = FALSE; + PContact contact = g_hash_table_lookup(contacts, jid); + + if (contact == NULL) { + log_warning("Contact not in list: %s", jid); + return FALSE; + } + + if (g_strcmp0(p_contact_presence(contact), presence) != 0) { + p_contact_set_presence(contact, presence); + changed = TRUE; + } + + if (g_strcmp0(p_contact_status(contact), status) != 0) { + p_contact_set_status(contact, status); + changed = TRUE; + } + + return changed; +} + GSList * get_contact_list(void) { diff --git a/src/contact_list.h b/src/contact_list.h index ac9ab6cd..9f6bbe4c 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -33,6 +33,8 @@ void contact_list_reset_search_attempts(void); void contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription); +gboolean contact_list_update_contact(const char * const jid, const char * const presence, + const char * const status); GSList * get_contact_list(void); char * contact_list_find_contact(char *search_str); PContact contact_list_get_contact(const char const *jid); diff --git a/src/profanity.c b/src/profanity.c index dd6aae6e..e4888e97 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -165,12 +165,15 @@ prof_handle_failed_login(void) void prof_handle_contact_online(char *contact, char *show, char *status) { - contact_list_add(contact, NULL, show, status, NULL); - PContact result = contact_list_get_contact(contact); - if (p_contact_subscription(result) != NULL) { - if (strcmp(p_contact_subscription(result), "none") != 0) { - win_contact_online(contact, show, status); - win_page_off(); + gboolean updated = contact_list_update_contact(contact, show, status); + + if (updated) { + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_online(contact, show, status); + win_page_off(); + } } } } @@ -178,12 +181,15 @@ prof_handle_contact_online(char *contact, char *show, char *status) void prof_handle_contact_offline(char *contact, char *show, char *status) { - contact_list_add(contact, NULL, "offline", status, NULL); - PContact result = contact_list_get_contact(contact); - if (p_contact_subscription(result) != NULL) { - if (strcmp(p_contact_subscription(result), "none") != 0) { - win_contact_offline(contact, show, status); - win_page_off(); + gboolean updated = contact_list_update_contact(contact, "offline", status); + + if (updated) { + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_offline(contact, show, status); + win_page_off(); + } } } } From 768b2aa4667a362ea1343f47c044d79b642c2497 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 29 Oct 2012 22:55:17 +0000 Subject: [PATCH 10/10] Fixed tests --- Makefile.am | 3 +- src/contact_list.c | 9 +- src/contact_list.h | 2 +- src/jabber.c | 6 +- tests/test_contact_list.c | 322 +++++++++++---------------------- tests/test_prof_autocomplete.c | 217 ---------------------- 6 files changed, 114 insertions(+), 445 deletions(-) diff --git a/Makefile.am b/Makefile.am index f28807d6..72343a7b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,8 @@ TESTS = tests/testsuite check_PROGRAMS = tests/testsuite tests_testsuite_SOURCES = tests/test_contact_list.c src/contact_list.c src/contact.c \ tests/test_common.c tests/test_prof_history.c src/prof_history.c src/common.c \ - tests/test_prof_autocomplete.c src/prof_autocomplete.c tests/testsuite.c + tests/test_prof_autocomplete.c src/prof_autocomplete.c tests/testsuite.c \ + src/log.c tests_testsuite_LDADD = -lheadunit -lstdc++ man_MANS = docs/profanity.1 diff --git a/src/contact_list.c b/src/contact_list.c index 3f8ff2ee..d05d7412 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -54,21 +54,22 @@ contact_list_reset_search_attempts(void) p_autocomplete_reset(ac); } -void +gboolean contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription) { + gboolean added = FALSE; PContact contact = g_hash_table_lookup(contacts, jid); if (contact == NULL) { contact = p_contact_new(jid, name, presence, status, subscription); g_hash_table_insert(contacts, strdup(jid), contact); - } else { - log_warning("Duplicate roster entry: %s", jid); + p_autocomplete_add(ac, strdup(jid)); + added = TRUE; } - p_autocomplete_add(ac, strdup(jid)); + return added; } gboolean diff --git a/src/contact_list.h b/src/contact_list.h index 9f6bbe4c..90ae947b 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -30,7 +30,7 @@ void contact_list_init(void); void contact_list_clear(void); void contact_list_reset_search_attempts(void); -void contact_list_add(const char * const jid, const char * const name, +gboolean contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription); gboolean contact_list_update_contact(const char * const jid, const char * const presence, diff --git a/src/jabber.c b/src/jabber.c index e2e146e8..8c9c9ba0 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -386,7 +386,11 @@ _roster_handler(xmpp_conn_t * const conn, const char *jid = xmpp_stanza_get_attribute(item, "jid"); const char *name = xmpp_stanza_get_attribute(item, "name"); const char *sub = xmpp_stanza_get_attribute(item, "subscription"); - contact_list_add(jid, name, "offline", NULL, sub); + gboolean added = contact_list_add(jid, name, "offline", NULL, sub); + + if (!added) { + log_warning("Attempt to add contact twice: %s", jid); + } item = xmpp_stanza_get_next(item); } diff --git a/tests/test_contact_list.c b/tests/test_contact_list.c index 18d5a6e4..ef31abbc 100644 --- a/tests/test_contact_list.c +++ b/tests/test_contact_list.c @@ -31,24 +31,24 @@ static void empty_list_when_none_added(void) static void contains_one_element(void) { - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); assert_int_equals(1, g_slist_length(list)); } static void first_element_correct(void) { - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); + assert_string_equals("James", p_contact_jid(james)); } static void contains_two_elements(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); assert_int_equals(2, g_slist_length(list)); @@ -56,22 +56,22 @@ static void contains_two_elements(void) static void first_and_second_elements_correct(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); - PContact dave = list->data; - PContact james = (g_slist_next(list))->data; + PContact first = list->data; + PContact second = (g_slist_next(list))->data; - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("Dave", p_contact_name(dave)); + assert_string_equals("James", p_contact_jid(first)); + assert_string_equals("Dave", p_contact_jid(second)); } static void contains_three_elements(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - contact_list_add("Dave", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); assert_int_equals(3, g_slist_length(list)); @@ -79,194 +79,100 @@ static void contains_three_elements(void) 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); + contact_list_add("Bob", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); 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)); - assert_string_equals("Bob", p_contact_name(bob)); + assert_string_equals("James", p_contact_jid(james)); + assert_string_equals("Dave", p_contact_jid(dave)); + assert_string_equals("Bob", p_contact_jid(bob)); } static void add_twice_at_beginning_adds_once(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); 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; + PContact first = list->data; + PContact second = (g_slist_next(list))->data; + PContact third = (g_slist_next(g_slist_next(list)))->data; assert_int_equals(3, g_slist_length(list)); - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("Dave", p_contact_name(dave)); - assert_string_equals("Bob", p_contact_name(bob)); + assert_string_equals("James", p_contact_jid(first)); + assert_string_equals("Dave", p_contact_jid(second)); + assert_string_equals("Bob", p_contact_jid(third)); } static void add_twice_in_middle_adds_once(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("James", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); 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; + PContact first = list->data; + PContact second = (g_slist_next(list))->data; + PContact third = (g_slist_next(g_slist_next(list)))->data; assert_int_equals(3, g_slist_length(list)); - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("Dave", p_contact_name(dave)); - assert_string_equals("Bob", p_contact_name(bob)); + assert_string_equals("James", p_contact_jid(first)); + assert_string_equals("Dave", p_contact_jid(second)); + assert_string_equals("Bob", p_contact_jid(third)); } static void add_twice_at_end_adds_once(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); 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; + PContact first = list->data; + PContact second = (g_slist_next(list))->data; + PContact third = (g_slist_next(g_slist_next(list)))->data; assert_int_equals(3, g_slist_length(list)); - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("Dave", p_contact_name(dave)); - assert_string_equals("Bob", p_contact_name(bob)); -} - -static void remove_when_none_does_nothing(void) -{ - contact_list_remove("James"); - GSList *list = get_contact_list(); - - assert_int_equals(0, g_slist_length(list)); -} - -static void remove_when_one_removes(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_remove("James"); - GSList *list = get_contact_list(); - - assert_int_equals(0, g_slist_length(list)); -} - -static void remove_first_when_two(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - - contact_list_remove("James"); - GSList *list = get_contact_list(); - - assert_int_equals(1, g_slist_length(list)); - PContact dave = list->data; - assert_string_equals("Dave", p_contact_name(dave)); -} - -static void remove_second_when_two(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - - contact_list_remove("Dave"); - GSList *list = get_contact_list(); - - assert_int_equals(1, g_slist_length(list)); - PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); -} - -static void remove_first_when_three(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - - contact_list_remove("James"); - GSList *list = get_contact_list(); - - assert_int_equals(2, g_slist_length(list)); - 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)); -} - -static void remove_second_when_three(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - - contact_list_remove("Dave"); - GSList *list = get_contact_list(); - - assert_int_equals(2, g_slist_length(list)); - 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)); -} - -static void remove_third_when_three(void) -{ - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - - contact_list_remove("Bob"); - GSList *list = get_contact_list(); - - assert_int_equals(2, g_slist_length(list)); - 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)); + assert_string_equals("James", p_contact_jid(first)); + assert_string_equals("Dave", p_contact_jid(second)); + assert_string_equals("Bob", p_contact_jid(third)); } static void test_show_when_value(void) { - contact_list_add("James", "away", NULL); + contact_list_add("James", NULL, "away", NULL, NULL); GSList *list = get_contact_list(); PContact james = list->data; - assert_string_equals("away", p_contact_show(james)); + assert_string_equals("away", p_contact_presence(james)); } static void test_show_online_when_no_value(void) { - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); PContact james = list->data; - assert_string_equals("online", p_contact_show(james)); + assert_string_equals("online", p_contact_presence(james)); } static void test_show_online_when_empty_string(void) { - contact_list_add("James", "", NULL); + contact_list_add("James", NULL, "", NULL, NULL); GSList *list = get_contact_list(); PContact james = list->data; - assert_string_equals("online", p_contact_show(james)); + assert_string_equals("online", p_contact_presence(james)); } static void test_status_when_value(void) { - contact_list_add("James", NULL, "I'm not here right now"); + contact_list_add("James", NULL, NULL, "I'm not here right now", NULL); GSList *list = get_contact_list(); PContact james = list->data; @@ -275,7 +181,7 @@ static void test_status_when_value(void) static void test_status_when_no_value(void) { - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); GSList *list = get_contact_list(); PContact james = list->data; @@ -284,57 +190,57 @@ static void test_status_when_no_value(void) static void update_show(void) { - contact_list_add("James", "away", NULL); - contact_list_add("James", "dnd", NULL); + contact_list_add("James", NULL, "away", NULL, NULL); + contact_list_update_contact("James", "dnd", NULL); GSList *list = get_contact_list(); assert_int_equals(1, g_slist_length(list)); - PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("dnd", p_contact_show(james)); + PContact first = list->data; + assert_string_equals("James", p_contact_jid(first)); + assert_string_equals("dnd", p_contact_presence(first)); } static void set_show_to_null(void) { - contact_list_add("James", "away", NULL); - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, "away", NULL, NULL); + contact_list_update_contact("James", NULL, NULL); GSList *list = get_contact_list(); assert_int_equals(1, g_slist_length(list)); PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); - assert_string_equals("online", p_contact_show(james)); + assert_string_equals("James", p_contact_jid(james)); + assert_is_null(p_contact_presence(james)); } static void update_status(void) { - contact_list_add("James", NULL, "I'm not here right now"); - contact_list_add("James", NULL, "Gone to lunch"); + contact_list_add("James", NULL, NULL, "I'm not here right now", NULL); + contact_list_update_contact("James", NULL, "Gone to lunch"); GSList *list = get_contact_list(); assert_int_equals(1, g_slist_length(list)); PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); + assert_string_equals("James", p_contact_jid(james)); assert_string_equals("Gone to lunch", p_contact_status(james)); } static void set_status_to_null(void) { - contact_list_add("James", NULL, "Gone to lunch"); - contact_list_add("James", NULL, NULL); + contact_list_add("James", NULL, NULL, "Gone to lunch", NULL); + contact_list_update_contact("James", NULL, NULL); GSList *list = get_contact_list(); assert_int_equals(1, g_slist_length(list)); PContact james = list->data; - assert_string_equals("James", p_contact_name(james)); + assert_string_equals("James", p_contact_jid(james)); assert_is_null(p_contact_status(james)); } static void find_first_exists(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *search = (char *) malloc(2 * sizeof(char)); strcpy(search, "B"); @@ -347,9 +253,9 @@ static void find_first_exists(void) static void find_second_exists(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *result = contact_list_find_contact("Dav"); assert_string_equals("Dave", result); @@ -358,9 +264,9 @@ static void find_second_exists(void) static void find_third_exists(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *result = contact_list_find_contact("Ja"); assert_string_equals("James", result); @@ -369,9 +275,9 @@ static void find_third_exists(void) static void find_returns_null(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *result = contact_list_find_contact("Mike"); assert_is_null(result); @@ -385,9 +291,9 @@ static void find_on_empty_returns_null(void) static void find_twice_returns_second_when_two_match(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Jamie", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Jamie", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *result1 = contact_list_find_contact("Jam"); char *result2 = contact_list_find_contact(result1); @@ -398,16 +304,16 @@ static void find_twice_returns_second_when_two_match(void) static void find_five_times_finds_fifth(void) { - contact_list_add("Jama", NULL, NULL); - contact_list_add("Jamb", NULL, NULL); - contact_list_add("Mike", NULL, NULL); - contact_list_add("Dave", NULL, NULL); - contact_list_add("Jamm", NULL, NULL); - contact_list_add("Jamn", NULL, NULL); - contact_list_add("Matt", NULL, NULL); - contact_list_add("Jamo", NULL, NULL); - contact_list_add("Jamy", NULL, NULL); - contact_list_add("Jamz", NULL, NULL); + contact_list_add("Jama", NULL, NULL, NULL, NULL); + contact_list_add("Jamb", NULL, NULL, NULL, NULL); + contact_list_add("Mike", NULL, NULL, NULL, NULL); + contact_list_add("Dave", NULL, NULL, NULL, NULL); + contact_list_add("Jamm", NULL, NULL, NULL, NULL); + contact_list_add("Jamn", NULL, NULL, NULL, NULL); + contact_list_add("Matt", NULL, NULL, NULL, NULL); + contact_list_add("Jamo", NULL, NULL, NULL, NULL); + contact_list_add("Jamy", NULL, NULL, NULL, NULL); + contact_list_add("Jamz", NULL, NULL, NULL, NULL); char *result1 = contact_list_find_contact("Jam"); char *result2 = contact_list_find_contact(result1); @@ -424,9 +330,9 @@ static void find_five_times_finds_fifth(void) static void find_twice_returns_first_when_two_match_and_reset(void) { - contact_list_add("James", NULL, NULL); - contact_list_add("Jamie", NULL, NULL); - contact_list_add("Bob", NULL, NULL); + contact_list_add("James", NULL, NULL, NULL, NULL); + contact_list_add("Jamie", NULL, NULL, NULL, NULL); + contact_list_add("Bob", NULL, NULL, NULL, NULL); char *result1 = contact_list_find_contact("Jam"); contact_list_reset_search_attempts(); @@ -436,24 +342,6 @@ static void find_twice_returns_first_when_two_match_and_reset(void) free(result2); } -static void removed_contact_not_in_search(void) -{ - contact_list_add("Jamatron", NULL, NULL); - contact_list_add("Bob", NULL, NULL); - contact_list_add("Jambo", NULL, NULL); - contact_list_add("James", NULL, NULL); - contact_list_add("Jamie", NULL, NULL); - - char *result1 = contact_list_find_contact("Jam"); // Jamatron - char *result2 = contact_list_find_contact(result1); // Jambo - contact_list_remove("James"); - char *result3 = contact_list_find_contact(result2); - assert_string_equals("Jamie", result3); - free(result1); - free(result2); - free(result3); -} - void register_contact_list_tests(void) { TEST_MODULE("contact_list tests"); @@ -470,13 +358,6 @@ void register_contact_list_tests(void) TEST(add_twice_at_beginning_adds_once); TEST(add_twice_in_middle_adds_once); TEST(add_twice_at_end_adds_once); - TEST(remove_when_none_does_nothing); - TEST(remove_when_one_removes); - TEST(remove_first_when_two); - TEST(remove_second_when_two); - TEST(remove_first_when_three); - TEST(remove_second_when_three); - TEST(remove_third_when_three); TEST(test_show_when_value); TEST(test_show_online_when_no_value); TEST(test_show_online_when_empty_string); @@ -493,6 +374,5 @@ void register_contact_list_tests(void) TEST(find_on_empty_returns_null); TEST(find_twice_returns_second_when_two_match); TEST(find_twice_returns_first_when_two_match_and_reset); - TEST(removed_contact_not_in_search); TEST(find_five_times_finds_fifth); } diff --git a/tests/test_prof_autocomplete.c b/tests/test_prof_autocomplete.c index 895a4a44..b61c9cf6 100644 --- a/tests/test_prof_autocomplete.c +++ b/tests/test_prof_autocomplete.c @@ -13,16 +13,6 @@ static void clear_empty(void) p_autocomplete_clear(ac); } -static void clear_empty_with_free_func(void) -{ - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_clear(ac); -} - static void reset_after_create(void) { PAutocomplete ac = p_autocomplete_new(); @@ -47,20 +37,6 @@ static void get_after_create_returns_null(void) p_autocomplete_clear(ac); } -static void get_after_create_with_copy_func_returns_null(void) -{ - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - GSList *result = p_autocomplete_get_list(ac); - - assert_is_null(result); - - p_autocomplete_clear(ac); -} - static void add_one_and_complete(void) { char *item = strdup("Hello"); @@ -73,22 +49,6 @@ static void add_one_and_complete(void) p_autocomplete_clear(ac); } -static void add_one_and_complete_with_funcs(void) -{ - PContact contact = p_contact_new("James", "Online", "I'm here"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact); - char *result = p_autocomplete_complete(ac, "Jam"); - - assert_string_equals("James", result); - - p_autocomplete_clear(ac); -} - static void add_two_and_complete_returns_first(void) { char *item1 = strdup("Hello"); @@ -103,24 +63,6 @@ static void add_two_and_complete_returns_first(void) p_autocomplete_clear(ac); } -static void add_two_and_complete_returns_first_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("Jamie", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact1); - p_autocomplete_add(ac, contact2); - char *result = p_autocomplete_complete(ac, "Jam"); - - assert_string_equals("James", result); - - p_autocomplete_clear(ac); -} - static void add_two_and_complete_returns_second(void) { char *item1 = strdup("Hello"); @@ -136,25 +78,6 @@ static void add_two_and_complete_returns_second(void) p_autocomplete_clear(ac); } -static void add_two_and_complete_returns_second_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("Jamie", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact1); - p_autocomplete_add(ac, contact2); - char *result1 = p_autocomplete_complete(ac, "Jam"); - char *result2 = p_autocomplete_complete(ac, result1); - - assert_string_equals("Jamie", result2); - - p_autocomplete_clear(ac); -} - static void add_two_adds_two(void) { char *item1 = strdup("Hello"); @@ -169,24 +92,6 @@ static void add_two_adds_two(void) p_autocomplete_clear(ac); } -static void add_two_adds_two_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("Jamie", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact1); - p_autocomplete_add(ac, contact2); - GSList *result = p_autocomplete_get_list(ac); - - assert_int_equals(2, g_slist_length(result)); - - p_autocomplete_clear(ac); -} - static void add_two_same_adds_one(void) { char *item1 = strdup("Hello"); @@ -201,24 +106,6 @@ static void add_two_same_adds_one(void) p_autocomplete_clear(ac); } -static void add_two_same_adds_one_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("James", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact1); - p_autocomplete_add(ac, contact2); - GSList *result = p_autocomplete_get_list(ac); - - assert_int_equals(1, g_slist_length(result)); - - p_autocomplete_clear(ac); -} - static void add_two_same_updates(void) { char *item1 = strdup("Hello"); @@ -237,29 +124,6 @@ static void add_two_same_updates(void) p_autocomplete_clear(ac); } -static void add_two_same_updates_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("James", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - p_autocomplete_add(ac, contact1); - p_autocomplete_add(ac, contact2); - GSList *result = p_autocomplete_get_list(ac); - - GSList *first = g_slist_nth(result, 0); - PContact contact = first->data; - - assert_string_equals("James", p_contact_name(contact)); - assert_string_equals("Away", p_contact_show(contact)); - assert_string_equals("Out to lunch", p_contact_status(contact)); - - p_autocomplete_clear(ac); -} - static void add_one_returns_true(void) { char *item = strdup("Hello"); @@ -271,21 +135,6 @@ static void add_one_returns_true(void) p_autocomplete_clear(ac); } -static void add_one_returns_true_with_funcs(void) -{ - PContact contact = p_contact_new("James", "Online", "I'm here"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - int result = p_autocomplete_add(ac, contact); - - assert_true(result); - - p_autocomplete_clear(ac); -} - static void add_two_different_returns_true(void) { char *item1 = strdup("Hello"); @@ -300,24 +149,6 @@ static void add_two_different_returns_true(void) p_autocomplete_clear(ac); } -static void add_two_different_returns_true_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("JamesB", "Away", "Out to lunch"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - int result1 = p_autocomplete_add(ac, contact1); - int result2 = p_autocomplete_add(ac, contact2); - - assert_true(result1); - assert_true(result2); - - p_autocomplete_clear(ac); -} - static void add_two_same_returns_false(void) { char *item1 = strdup("Hello"); @@ -332,68 +163,20 @@ static void add_two_same_returns_false(void) p_autocomplete_clear(ac); } -static void add_two_same_returns_false_with_funcs(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("James", "Online", "I'm here"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - int result1 = p_autocomplete_add(ac, contact1); - int result2 = p_autocomplete_add(ac, contact2); - - assert_true(result1); - assert_false(result2); - - p_autocomplete_clear(ac); -} - -static void add_two_same_different_data_returns_true(void) -{ - PContact contact1 = p_contact_new("James", "Online", "I'm here"); - PContact contact2 = p_contact_new("James", "Away", "I'm not here right now"); - PAutocomplete ac = - p_obj_autocomplete_new((PStrFunc)p_contact_name, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); - int result1 = p_autocomplete_add(ac, contact1); - int result2 = p_autocomplete_add(ac, contact2); - - assert_true(result1); - assert_true(result2); - - p_autocomplete_clear(ac); -} - void register_prof_autocomplete_tests(void) { TEST_MODULE("prof_autocomplete tests"); TEST(clear_empty); - TEST(clear_empty_with_free_func); TEST(reset_after_create); TEST(find_after_create); TEST(get_after_create_returns_null); - TEST(get_after_create_with_copy_func_returns_null); TEST(add_one_and_complete); - TEST(add_one_and_complete_with_funcs); TEST(add_two_and_complete_returns_first); - TEST(add_two_and_complete_returns_first_with_funcs); TEST(add_two_and_complete_returns_second); - TEST(add_two_and_complete_returns_second_with_funcs); TEST(add_two_adds_two); - TEST(add_two_adds_two_with_funcs); TEST(add_two_same_adds_one); - TEST(add_two_same_adds_one_with_funcs); TEST(add_two_same_updates); - TEST(add_two_same_updates_with_funcs); TEST(add_one_returns_true); - TEST(add_one_returns_true_with_funcs); TEST(add_two_different_returns_true); - TEST(add_two_different_returns_true_with_funcs); TEST(add_two_same_returns_false); - TEST(add_two_same_returns_false_with_funcs); - TEST(add_two_same_different_data_returns_true); }