[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lost] [Patch] readline: add_history()



Dieser Patch fügt readline eine einfache History hinzu, die von der Shell benutzt wird.
Index: include/readline/history.h
===================================================================
--- include/readline/history.h	(Revision 0)
+++ include/readline/history.h	(Revision 0)
@@ -0,0 +1,43 @@
+/*  
+ * Copyright (c) 2007 The LOST Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the LOST Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the LOST Project
+ *     and its contributors.
+ * 4. Neither the name of the LOST Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _READLINE_HISTORY_H_
+#define _READLINE_HISTORY_H_
+
+/**
+ * Nimmt eine Zeile in die readline-History auf
+ */
+void add_history(char* line);
+
+#endif

Eigenschaftsänderungen: include/readline/history.h
___________________________________________________________________
Name: svn:eol-style
   + native

Index: lib/readline.c
===================================================================
--- lib/readline.c	(Revision 671)
+++ lib/readline.c	(Arbeitskopie)
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
+#include <collections.h>
 
 #include <readline/readline.h>
 
@@ -53,13 +54,28 @@
 #define KEY_INS 82
 #define KEY_DEL 83
 
+static list_t* history = NULL;
+
 /**
  * Einzelnes Zeichen von der Tastatur einlesen
+ *
+ * @return Das eingelesene Zeichen oder NULL, wenn das Ende der Eingabedatei
+ * erreicht ist.
  */
 static char keyboard_read_char(void)
 {
     char c = 0;
-    while (!fread(&c, 1, 1, stdin));
+    
+    while (!fread(&c, 1, 1, stdin)) {
+        // FIXME Das gehoert eigentlich rein, geht aber nicht, weil vterm ein EOF
+        // liefert, wenn der Eingabepuffer gerade leer ist.
+        /*
+        if (feof(stdin)) {
+            return 0;
+        }
+        */
+    }
+
     return c;
 }
 
@@ -109,9 +125,18 @@
  */
 char* readline(const char* prompt)
 {
+    // FIXME Das gehoert eigentlich rein, geht aber nicht, weil vterm ein EOF
+    // liefert, wenn der Eingabepuffer gerade leer ist.
+    /*
+    if (feof(stdin)) {
+        return NULL;
+    }
+    */
+
     char* buffer = malloc(BUFFER_SIZE);
     int pos, size;
     bool enter = FALSE;
+    int history_pos = -1;
 
     printf("%s", prompt);
     fflush(stdout);
@@ -126,6 +151,14 @@
             case '\0':
                 c = keyboard_read_char();
                 switch (c) {
+                    // Ende der Eingabedatei
+                    case '\0':
+                        enter = TRUE;  
+                        
+                        printf("\r\n");
+                        fflush(stdout);
+                        break;
+
                     // Links
                     case KEY_LEFT:
                         if (pos > 0) {
@@ -143,6 +176,40 @@
                             pos++;
                         }
                         break;
+
+                    // Hoch/Runter
+                    case KEY_UP:
+                    case KEY_DOWN:
+                        if (c == KEY_UP) {
+                            if (history_pos < (int) list_size(history) - 1) {
+                                history_pos++;
+                            } else {
+                                break;
+                            }
+                        } else {
+                            if (history_pos > -1) {
+                                history_pos--;
+                            } else {
+                                break;
+                            }
+                        }
+
+                        memset(buffer, 0, BUFFER_SIZE);
+                        if (history_pos > -1) {
+                            strncpy(buffer, 
+                                list_get_element_at(history, history_pos), 
+                                BUFFER_SIZE - 1);
+                        }
+                        
+                        char* format;
+                        asprintf(&format, "\033[%dD", pos);
+                        printf("%s\033[K%s", format, buffer);
+                        free(format);
+                        fflush(stdout);
+
+                        pos = size = strlen(buffer);
+
+                        break;
             
                     // Entfernen
                     case KEY_DEL:
@@ -215,3 +282,21 @@
 
     return realloc(buffer, strlen(buffer) + 1);
 }
+
+/**
+ * Fuegt eine Zeile der History hinzu
+ */
+void add_history(char* line)
+{
+    char* copy;
+    
+    if (history == NULL) {
+        history = list_create();
+    }
+
+    copy = malloc(strlen(line) + 1);
+    if (copy) {
+        strcpy(copy, line);
+        list_push(history, copy);
+    }
+}
Index: c/shell/shell.c
===================================================================
--- c/shell/shell.c	(Revision 671)
+++ c/shell/shell.c	(Arbeitskopie)
@@ -44,8 +44,10 @@
 #include "dir.h"
 #include "lostio.h"
 #include "config.h"
+#include <sleep.h>
 
 #include <readline/readline.h>
+#include <readline/history.h>
 
 #define _USE_START_
 #include "init.h"
@@ -174,24 +176,9 @@
     return 0;
 }
 
-///Einzelnes Zeichen von der Tastatur einlesen
-char keyboard_read_char()
-{
-    char c = 0;
-    while((c == 0) || (c == '\t'))
-    {
-        fread(&c, 1, 1, stdin);
-    }
-    return c;
-}
-
-
 ///Prompt anzeigen und Shellkommando von der Tastatur einlesen
 void shell_read_command()
 {
-    int i;
-    char c;
-
     char* cwd = getcwd(NULL, 0);
     char* prompt;
     char* input;
@@ -199,9 +186,18 @@
     asprintf(&prompt, "%s # ", cwd);
 
     input = readline(prompt);
-    strncpy(shell_command_buffer, input, COMMAND_BUFFER_SIZE);
-    free(input);
+    if (input) {
+        if (*input) {
+            add_history(input);
+        }
 
+        strncpy(shell_command_buffer, input, COMMAND_BUFFER_SIZE);
+        free(input);
+    } else {
+        // Bei EOF wird die Shell beendet
+        strcpy(shell_command_buffer, "exit");
+    }
+
     free(prompt);
     free(cwd);
 }