hi, I add editline into openipmi as a library, and link it into openipmish.

now, openipmish can support history commands, by up and down arrow key.

Corey:
1, the attachment is patch under directory OpenIPMI/cmdlang.
2, I can't attach the editline tar ball in this mail(too big). Please download the tar ball from http://www.thrysoee.dk/editline/libedit-20060103-2.9.tar.gz  , and put the editline source code into OpenIPMI/libedit, for I reference this path by Makefile.am in OpenIPMI/cmdlang.
2, I have to trouble you to add the libedit into OpenIPMI automake and autoconf scripts.

Bugs:
does not support Ctrl+l to perform redisplay, for editline does not support keymap modification, and I can't register a hook for Ctrl+l.

ToDo:
1, add two commands for openipmish (clear, and history), if necessary.
2, add commands auto completing if necessary.

Best regards.

Coly
Index: Makefile.am
===================================================================
RCS file: /cvsroot/openipmi/OpenIPMI/cmdlang/Makefile.am,v
retrieving revision 1.20
diff -u -r1.20 Makefile.am
--- Makefile.am	7 Feb 2006 01:03:35 -0000	1.20
+++ Makefile.am	10 Feb 2006 03:59:16 -0000
@@ -10,7 +10,7 @@
 VERSION_AGE = $(wordlist 2, 2, $(SPACE_VERSION))
 LD_VERSION = $(VERSION_CURRENT):$(VERSION_REVISION):$(VERSION_AGE)
 
-AM_CFLAGS = -Wall -I$(top_srcdir)/include -DIPMI_CHECK_LOCKS $(GLIB_CFLAGS)
+AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_srcdir)/libedit/src -DIPMI_CHECK_LOCKS $(GLIB_CFLAGS)
 
 lib_LTLIBRARIES = libOpenIPMIcmdlang.la
 
@@ -30,6 +30,7 @@
 		$(top_builddir)/utils/libOpenIPMIutils.la \
 		$(top_builddir)/lib/libOpenIPMI.la \
 		$(top_builddir)/unix/libOpenIPMIposix.la \
+		$(top_builddir)/libedit/src/libedit.la \
 		$(SNMPLIBS) $(GLIB_LIB) $(GLIB_LIBS) $(OPENSSLLIBS) \
 		$(GDBM_LIB)
 
@@ -38,4 +39,5 @@
 # We need to make a link from ipmish to openipmish for backwards
 # compatability.
 install-data-local:
-	$(LN_S) openipmish $(DESTDIR)$(bindir)/ipmish
\ No newline at end of file
+	$(LN_S) openipmish $(DESTDIR)$(bindir)/ipmish
+
Index: ipmish.c
===================================================================
RCS file: /cvsroot/openipmi/OpenIPMI/cmdlang/ipmish.c,v
retrieving revision 1.26
diff -u -r1.26 ipmish.c
--- ipmish.c	10 Jan 2006 22:20:53 -0000	1.26
+++ ipmish.c	10 Feb 2006 03:59:17 -0000
@@ -47,6 +47,7 @@
 #include <OpenIPMI/ipmi_glib.h>
 #include <OpenIPMI/ipmi_cmdlang.h>
 #include <OpenIPMI/ipmi_debug.h>
+#include <editline/readline.h>
 
 #ifdef HAVE_GLIB
 #include <glib.h>
@@ -78,9 +79,6 @@
 static int done = 0;
 static int evcount = 0;
 static int handling_input = 0;
-static char *line_buffer;
-static int  line_buffer_max = 0;
-static int  line_buffer_pos = 0;
 static int cmd_redisp = 1;
 
 static void user_input_ready(int fd, void *data, os_hnd_fd_id_t *id);
@@ -93,8 +91,7 @@
     if (force)
 	redisp = 1;
     if (!done && handling_input && redisp) {
-	fputs("> ", stdout);
-	fwrite(line_buffer, 1, line_buffer_pos, stdout);
+	rl_redisplay();
 	fflush(stdout);
     }
 }
@@ -607,105 +604,41 @@
 static void
 user_input_ready(int fd, void *data, os_hnd_fd_id_t *id)
 {
-    ipmi_cmdlang_t *info = data;
-    out_data_t *out_data = info->user_data;
-    char rc;
-    int  count;
-    int  i;
+    rl_callback_read_char();
+}
+
+static void
+rl_ipmish_cb_handler(char *cmdline)
+{
+    char *expansion = NULL;
+    int result;
 
-    count = read(fd, &rc, 1);
-    if (count <= 0) {
+    if (cmdline == NULL) {
 	done = 1;
 	evcount = 1; /* Force a newline */
 	return;
     }
-
-    switch(rc) {
-    case 0x04: /* ^d */
-	if (line_buffer_pos == 0) {
-	    done = 1;
-	    evcount = 1; /* Force a newline */
-	}
-	break;
-
-    case 12: /* ^l */
-	fputc('\n', out_data->stream);
-	redraw_cmdline(1);
-	break;
-
-    case '\r': case '\n':
-	fputc(rc, out_data->stream);
-	if (line_buffer) {
-	    line_buffer[line_buffer_pos] = '\0';
-	    for (i=0; isspace(line_buffer[i]); i++)
-		;
-	    /* Ignore blank lines. */
-	    if (line_buffer[i] != '\0') {
-		/* Turn off input processing. */
-		disable_term_fd(info);
-
-		cmdlang.err = 0;
-		cmdlang.errstr = NULL;
-		cmdlang.errstr_dynalloc = 0;
-		cmdlang.location = NULL;
-		handling_input = 0;
-		line_buffer_pos = 0;
-		ipmi_cmdlang_handle(&cmdlang, line_buffer);
-	    } else {
-		fputs("> ", out_data->stream);
-	    }
-	} else {
-	    fputs("> ", out_data->stream);
-	}
-	break;
-
-    case 0x7f: /* delete */
-    case '\b': /* backspace */
-	if (line_buffer_pos > 0) {
-	    line_buffer_pos--;
-	    fputs("\b \b", out_data->stream);
-	}
-	break;
-
-    default:
-	if (line_buffer_pos >= line_buffer_max) {
-	    char *new_line = ipmi_mem_alloc(line_buffer_max+10+1);
-	    if (!new_line)
-		break;
-	    line_buffer_max += 10;
-	    if (line_buffer) {
-		memcpy(new_line, line_buffer, line_buffer_pos);
-		ipmi_mem_free(line_buffer);
-	    }
-	    line_buffer = new_line;
-	}
-	line_buffer[line_buffer_pos] = rc;
-	line_buffer_pos++;
-	fputc(rc, out_data->stream);
-	break;
+    result = history_expand(cmdline, &expansion);
+    if (result < 0 || result == 2) {
+	fprintf(stderr, "%s\n", expansion);
+    } else if (expansion && strlen(expansion)){
+	cmdlang.err = 0;
+	cmdlang.errstr = NULL;
+	cmdlang.errstr_dynalloc = 0;
+	cmdlang.location = NULL;
+	handling_input = 0;
+	add_history(expansion);
+	ipmi_cmdlang_handle(&cmdlang, expansion);
     }
-
-    fflush(out_data->stream);
+    if (expansion)
+	ipmi_mem_free(expansion);
 }
 
-static int term_setup;
-struct termios old_termios;
-
 static void
 cleanup_term(void)
 {
-    if (line_buffer) {
-	ipmi_mem_free(line_buffer);
-	line_buffer = NULL;
-    }
+    rl_callback_handler_remove();
     disable_term_fd(&cmdlang);
-
-    if (!term_setup)
-	return;
-
-    tcsetattr(0, TCSADRAIN, &old_termios);
-    tcdrain(0);
-    term_setup = 0;
 }
 
 static void cleanup_sig(int sig);
@@ -713,20 +646,14 @@
 static void
 setup_term(os_handler_t *os_hnd)
 {
-    struct termios new_termios;
-
-    tcgetattr(0, &old_termios);
-    new_termios = old_termios;
-    new_termios.c_lflag &= ~(ICANON|ECHO);
-    tcsetattr(0, TCSADRAIN, &new_termios);
-    term_setup = 1;
-
     signal(SIGINT, cleanup_sig);
     signal(SIGPIPE, cleanup_sig);
     signal(SIGUSR1, cleanup_sig);
     signal(SIGUSR2, cleanup_sig);
     signal(SIGPWR, cleanup_sig);
 
+    stifle_history(500);
+    rl_callback_handler_install("> ", rl_ipmish_cb_handler);
     lout_data.stream = stdout;
 
     cmdlang.os_hnd = os_hnd;
@@ -809,6 +736,7 @@
     read_nest++;
     saved_done_ptr = done_ptr;
 
+    /* not record the file's commands into history */
     while (fgets(cmdline, sizeof(cmdline), s)) {
 	my_out_data.stream = stdout;
 	my_out_data.indent = 0;
@@ -816,6 +744,7 @@
 	cdone = 0;
 	done_ptr = &cdone;
 	printf("> %s", cmdline);
+	fflush(stdout);
 	ipmi_cmdlang_handle(&my_cmdlang, cmdline);
 	while (!cdone)
 	    cmdlang->os_hnd->perform_one_op(cmdlang->os_hnd, NULL);
@@ -1097,8 +1026,9 @@
 	read_nest = 1;
 	execs = e->next;
 	printf("> %s\n", e->str);
+	fflush(stdout);
 	done_ptr = &cdone;
-	ipmi_cmdlang_handle(&cmdlang, e->str);
+	rl_ipmish_cb_handler(e->str);
 	while (!cdone)
 	    os_hnd->perform_one_op(os_hnd, NULL);
 	done_ptr = NULL;
@@ -1106,7 +1036,6 @@
 	read_nest = 0;
     }
 
-    printf("> ");
     fflush(stdout);
 
     handling_input = 1;
@@ -1131,8 +1060,11 @@
 
     os_hnd->free_os_handler(os_hnd);
 
+    /* remove the prompt which editline printed */
+    printf("\b\b  \b\b");
     if (evcount)
 	printf("\n");
+    fflush(stdout);
 
     if (rv)
 	return 1;

Reply via email to