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

[elk] configure for readline-extension



dear sam,

since we want to release the next version of our sound synthesis
system, we will package up a customized version of elk for that
purpose (containing all of our patches).

i added the ./configure support for the readline patch.  ./configure
now looks for BSD libedit, unless the user specifies
--enable-gnu-readline at the command line.  i prepared another
fallback solution if libedit is not found, but it is commented out
yet.  i didn't find the time to adopt libeditline to our needs.  for
the first step, it would be o.k. to disable the completion in that
case.

the new readline-patch is attached.

what about the lowercase filenames while (load )ing something?  is
this intended to have lower case filenames in all cases?  i'm just
wondering if it would be better to rename our scheme-library to
lowercase.  but the implications on case sensivite filesystems wasn't
yet solved, was it?

all the best,

martin


-- 
martinrumori (martin@rumori.de)
/* home is where your home directory is */
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-02-20 19:22:59.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-02-20 19:23:15.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-02-20 19:23:57.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-02-20 19:24:07.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;
+
+
+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;
+}
+
+
+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-02-20 19:24:14.000000000 +0100
@@ -0,0 +1,176 @@
+/* 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;
+
+
+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);
+}
+
+
+Object
+P_Readline_Read (void)
+{
+  char *expr, *line, *prompt = _prompt;
+  int bufsize = 1024, exprlen = 0, first = 1, llen;
+  Object ret, port;
+  GC_Node2;
+
+  /* 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_Link2(port, ret);
+  ret = General_Read(port, 0);
+  GC_Unlink;
+ (void)P_Close_Input_Port(port);
+ free(expr);
+
+ return ret;
+}
+
+
+Object
+P_Readline_Add_History (Object add)
+{
+  add_history(Get_String(add));
+
+  return True;
+}
+
+
+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"));
+}
+
+/* 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-02-20 19:24:17.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-02-20 19:24:31.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-02-20 19:31:18.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)