about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-03-10 23:48:10 +0000
committerJames Booth <boothj5@gmail.com>2012-03-10 23:48:10 +0000
commitf7584469bb8e546f547706083be6d7ccc19c59dc (patch)
treece73b27d4ccb3da9b42bdaf92e9a0c3873dccff5
parentb22a7c5fdad64636200d43219a47fca8a24cc16f (diff)
downloadprofani-tty-f7584469bb8e546f547706083be6d7ccc19c59dc.tar.gz
Tab completion of online contacts now rolls
-rw-r--r--contact_list.c77
-rw-r--r--input_win.c3
-rw-r--r--test_contact_list.c41
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);
 }