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

[elk] readline patch fixed



dear sam,

i just fixed a small bug in the readline extension regarding GC_Link
(wrong object was linked)...

all the best,

martin

diff -rpuN elk-trunk/configure.ac elk-trunk-readline/configure.ac
--- elk-trunk/configure.ac	2004-01-28 15:36:29.000000000 +0100
+++ elk-trunk-readline/configure.ac	2004-03-01 20:02:30.000000000 +0100
@@ -80,6 +80,39 @@ AC_EGREP_HEADER(environ, unistd.h,
   AC_DEFINE(ENVIRON_IN_UNISTD_H, 1, Define if <unistd.h> defines environ)],
  [AC_MSG_RESULT(no)])
 
+# check for libedit/libreadline
+AC_ARG_ENABLE(gnu-readline,
+  [  --enable-gnu-readline   force gnu readline support (GPL license!!!)
+],,
+  enable_gnu_readline=no)
+
+if test "$enable_gnu_readline" = no; then
+  AC_CHECK_HEADERS(editline/readline.h editline/history.h)
+  AC_CHECK_LIB(edit, readline,
+  [ac_cv_my_have_readline=yes
+  RL_LIBS="-ledit"],
+  [ac_cv_my_have_readline=no])
+
+  # check for alternative readline replacement
+#  if test "$ac_cv_my_have_readline" = no; then
+#    AC_CHECK_HEADERS(readline.h history.h)
+#    AC_CHECK_LIB(editline, readline,
+#    [ac_cv_my_have_readline=yes
+#    RL_LIBS="-leditline"],
+#    [ac_cv_my_have_readline=no])
+#  fi
+
+else
+  AC_CHECK_HEADERS(readline/readline.h readline/history.h)
+  AC_CHECK_LIB(readline, readline,
+  [ac_cv_my_have_readline=yes
+  RL_LIBS="-lreadline"],
+  [ac_cv_my_have_readline=no])
+fi
+
+AM_CONDITIONAL(HAVE_READLINE, test "${ac_cv_my_have_readline}" = "yes")
+AC_SUBST(RL_LIBS)
+
 # Does the system support the vprintf library function?  If not,
 # availability of the (non-portable) _doprnt function is assumed.
 AC_CHECK_FUNCS(vprintf)
@@ -593,6 +626,7 @@ AC_OUTPUT([
   lib/xwidgets/Makefile
   lib/xwidgets/xaw/Makefile
   lib/xwidgets/motif/Makefile
+  lib/readline/Makefile
   scm/Makefile
   src/Makefile
 
diff -rpuN elk-trunk/lib/Makefile.am elk-trunk-readline/lib/Makefile.am
--- elk-trunk/lib/Makefile.am	2004-02-03 17:47:28.000000000 +0100
+++ elk-trunk-readline/lib/Makefile.am	2004-03-01 20:02:30.000000000 +0100
@@ -1 +1 @@
-SUBDIRS = misc unix xlib xwidgets
+SUBDIRS = misc unix xlib xwidgets readline
diff -rpuN elk-trunk/lib/readline/Makefile.am elk-trunk-readline/lib/readline/Makefile.am
--- elk-trunk/lib/readline/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ elk-trunk-readline/lib/readline/Makefile.am	2004-03-01 20:02:30.000000000 +0100
@@ -0,0 +1,19 @@
+NULL = 
+
+EXTRA_DIST =
+
+pkglib_LTLIBRARIES = $(readline_la)
+
+if HAVE_READLINE
+readline_la = readline.la
+endif
+
+readline_la_SOURCES = \
+	readline.c \
+	completion.c \
+	$(NULL)
+readline_la_LDFLAGS = -module -avoid-version -no-undefined
+readline_la_LIBADD = $(top_builddir)/src/libelk.la @RL_LIBS@
+
+extensions_HEADERS = readline.h
+extensionsdir = $(pkgincludedir)/extensions
diff -rpuN elk-trunk/lib/readline/completion.c elk-trunk-readline/lib/readline/completion.c
--- elk-trunk/lib/readline/completion.c	1970-01-01 01:00:00.000000000 +0100
+++ elk-trunk-readline/lib/readline/completion.c	2004-03-02 09:16:48.000000000 +0100
@@ -0,0 +1,98 @@
+/* completion.c
+ *
+ * $Id$
+ *
+ * Copyright 2004 Martin Rumori <martin@rumori.de>, Berlin
+ *
+ * This software was derived from Elk 1.2, which was Copyright 1987, 1988,
+ * 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
+ * by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
+ * between TELES and Nixdorf Microprocessor Engineering, Berlin).
+ *
+ * Oliver Laumann, TELES GmbH, Nixdorf Computer AG, Sam Hocevar and
+ * Martin Rumori, as co- owners or individual owners of copyright in
+ * this software, grant to any person or company a worldwide, royalty
+ * free, license to
+ *
+ *    i) copy this software,
+ *   ii) prepare derivative works based on this software,
+ *  iii) distribute copies of this software or derivative works,
+ *   iv) perform this software, or
+ *    v) display this software,
+ *
+ * provided that this notice is not removed and that neither Oliver Laumann
+ * nor Teles nor Nixdorf are deemed to have made any representations as to
+ * the suitability of this software for any purpose nor are held responsible
+ * for any defects of this software.
+ *
+ * THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "readline.h"
+
+static int _erl_maxcompl;
+static char **_erl_completions;
+
+
+static void
+erl_calc_completions (char *text)
+{
+  Object oblist, bucket;
+  char *symname;
+  int iter = 0, textlen = strlen(text);
+
+  for (oblist = P_Oblist(); ! Nullp(oblist); oblist = Cdr(oblist))
+    {
+      for (bucket = Car(oblist); ! Nullp(bucket); bucket = Cdr(bucket))
+	{
+	  if (! Truep(P_Boundp(Car(bucket)))) 
+	    {
+	      continue;
+	    }
+	  symname = Get_Strsym(Car(bucket));
+        
+	  if (! strncmp(text, symname, textlen))
+	    {
+	      *(_erl_completions + iter) = strdup(symname);
+	      ++iter;
+
+	      if (iter >= _erl_maxcompl)
+		{
+		  _erl_maxcompl *= 2;
+		  _erl_completions = realloc(_erl_completions, _erl_maxcompl * sizeof(char *));
+		}
+	    }
+	}
+    }
+  *(_erl_completions + iter) = NULL;
+}
+
+
+static char *
+erl_complete (char *text, int state)
+{
+  if (! state)
+    {
+      erl_calc_completions (text);
+    }
+
+  return *(_erl_completions + state);
+}
+
+
+void
+elk_init_readline_completion (void)
+{
+  _erl_maxcompl = 256;
+  _erl_completions = (char **)malloc(_erl_maxcompl * sizeof(char *));
+  rl_completion_entry_function = (void *)erl_complete;
+}
+
+
+void
+elk_finit_readline_completion (void)
+{
+  free(_erl_completions);
+}
+
+/* EOF */
diff -rpuN elk-trunk/lib/readline/readline.c elk-trunk-readline/lib/readline/readline.c
--- elk-trunk/lib/readline/readline.c	1970-01-01 01:00:00.000000000 +0100
+++ elk-trunk-readline/lib/readline/readline.c	2004-03-02 09:16:48.000000000 +0100
@@ -0,0 +1,183 @@
+/* readline.c
+ *
+ * $Id$
+ *
+ * Copyright 2004 Martin Rumori <martin@rumori.de>, Berlin
+ *
+ * This software was derived from Elk 1.2, which was Copyright 1987, 1988,
+ * 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
+ * by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
+ * between TELES and Nixdorf Microprocessor Engineering, Berlin).
+ *
+ * Oliver Laumann, TELES GmbH, Nixdorf Computer AG, Sam Hocevar and
+ * Martin Rumori, as co- owners or individual owners of copyright in
+ * this software, grant to any person or company a worldwide, royalty
+ * free, license to
+ *
+ *    i) copy this software,
+ *   ii) prepare derivative works based on this software,
+ *  iii) distribute copies of this software or derivative works,
+ *   iv) perform this software, or
+ *    v) display this software,
+ *
+ * provided that this notice is not removed and that neither Oliver Laumann
+ * nor Teles nor Nixdorf are deemed to have made any representations as to
+ * the suitability of this software for any purpose nor are held responsible
+ * for any defects of this software.
+ *
+ * THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "readline.h"
+
+
+static char *_prompt, *_cont_prompt;
+
+
+static int
+erl_check_line (const char *line, int first)
+{
+  static int comment = 0, string = 0, braces = 0;
+  const char *c = line;
+
+  if (first)
+    { /* reset static paren and string memory */
+      comment = string = braces = 0;
+    }
+
+  while (c && *c)
+    {
+      if (comment && *c == '\n')
+	{
+	  comment = 0;
+	}
+      else if (string && *c == '"')
+	{
+	  string = 0;
+	}
+      else if (*c == ';')
+	{
+	  comment = 1;
+	}
+      else if (*c == '"')
+	{
+	  string = 1;
+	}
+      else if (*c == '(')
+	{
+	  ++braces;
+	}
+      else if (*c == ')')
+	{
+	  --braces;
+	}
+      ++c;
+    } /* while ... */
+
+  return (braces <= 0);
+}
+
+
+static Object
+P_Readline_Read (void)
+{
+  char *expr, *line, *prompt = _prompt;
+  int bufsize = 1024, exprlen = 0, first = 1, llen;
+  Object ret, port;
+  GC_Node;
+
+  /* alloc memory for expression */
+  expr = malloc(bufsize * sizeof(char));
+  *expr = '\0';
+
+  /* let's go */
+  while (1)
+    {
+      if (NULL == (line = readline(prompt)))
+	{
+	  Primitive_Error("error while reading line");
+	}
+      if (! (llen = strlen(line)))
+	{
+	  continue;
+	}
+      if ((exprlen += llen + 1) >= bufsize)
+	{
+	  bufsize *= 2;
+	  expr = realloc(expr, bufsize * sizeof(char));
+	}
+      strcat(expr, line);
+
+      if (erl_check_line(line, first))
+	{
+	  free(line);
+	  --exprlen; /* correct missing '\n' when last line */
+	  break;
+	}
+
+      if (first)
+	{
+	  first = 0;
+	  prompt = _cont_prompt;
+	}
+
+      strcat(expr, "\n");
+      free(line);
+    } /* while (1) */
+
+  /* add to history */
+  add_history(expr);
+
+  /* give the whole stuff to elk via a string port */
+  port = P_Open_Input_String(Make_String(expr, exprlen));
+  GC_Link(port);
+  ret = General_Read(port, 0);
+  GC_Unlink;
+ (void)P_Close_Input_Port(port);
+ free(expr);
+
+ return ret;
+}
+
+
+static Object
+P_Readline_Add_History (Object add)
+{
+  add_history(Get_String(add));
+
+  return True;
+}
+
+
+static Object
+P_Readline_Set_Prompt (Object prompt)
+{
+  free(_prompt);
+  _prompt = strdup(Get_String(prompt));
+
+  return True;
+}
+
+
+void
+elk_init_readline_readline (void)
+{
+  _prompt = strdup("> ");
+  _cont_prompt = "> ";
+  using_history();
+
+  Def_Prim(P_Readline_Read,		"readline-read",	0, 0,	EVAL);
+  Def_Prim(P_Readline_Add_History,	"readline-add-history",	1, 1,	EVAL);
+  Def_Prim(P_Readline_Set_Prompt,	"readline-set-prompt",	1, 1,	EVAL);
+
+  P_Provide(Intern("readline.la"));
+}
+
+
+void
+elk_finit_readline_readline (void)
+{
+  free(_prompt);
+}
+
+/* EOF */
diff -rpuN elk-trunk/lib/readline/readline.h elk-trunk-readline/lib/readline/readline.h
--- elk-trunk/lib/readline/readline.h	1970-01-01 01:00:00.000000000 +0100
+++ elk-trunk-readline/lib/readline/readline.h	2004-03-01 20:02:30.000000000 +0100
@@ -0,0 +1,57 @@
+/* readline.h
+ *
+ * $Id$
+ *
+ * Copyright 2004 Martin Rumori <martin@rumori.de>, Berlin
+ *
+ * This software was derived from Elk 1.2, which was Copyright 1987, 1988,
+ * 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
+ * by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
+ * between TELES and Nixdorf Microprocessor Engineering, Berlin).
+ *
+ * Oliver Laumann, TELES GmbH, Nixdorf Computer AG, Sam Hocevar and
+ * Martin Rumori, as co- owners or individual owners of copyright in
+ * this software, grant to any person or company a worldwide, royalty
+ * free, license to
+ *
+ *    i) copy this software,
+ *   ii) prepare derivative works based on this software,
+ *  iii) distribute copies of this software or derivative works,
+ *   iv) perform this software, or
+ *    v) display this software,
+ *
+ * provided that this notice is not removed and that neither Oliver Laumann
+ * nor Teles nor Nixdorf are deemed to have made any representations as to
+ * the suitability of this software for any purpose nor are held responsible
+ * for any defects of this software.
+ *
+ * THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_EDITLINE_READLINE_H
+#include <editline/readline.h>
+#elif defined HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#endif
+
+#ifdef HAVE_EDITLINE_HISTORY_H
+#include <editline/history.h>
+#elif defined HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#endif
+
+#include "scheme.h"
+
+
+extern Object P_Readline_Read (void);
+extern Object P_Readline_Add_History (Object add);
+extern Object P_Readline_Set_Prompt (Object prompt);
+
+#define Def_Prim Define_Primitive
+
+/* EOF */
diff -rpuN elk-trunk/scm/Makefile.am elk-trunk-readline/scm/Makefile.am
--- elk-trunk/scm/Makefile.am	2004-01-28 15:36:12.000000000 +0100
+++ elk-trunk-readline/scm/Makefile.am	2004-03-01 20:02:30.000000000 +0100
@@ -24,6 +24,7 @@ SCM_FILES = \
 	toplevel.scm \
 	trace.scm \
 	unix.scm \
+	toplevel-readline.scm \
 	$(NULL)
 
 SCM_MAYBE = \
diff -rpuN elk-trunk/scm/toplevel-readline.scm elk-trunk-readline/scm/toplevel-readline.scm
--- elk-trunk/scm/toplevel-readline.scm	1970-01-01 01:00:00.000000000 +0100
+++ elk-trunk-readline/scm/toplevel-readline.scm	2004-03-01 20:02:30.000000000 +0100
@@ -0,0 +1,115 @@
+;;; -*-Scheme-*-
+;;;
+;;; Read-eval-print loop and error handler (readline extension support)
+
+
+(autoload 'pp 'pp.scm)
+(autoload 'apropos 'apropos.scm)
+(autoload 'sort 'qsort.scm)
+(autoload 'describe 'describe.scm)
+(autoload 'backtrace 'debug.scm)
+(autoload 'inspect 'debug.scm)
+
+(require 'readline.la)
+(define elk-prompt-base "> ")
+
+(define ?)
+(define ??)
+(define ???)
+(define !)
+(define !!)
+(define !!!)
+(define &)
+
+(define (rep-loop env)
+  (define input)
+  (define value)
+  (let loop ()
+    (set! ??? ??)
+    (set! ?? ?)
+    (set! ? &)
+    ;;; X Windows hack
+    (if (and (bound? 'display-flush-output) (bound? 'dpy) (display? dpy))
+	(display-flush-output dpy))
+    (if (> rep-level 0)
+	(readline-set-prompt (string-append
+			      (format #f "~a" rep-level)
+			      elk-prompt-base))
+	(readline-set-prompt elk-prompt-base))
+    (set! input (readline-read))
+    (set! & input)
+    (if (not (eof-object? input))
+	(begin
+	  (set! value (eval input env))
+	  (set! !!! !!)
+	  (set! !! !)
+	  (set! ! value)
+	  (write value)
+	  (newline)
+	  (loop)))))
+
+(define rep-frames)
+(define rep-level)
+
+(set! interrupt-handler
+  (lambda ()
+    (format #t "~%\7Interrupt!~%")
+    (let ((next-frame (car rep-frames)))
+      (next-frame #t))))
+
+(define-macro (push-frame control-point)
+  `(begin
+     (set! rep-frames (cons ,control-point rep-frames))
+     (set! rep-level (1+ rep-level))))
+
+(define-macro (pop-frame)
+  '(begin
+     (set! rep-frames (cdr rep-frames))
+     (set! rep-level (1- rep-level))))
+
+(define (error-print error-msg)
+  (format #t "~s: " (car error-msg))
+  (apply format `(#t ,@(cdr error-msg)))
+  (newline))
+
+(set! error-handler
+  (lambda error-msg
+    (error-print error-msg)
+    (let loop ((intr-level (enable-interrupts)))
+      (if (positive? intr-level)
+	  (loop (enable-interrupts))))
+    (let loop ()
+      (if (call-with-current-continuation
+	   (lambda (control-point)
+	     (push-frame control-point)
+	     (rep-loop (the-environment))
+	     #f))
+	  (begin
+	    (pop-frame)
+	    (loop))))
+    (newline)
+    (pop-frame)
+    (let ((next-frame (car rep-frames)))
+      (next-frame #t))))
+
+(define top-level-environment (the-environment))
+
+(define (top-level)
+  (let loop ()
+    ;;; Allow GC to free old rep-frames when we get here on "reset":
+    (set! rep-frames (list top-level-control-point))
+    (if (call-with-current-continuation
+	 (lambda (control-point)
+	   (set! rep-frames (list control-point))
+	   (set! top-level-control-point control-point)
+	   (set! rep-level 0)
+	   (rep-loop top-level-environment)
+	   #f))
+	(loop))))
+
+(define (the-top-level)
+  (top-level)
+  (newline)
+  (exit))
+
+(the-top-level)