about summary refs log tree commit diff stats
path: root/prof_history.c
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-04-30 19:52:56 +0100
committerJames Booth <boothj5@gmail.com>2012-04-30 19:52:56 +0100
commit4531aebd291186e9dd49fb2ec1f1b9b96a4ed23f (patch)
tree73132cb006da80e2cde09537ac379c99deba9aae /prof_history.c
parentf21cb52ab025cfe1bc90226d7bb433fc775d390e (diff)
downloadprofani-tty-4531aebd291186e9dd49fb2ec1f1b9b96a4ed23f.tar.gz
More work on history
Diffstat (limited to 'prof_history.c')
-rw-r--r--prof_history.c105
1 files changed, 75 insertions, 30 deletions
diff --git a/prof_history.c b/prof_history.c
index 24213140..e896ac15 100644
--- a/prof_history.c
+++ b/prof_history.c
@@ -32,17 +32,26 @@ PHistory p_history_new(unsigned int size)
 
 void p_history_append(PHistory history, char *item)
 {
-    char *copied = strdup(item);
+    char *copied = "";
+    if (item != NULL) {
+        copied = strdup(item);
+    }
 
-    // if not editing history (no session)
+    // if no history yet, just add the item
+    if (history->items == NULL) {
+        history->items = g_list_append(history->items, copied);
+        return;
+    }
+        
+    // if not editing history (no session started)
     if (history->session == NULL) {
         
-        // if already at max size
+        // lose first element if hit max size
         if (g_list_length(history->items) == history->max_size) {
 
             // remove first element
             GList *first = g_list_first(history->items);
-            const char *first_item = (char *) first->data;
+            char *first_item = first->data;
             history->items = g_list_remove(history->items, first_item);
         }
     
@@ -51,19 +60,23 @@ void p_history_append(PHistory history, char *item)
 
     // if editing history (session exists with possible changes)
     } else {
-        
-        // if adding a new element, copy the session over the history
-        if (history->sess_curr == history->sess_new) {
+
+        // if adding a new item, copy the session over the history
+        if ((history->sess_new != NULL) && 
+                (history->sess_curr == history->sess_new)) {
             _replace_history_with_session(history);
 
         // otherwise, adding edited history item
         } else {
-            // remove the new item, from the session
-            history->session = g_list_reverse(history->session);
-            GList *first = g_list_first(history->session);
-            const char *first_item = (char *) first->data;
-            history->session = g_list_remove(history->session, first_item);
-            history->session = g_list_reverse(history->session);
+            
+            // 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 sess_curr to the end of the session
             char *new_data = strdup(history->sess_curr->data);
@@ -99,45 +112,77 @@ static void _replace_history_with_session(PHistory history)
 
 char * p_history_previous(PHistory history, char *item)
 {
+    // no history
     if (history->items == NULL) {
         return item;
     }
 
+    char *copied = "";
+    if (item != NULL) {
+        copied = strdup(item);
+    }
+    
+    // no session, create one
     if (history->session == NULL) {
         history->session = g_list_copy(history->items);
         history->sess_curr = g_list_last(history->session);
+        history->items_curr = g_list_last(history->items);
+        
+        // add the new item including empty string
+        g_list_append(history->session, copied);
+        history->sess_new = g_list_last(history->session);
+
+        char *result = strdup(history->sess_curr->data);
+        return result;
+
+    // session exists
     } else {
+        // update the currently pointed to item with passed data
+        history->sess_curr->data = copied;
+        
+        // move to previous
         history->sess_curr = g_list_previous(history->sess_curr);
-    }
+        history->items_curr = g_list_previous(history->items_curr);
 
-    // set to first if rolled over beginning
-    if (history->sess_curr == NULL) {
-        history->sess_curr = g_list_first(history->session);
+        // set to first if rolled over beginning
+        if (history->sess_curr == NULL) {
+            history->sess_curr = g_list_first(history->session);
+            history->items_curr = g_list_first(history->items);
+        }
     }
 
-    char *curr = history->sess_curr->data;
-    char *result = malloc((strlen(curr) + 1) * sizeof(char));
-    strcpy(result, curr);
-
+    char *result = strdup(history->sess_curr->data);
     return result;
 }
 
 char * p_history_next(PHistory history, char *item)
 {
-    if (history->session == NULL) {
-        return NULL;
-    } else {
-        history->sess_curr = g_list_next(history->sess_curr);
+
+    // no history, or no session, return item
+    if ((history->items == NULL) || (history->session == NULL)) {
+        return item;
+    }
+
+    char *copied = "";
+    if (item != NULL) {
+        copied = strdup(item);
     }
 
-    // set to last if rolled over end
+    // session exists
+    
+    // update the currently pointed to item with passed data
+    history->sess_curr->data = copied;
+    
+    // move to next
+    history->sess_curr = g_list_next(history->sess_curr);
+    history->items_curr = g_list_next(history->items_curr);
+
+    // set to last if rolled over beginning
     if (history->sess_curr == NULL) {
         history->sess_curr = g_list_last(history->session);
+        history->items_curr = NULL;
     }
 
-    char *curr = history->sess_curr->data;
-    char *result = malloc((strlen(curr) + 1) * sizeof(char));
-    strcpy(result, curr);
-
+    char *result = strdup(history->sess_curr->data);
     return result;
 }