about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-05-01 00:24:31 +0100
committerJames Booth <boothj5@gmail.com>2012-05-01 00:24:31 +0100
commit1730372e00a7469a05c7535c68dbfab83f8af0b4 (patch)
tree9278455cd79141634465863bbcfd0d0595b232ad
parent4531aebd291186e9dd49fb2ec1f1b9b96a4ed23f (diff)
downloadprofani-tty-1730372e00a7469a05c7535c68dbfab83f8af0b4.tar.gz
Bash style history
-rw-r--r--Makefile7
-rw-r--r--command.c5
-rw-r--r--command.h2
-rw-r--r--history.c56
-rw-r--r--history.h6
-rw-r--r--input_win.c4
-rw-r--r--prof_history.c25
-rw-r--r--profanity.c3
-rw-r--r--test_history.c130
-rw-r--r--test_prof_history.c107
-rw-r--r--testsuite.c1
-rw-r--r--testsuite.h1
12 files changed, 148 insertions, 199 deletions
diff --git a/Makefile b/Makefile
index be25a2aa..61210e29 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ CFLAGS = -I ~/include -O3 $(WARNS) $(LIBS) `pkg-config --cflags glib-2.0`
 OBJS = log.o windows.o title_bar.o status_bar.o input_win.o jabber.o \
        profanity.o util.o command.o history.o contact_list.o prof_history.o \
 	   main.o
-TESTOBJS = test_history.o history.o test_contact_list.o contact_list.o \
+TESTOBJS = test_contact_list.o contact_list.o \
 	       test_util.o test_prof_history.o prof_history.o util.o
 
 profanity: $(OBJS)
@@ -20,15 +20,14 @@ title_bar.o: windows.h
 status_bar.o: windows.h util.h
 input_win.o: windows.h
 jabber.o: jabber.h log.h windows.h contact_list.h
-profanity.o: log.h windows.h jabber.h command.h history.h
+profanity.o: log.h windows.h jabber.h command.h
 util.o: util.h
 command.o: command.h util.h history.h contact_list.h
-history.o: history.h
+history.o: history.h prof_history.h
 contact_list.o: contact_list.h
 prof_history.o: prof_history.h
 main.o: profanity.h
 
-test_history.o: history.h
 test_contact_list.o: contact_list.h
 test_util.o: util.h
 test_prof_history.o: prof_history.h
diff --git a/command.c b/command.c
index 17c2dcb0..1de58310 100644
--- a/command.c
+++ b/command.c
@@ -72,6 +72,11 @@ gboolean process_input(char *inp)
     return result;
 }
 
+void command_init(void)
+{
+    history_init();
+}
+
 static gboolean _handle_command(const char * const command, const char * const inp)
 {
     gboolean result = FALSE;
diff --git a/command.h b/command.h
index d0d57022..9da8838c 100644
--- a/command.h
+++ b/command.h
@@ -23,7 +23,7 @@
 #ifndef COMMAND_H
 #define COMMAND_H
 
-void cmd_init(void);
+void command_init(void);
 gboolean process_input(char *inp);
 
 #endif
diff --git a/history.c b/history.c
index 00b06582..a7b570f8 100644
--- a/history.c
+++ b/history.c
@@ -23,53 +23,43 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "prof_history.h"
+
 #define MAX_HISTORY 100
 
-static char *_history[MAX_HISTORY];
-static int _size;
-static int _pos;
+static PHistory history;
 
 void history_init(void)
 {
-    int i;
-    for (i = 0; i < _size; i++)
-        free(_history[i]);
-    
-    _size = 0;
-    _pos = -1;
+    history = p_history_new(MAX_HISTORY);
 }
 
-// FIXME: Roll history when full
-void history_append(const char * const inp)
+void history_append(char *inp)
 {
-    if (_size < MAX_HISTORY) {
-        _history[_size] = (char*) malloc((strlen(inp) + 1) * sizeof(char));
-        strcpy(_history[_size], inp);
-        _pos = _size;
-        _size++;
-    }
+    p_history_append(history, inp);
 }
 
-char *history_previous(void)
+char * history_previous(char *inp, int *size)
 {
-    if (_size == 0 || _pos == -1)
-        return NULL;
+    char inp_str[*size + 1];
+    int i;
+    for (i = 0; i < *size; i++) {
+        inp_str[i] = inp[i];
+    }
+    inp_str[*size] = '\0';
 
-    return _history[_pos--];
+    return p_history_previous(history, inp_str);
 }
 
-char *history_next(void)
+char *history_next(char *inp, int *size)
 {
-    if (_size == 0)
-        return NULL;
-    if (_pos == (_size - 1))
-        return NULL;
-    if (_pos + 2 >= _size)
-        return NULL;
-    
-    int pos = _pos + 2;
-    _pos++;
- 
-    return _history[pos];
+    char inp_str[*size + 1];
+    int i;
+    for (i = 0; i < *size; i++) {
+        inp_str[i] = inp[i];
+    }
+    inp_str[*size] = '\0';
+
+    return p_history_next(history, inp_str);
 }
 
diff --git a/history.h b/history.h
index 7afca5e1..a65ac397 100644
--- a/history.h
+++ b/history.h
@@ -25,8 +25,8 @@
 #define HISTORY_H
 
 void history_init(void);
-void history_append(const char * const inp);
-char *history_previous(void);
-char *history_next(void);
+void history_append(char *inp);
+char *history_previous(char *inp, int *size);
+char *history_next(char *inp, int *size);
 
 #endif
diff --git a/input_win.c b/input_win.c
index f0cd364f..5ed17d05 100644
--- a/input_win.c
+++ b/input_win.c
@@ -210,13 +210,13 @@ static int _handle_edit(const int ch, char *input, int *size)
         return 1;
 
     case KEY_UP:
-        prev = history_previous();
+        prev = history_previous(input, size);
         if (prev)
             _replace_input(input, prev, size);
         return 1;
 
     case KEY_DOWN:
-        next = history_next();
+        next = history_next(input, size);
         if (next)
             _replace_input(input, next, size);
         return 1;
diff --git a/prof_history.c b/prof_history.c
index e896ac15..cf82fafd 100644
--- a/prof_history.c
+++ b/prof_history.c
@@ -62,26 +62,19 @@ void p_history_append(PHistory history, char *item)
     } else {
 
         // if adding a new item, copy the session over the history
-        if ((history->sess_new != NULL) && 
-                (history->sess_curr == history->sess_new)) {
+        if (history->sess_curr == history->sess_new) {
+            history->sess_curr->data = copied;
             _replace_history_with_session(history);
 
         // otherwise, adding edited history item
         } else {
-            
-            // discard the new item if there was one
             if (history->sess_new != NULL) {
-                history->session = g_list_reverse(history->session);
-                GList *first = g_list_first(history->session);
-                char *first_item = first->data;
-                history->session = g_list_remove(history->session, first_item);
-                history->session = g_list_reverse(history->session);
+                // copy the current string to the last element in session
+                history->sess_new->data = copied;
+            } else {
+                g_list_append(history->session, copied);
             }
-
-            // copy sess_curr to the end of the session
-            char *new_data = strdup(history->sess_curr->data);
-            history->session = g_list_append(history->session, new_data);
-
+            
             // replace the edited version with the data from the history
             history->sess_curr->data = strdup(history->items_curr->data);
             
@@ -114,7 +107,7 @@ char * p_history_previous(PHistory history, char *item)
 {
     // no history
     if (history->items == NULL) {
-        return item;
+        return NULL;
     }
 
     char *copied = "";
@@ -160,7 +153,7 @@ char * p_history_next(PHistory history, char *item)
 
     // no history, or no session, return item
     if ((history->items == NULL) || (history->session == NULL)) {
-        return item;
+        return NULL;
     }
 
     char *copied = "";
diff --git a/profanity.c b/profanity.c
index de26f8b8..f87fca6a 100644
--- a/profanity.c
+++ b/profanity.c
@@ -29,7 +29,6 @@
 #include "windows.h"
 #include "jabber.h"
 #include "command.h"
-#include "history.h"
 
 static void _profanity_shutdown(void);
 
@@ -67,7 +66,7 @@ void profanity_init(const int disable_tls)
     log_init();
     gui_init();
     jabber_init(disable_tls);
-    history_init();
+    command_init();
     atexit(_profanity_shutdown);
 }
 
diff --git a/test_history.c b/test_history.c
deleted file mode 100644
index f455d7d1..00000000
--- a/test_history.c
+++ /dev/null
@@ -1,130 +0,0 @@
-#include <stdlib.h>
-#include <head-unit.h>
-#include "history.h"
-
-static void beforetest(void)
-{
-    history_init();
-}
-
-static void previous_returns_null_after_init(void)
-{
-    char *prev = history_previous();
-    assert_is_null(prev);
-}
-
-static void next_returns_null_after_init(void)
-{
-    char *next = history_next();
-    assert_is_null(next);
-}
-
-static void append_after_init_doesnt_fail(void)
-{
-    history_append("try append");
-    assert_true(1);
-}
-
-static void append_then_previous_returns_appended(void)
-{
-    history_append("try append");
-    char *prev = history_previous();
-    assert_string_equals("try append", prev); 
-}
-
-static void append_then_next_returns_null(void)
-{
-    history_append("try append");
-    char *next = history_next();
-    assert_is_null(next);
-}
-
-static void hits_null_at_top(void)
-{
-    history_append("cmd1");
-    history_append("cmd2");
-    history_previous(); // cmd2
-    history_previous(); // cmd1
-    char *prev = history_previous();
-    assert_is_null(prev);
-}
-
-static void navigate_to_correct_item(void)
-{
-    history_append("cmd1");
-    history_append("cmd2");
-    history_append("cmd3");
-    history_append("cmd4");
-    history_append("cmd5");
-    history_append("cmd6");
-
-    history_previous(); // cmd6
-    history_previous(); // cmd5
-    history_previous(); // cmd4
-    history_previous(); // cmd3
-    history_next(); // cmd4
-    history_previous(); // cmd3
-    history_previous(); // cmd2
-    char *str = history_next(); // cmd3
-
-    assert_string_equals("cmd3", str);
-}
-
-static void append_previous_item(void)
-{
-    history_append("cmd1");
-    history_append("cmd2");
-    history_append("cmd3");
-    history_append("cmd4");
-    history_append("cmd5");
-    history_append("cmd6");
-
-    history_previous(); // cmd6
-    history_previous(); // cmd5
-    history_previous(); // cmd4
-    history_previous(); // cmd3
-    history_next(); // cmd4
-    history_previous(); // cmd3
-    history_previous(); // cmd2
-    char *str = history_next(); // cmd3
-
-    history_append(str);
-
-    char *cmd3_1 = history_previous();
-    assert_string_equals("cmd3", cmd3_1);
-
-    char *cmd6 = history_previous();
-    assert_string_equals("cmd6", cmd6);
-
-    char *cmd5 = history_previous();
-    assert_string_equals("cmd5", cmd5);
-
-    char *cmd4 = history_previous();
-    assert_string_equals("cmd4", cmd4);
-
-    char *cmd3 = history_previous();
-    assert_string_equals("cmd3", cmd3);
-
-    char *cmd2 = history_previous();
-    assert_string_equals("cmd2", cmd2);
-
-    char *cmd1 = history_previous();
-    assert_string_equals("cmd1", cmd1);
-
-    char *end = history_previous();
-    assert_is_null(end);
-}
-
-void register_history_tests(void)
-{
-    TEST_MODULE("history tests");
-    BEFORETEST(beforetest);
-    TEST(previous_returns_null_after_init);
-    TEST(next_returns_null_after_init);
-    TEST(append_after_init_doesnt_fail);
-    TEST(append_then_previous_returns_appended);
-    TEST(append_then_next_returns_null);
-    TEST(hits_null_at_top);
-    TEST(navigate_to_correct_item);
-    TEST(append_previous_item);
-}
diff --git a/test_prof_history.c b/test_prof_history.c
index 6b42a160..69028609 100644
--- a/test_prof_history.c
+++ b/test_prof_history.c
@@ -2,20 +2,20 @@
 #include <head-unit.h>
 #include "prof_history.h"
 
-void previous_on_empty_returns_current(void)
+void previous_on_empty_returns_null(void)
 {
     PHistory history = p_history_new(10);
     char *item = p_history_previous(history, "inp");
 
-    assert_string_equals("inp", item);
+    assert_is_null(item);
 }
 
-void next_on_empty_returns_current(void)
+void next_on_empty_returns_null(void)
 {
     PHistory history = p_history_new(10);
     char *item = p_history_next(history, "inp");
 
-    assert_string_equals("inp", item);
+    assert_is_null(item);
 }
 
 void previous_once_returns_last(void)
@@ -105,11 +105,103 @@ void prev_with_val_then_next_twice_returns_val(void)
     assert_string_equals("Oioi", item3);
 }
 
+void navigate_then_append_new(void)
+{
+    PHistory history = p_history_new(10);
+    p_history_append(history, "Hello");
+    p_history_append(history, "again");
+    p_history_append(history, "testing");
+    p_history_append(history, "history");
+    p_history_append(history, "append");
+
+    char *item1 = p_history_previous(history, "new text");
+    assert_string_equals("append", item1);
+
+    char *item2 = p_history_previous(history, item1);
+    assert_string_equals("history", item2);
+
+    char *item3 = p_history_previous(history, item2);
+    assert_string_equals("testing", item3);
+
+    char *item4 = p_history_next(history, item3);
+    assert_string_equals("history", item4);
+
+    char *item5 = p_history_next(history, item4);
+    assert_string_equals("append", item5);
+    
+    char *item6 = p_history_next(history, item5);
+    assert_string_equals("new text", item6);
+}
+
+void edit_item_mid_history(void)
+{
+    PHistory history = p_history_new(10);
+    p_history_append(history, "Hello");
+    p_history_append(history, "again");
+    p_history_append(history, "testing");
+    p_history_append(history, "history");
+    p_history_append(history, "append");
+
+    char *item1 = p_history_previous(history, "new item");
+    assert_string_equals("append", item1);
+    
+    char *item2 = p_history_previous(history, item1);
+    assert_string_equals("history", item2);
+
+    char *item3 = p_history_previous(history, item2);
+    assert_string_equals("testing", item3);
+    
+    char *item4 = p_history_previous(history, "EDITED");
+    assert_string_equals("again", item4);   
+    
+    char *item5 = p_history_previous(history, item4);
+    assert_string_equals("Hello", item5);
+
+    char *item6 = p_history_next(history, item5);
+    assert_string_equals("again", item6);
+    
+    char *item7 = p_history_next(history, item6);
+    assert_string_equals("EDITED", item7);
+
+    char *item8 = p_history_next(history, item7);
+    assert_string_equals("history", item8);
+
+    char *item9 = p_history_next(history, item8);
+    assert_string_equals("append", item9);
+
+    char *item10 = p_history_next(history, item9);
+    assert_string_equals("new item", item10);
+}
+
+void edit_previous_and_append(void)
+{
+    PHistory history = p_history_new(10);
+    p_history_append(history, "Hello");
+    p_history_append(history, "again");
+    p_history_append(history, "testing");
+    p_history_append(history, "history");
+    p_history_append(history, "append");
+
+    char *item1 = p_history_previous(history, "new item");
+    assert_string_equals("append", item1);
+    
+    char *item2 = p_history_previous(history, item1);
+    assert_string_equals("history", item2);
+
+    char *item3 = p_history_previous(history, item2);
+    assert_string_equals("testing", item3);
+    
+    p_history_append(history, "EDITED");
+
+    char *item4 = p_history_previous(history, NULL);
+    assert_string_equals("EDITED", item4);
+}
+
 void register_prof_history_tests(void)
 {
     TEST_MODULE("prof_history tests");
-    TEST(previous_on_empty_returns_current);
-    TEST(next_on_empty_returns_current);
+    TEST(previous_on_empty_returns_null);
+    TEST(next_on_empty_returns_null);
     TEST(previous_once_returns_last);
     TEST(previous_twice_when_one_returns_first);
     TEST(previous_always_stops_at_first);
@@ -117,4 +209,7 @@ void register_prof_history_tests(void)
     TEST(prev_then_next_returns_empty);
     TEST(prev_with_val_then_next_returns_val);
     TEST(prev_with_val_then_next_twice_returns_val);
+    TEST(navigate_then_append_new);
+    TEST(edit_item_mid_history);
+    TEST(edit_previous_and_append);
 }
diff --git a/testsuite.c b/testsuite.c
index 7a6ab3b2..e6eb6d0b 100644
--- a/testsuite.c
+++ b/testsuite.c
@@ -3,7 +3,6 @@
 
 int main(void)
 {
-    register_history_tests();
     register_prof_history_tests();
     register_contact_list_tests();
     register_util_tests();
diff --git a/testsuite.h b/testsuite.h
index 90a2d34b..410b3e47 100644
--- a/testsuite.h
+++ b/testsuite.h
@@ -1,7 +1,6 @@
 #ifndef TESTSUITE_H
 #define TESTSUITE_H
 
-void register_history_tests(void);
 void register_prof_history_tests(void);
 void register_contact_list_tests(void);
 void register_util_tests(void);