diff options
author | James Booth <boothj5@gmail.com> | 2012-03-10 23:48:10 +0000 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2012-03-10 23:48:10 +0000 |
commit | f7584469bb8e546f547706083be6d7ccc19c59dc (patch) | |
tree | ce73b27d4ccb3da9b42bdaf92e9a0c3873dccff5 | |
parent | b22a7c5fdad64636200d43219a47fca8a24cc16f (diff) | |
download | profani-tty-f7584469bb8e546f547706083be6d7ccc19c59dc.tar.gz |
Tab completion of online contacts now rolls
-rw-r--r-- | contact_list.c | 77 | ||||
-rw-r--r-- | input_win.c | 3 | ||||
-rw-r--r-- | test_contact_list.c | 41 |
3 files changed, 117 insertions, 4 deletions
diff --git a/contact_list.c b/contact_list.c index 050ddc41..51abe21b 100644 --- a/contact_list.c +++ b/contact_list.c @@ -33,10 +33,11 @@ struct _contact_node_t { }; // the contact list -static struct _contact_node_t *_contact_list = NULL; +static struct _contact_node_t * _contact_list = NULL; // number of tabs pressed whilst searching -static int _search_attempts = 0; +static struct _contact_node_t * _last_found = NULL; +static char * _search_str = NULL; static struct _contact_node_t * _make_contact_node(const char * const name, const char * const show, const char * const status); @@ -57,12 +58,18 @@ void contact_list_clear(void) free(_contact_list); _contact_list = NULL; + + reset_search_attempts(); } } void reset_search_attempts(void) { - _search_attempts = 0; + _last_found = NULL; + if (_search_str != NULL) { + free(_search_str); + _search_str = NULL; + } } int contact_list_remove(const char * const name) @@ -81,6 +88,11 @@ int contact_list_remove(const char * const name) else _contact_list = curr->next; + // reset last found if it points at the node to be removed + if (_last_found != NULL) + if (strcmp(_last_found->contact->name, contact->name) == 0) + _last_found = NULL; + _destroy_contact(contact); free(curr); @@ -176,16 +188,73 @@ char * find_contact(const char * const search_str) { struct _contact_node_t *curr = _contact_list; + // no contact if (!curr) { return NULL; + + // not first search attempt + } else if (_last_found != NULL) { + + // search from here+1 to end + curr = _last_found->next; + while(curr) { + contact_t *curr_contact = curr->contact; + + // match found + if (strncmp(curr_contact->name, _search_str, strlen(_search_str)) == 0) { + char *result = + (char *) malloc((strlen(curr_contact->name) + 1) * sizeof(char)); + + // set pointer to last found + _last_found = curr; + + // return the contact, must be free'd by caller + strcpy(result, curr_contact->name); + return result; + } + + curr = curr->next; + } + + // search from beginning to last found + curr = _contact_list; + while(curr) { + contact_t *curr_contact = curr->contact; + + // match found + if (strncmp(curr_contact->name, _search_str, strlen(_search_str)) == 0) { + char *result = + (char *) malloc((strlen(curr_contact->name) + 1) * sizeof(char)); + + // set pointer to last found + _last_found = curr; + + // return the contact, must be free'd by caller + strcpy(result, curr_contact->name); + return result; + } + + curr = curr->next; + } + + // we found nothing, reset last_found + reset_search_attempts(); + return NULL; + + // first attempt at searching } else { + _search_str = (char *) malloc((strlen(search_str) + 1) * sizeof(char)); + strcpy(_search_str, search_str); while(curr) { contact_t *curr_contact = curr->contact; // match found - if (strncmp(curr_contact->name, search_str, strlen(search_str)) == 0) { + if (strncmp(curr_contact->name, _search_str, strlen(_search_str)) == 0) { char *result = (char *) malloc((strlen(curr_contact->name) + 1) * sizeof(char)); + + // set pointer to last found + _last_found = curr; // return the contact, must be free'd by caller strcpy(result, curr_contact->name); diff --git a/input_win.c b/input_win.c index 88e21355..176b1847 100644 --- a/input_win.c +++ b/input_win.c @@ -108,6 +108,8 @@ void inp_get_char(int *ch, char *input, int *size) waddch(inp_win, *ch); input[(*size)++] = *ch; } + + reset_search_attempts(); } } @@ -151,6 +153,7 @@ static int _handle_edit(const int ch, char *input, int *size) case 127: case KEY_BACKSPACE: + reset_search_attempts(); if (*size > 0) { // if at end, delete last char diff --git a/test_contact_list.c b/test_contact_list.c index 92972651..135ddb54 100644 --- a/test_contact_list.c +++ b/test_contact_list.c @@ -359,6 +359,44 @@ static void find_on_empty_returns_null(void) assert_is_null(result); } +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); + + char *result1 = find_contact("Jam"); + char *result2 = find_contact(result1); + assert_string_equals("Jamie", result2); +} + +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); + + char *result1 = find_contact("Jam"); + reset_search_attempts(); + char *result2 = find_contact(result1); + assert_string_equals("James", 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 = find_contact("Jam"); // Jamatron + char *result2 = find_contact(result1); // Jambo + contact_list_remove("James"); + char *result3 = find_contact(result2); + assert_string_equals("Jamie", result3); +} + void register_contact_list_tests(void) { TEST_MODULE("contact_list tests"); @@ -394,4 +432,7 @@ void register_contact_list_tests(void) TEST(find_third_exists); TEST(find_returns_null); 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); } |