[m-rev.] for review: support editline as an alternative to GNU readline

Julien Fischer jfischer at opturion.com
Mon Jun 18 16:22:30 AEST 2018


For review by anyone.

-------------------------------

Support editline as an alternative to GNU readline.

Support the use of the editline library as an alternative to GNU readline for
the debugger command-line prompt.  The former has a more permissive license
than the latter.  If licensing is not an issue then GNU readline is the
preferable choice (e.g. feature wise), as such it is the default option.

NOTE: there are (apparently) two editline libraries, one derived from NetBSD
and one from Minix -- this diff adds support for the former.  (Using the
latter should just be a matter of using a different header file and
supplying a different library name to link against, but I haven't tried
it yet.)

m4/mercury.m4:
     Add a configuration check for editline library

configure.ac:
     Check for the presence of editline library.

runtime/mercury_conf.h.in:
     Replace the macro MR_NO_USE_READLINE with MR_USE_READLINE which
     is defined if GNU readline is available and the user has not
     forbidden its use.

     Add a new macro MR_USE_EDITLINE which does the same for editline.

     Add a new macro that is defined if the header editline/readline.h
     is present.

trace/mercury_trace_completion.c:
trace/mercury_trace_readline.c:
     Use editline in place of readline if appropriate.

Julien.

diff --git a/configure.ac b/configure.ac
index 37ee475..2d295f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5227,10 +5227,11 @@ AC_SUBST(USE_MSVCRT)

  #-----------------------------------------------------------------------------#
  #
-# Check for readline
+# Check for readline and editline.
  #

  MERCURY_CHECK_READLINE
+MERCURY_CHECK_EDITLINE

  #-----------------------------------------------------------------------------#
  #
diff --git a/m4/mercury.m4 b/m4/mercury.m4
index 17c47aa..f83dc56 100644
--- a/m4/mercury.m4
+++ b/m4/mercury.m4
@@ -201,22 +201,22 @@ AC_DEFUN([MERCURY_TRY_STATIC_ASSERT], [
  AC_DEFUN([MERCURY_CHECK_READLINE],
  [
  AC_ARG_WITH(readline,
-[  --without-readline      Don't use the GPL'd GNU readline library],
+[  --without-readline      Do not use the GPL'd GNU readline library],
  mercury_cv_with_readline="$withval", mercury_cv_with_readline=yes)

  if test "$mercury_cv_with_readline" = yes; then

-	# check for the readline header files
+	# Check for the readline header files.
  	MERCURY_CHECK_FOR_HEADERS(readline/readline.h readline/history.h)

-	# check for the libraries that readline depends on
+	# Check for the libraries that readline depends on.
  	MERCURY_MSG('looking for termcap or curses (needed by readline)...')
  	AC_CHECK_LIB(termcap, tgetent, mercury_cv_termcap_lib=-ltermcap,
  	 [AC_CHECK_LIB(curses,  tgetent, mercury_cv_termcap_lib=-lcurses,
  	  [AC_CHECK_LIB(ncurses, tgetent, mercury_cv_termcap_lib=-lncurses,
  	   mercury_cv_termcap_lib='')])])

-	# check for the readline library
+	# Check for the readline library.
  	AC_CHECK_LIB(readline, readline, mercury_cv_have_readline=yes,
  		mercury_cv_have_readline=no, $mercury_cv_termcap_lib)
  else
@@ -230,8 +230,8 @@ fi
  if test $mercury_cv_have_readline = no; then
  	TERMCAP_LIBRARY=""
  	READLINE_LIBRARIES=""
-	AC_DEFINE(MR_NO_USE_READLINE)
  else
+	AC_DEFINE(MR_USE_READLINE)
  	TERMCAP_LIBRARY="$mercury_cv_termcap_lib"
  	READLINE_LIBRARIES="-lreadline $TERMCAP_LIBRARY"
  fi
@@ -241,6 +241,36 @@ AC_SUBST(READLINE_LIBRARIES)
  ])

  #-----------------------------------------------------------------------------#
+
+AC_DEFUN([MERCURY_CHECK_EDITLINE], [
+AC_REQUIRE([MERCURY_CHECK_READLINE])
+AC_ARG_WITH(editline,
+[  --without-editline      Do not use the editline library],
+mercury_cv_with_editline="$withval", mercury_cv_with_editline=yes)
+
+if test $mercury_cv_with_editline = no; then
+	mercury_cv_have_editline=no
+elif test $mercury_cv_have_readline = no; then
+
+	# Check for the editline header files.
+	MERCURY_CHECK_FOR_HEADERS(editline/readline.h)
+
+	# Check for the editline library.
+	AC_CHECK_LIB(edit, readline, mercury_cv_have_editline=yes,
+		mercury_cv_have_editline=no)
+else
+	mercury_cv_have_editline=no
+fi
+
+if test $mercury_cv_have_editline = yes; then
+	AC_DEFINE(MR_USE_EDITLINE)
+	TERMCAP_LIBARARIES=""
+	READLINE_LIBRARIES="-ledit"
+fi
+
+])
+
+#-----------------------------------------------------------------------------#
  #
  # Microsoft.NET configuration
  #
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index 70b26e5..46fc4e5 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -533,11 +533,11 @@

  #undef  MR_DEEP_PROFILER_ENABLED

-// MR_NO_USE_READLINE
+// MR_USE_READLINE
  //
-// Set this if you want to prevent the debugger from using the GNU readline
-// library for the command-line prompt. The autoconfiguration script sets this
-// if it can't find a termcap library.
+// GNU readline and any supporting libraries required (e.g. termcap) are
+// available and should be used by the debugger for the command-line prompt.
+// this will *not* be defind if MR_USE_EDITLINE is defined.
  //
  // MR_HAVE_READLINE_READLINE_H
  // MR_HAVE_READLINE_HISTORY_H
@@ -545,10 +545,23 @@
  // Defined if the header files readline/readline.h and
  // readline/history.h are available.

-#undef  MR_NO_USE_READLINE
+#undef  MR_USE_READLINE
  #undef  MR_HAVE_READLINE_READLINE_H
  #undef  MR_HAVE_READLINE_HISTORY_H

+// MR_USE_EDITLINE
+//
+// The editline library is available and should be used by the debugger
+// for the command-line prompt.
+// This will *not* be defined if MR_USE_READLINE is defined.
+//
+// MR_HAVE_EDITLINE_READLINE_H
+//
+// Define if the header file editline/readline.h. is available.
+
+#undef MR_USE_EDITLINE
+#undef MR_HAVE_EDITLINE_READLINE_H
+
  // MR_MKFIFO
  //
  // The name of the shell command to make a named pipe. This will be the
diff --git a/trace/mercury_trace_completion.c b/trace/mercury_trace_completion.c
index 428b2b1..541c26b 100644
--- a/trace/mercury_trace_completion.c
+++ b/trace/mercury_trace_completion.c
@@ -22,9 +22,11 @@
  #include <stdlib.h>
  #include <string.h>

-#ifndef MR_NO_USE_READLINE
-  #ifdef MR_HAVE_READLINE_READLINE_H
+#if defined(MR_USE_READLINE) || defined(MR_USE_EDITLINE)
+  #if defined(MR_HAVE_READLINE_H)
      #include <readline/readline.h>
+  #elif defined(MR_HAVE_EDITLINE_H)
+    #include <editline/readline.h>
    #else
      extern char     *rl_line_buffer;
      extern int      rl_point;
@@ -78,7 +80,7 @@ static  void                MR_trace_free_map_completer_data(
  char *
  MR_trace_line_completer(const char *passed_word, int state)
  {
-#ifdef MR_NO_USE_READLINE
+#if !defined(MR_USE_READLINE) && !defined(MR_USE_EDITLINE)
      return NULL;
  #else
      static MR_CompleterList     *completer_list;
@@ -226,7 +228,7 @@ MR_trace_line_completer(const char *passed_word, int state)
      }

      return completion;
-#endif // ! MR_NO_USE_READLINE
+#endif // defined(MR_USE_READLINE) || defined(MR_USE_EDITLINE)
  }

  static char *
@@ -585,7 +587,7 @@ static char *
  MR_trace_filename_completer_next(const char *word, size_t word_len,
      MR_CompleterData *data)
  {
-#ifdef MR_NO_USE_READLINE
+#if !defined(MR_USE_READLINE) && !defined(MR_USE_EDITLINE)
      return NULL;
  #else
      MR_Integer  state;
@@ -593,7 +595,7 @@ MR_trace_filename_completer_next(const char *word, size_t word_len,
      state = (MR_Integer) *data;
      *data = (MR_CompleterData) 1;
      return filename_completion_function((char *) word, (int) state);
-#endif // ! MR_NO_USE_READLINE
+#endif // defined(MR_USE_READLINE) || defined(MR_USE_EDITLINE)
  }

  ////////////////////////////////////////////////////////////////////////////
diff --git a/trace/mercury_trace_readline.c b/trace/mercury_trace_readline.c
index ac790db..905a36c 100644
--- a/trace/mercury_trace_readline.c
+++ b/trace/mercury_trace_readline.c
@@ -17,9 +17,11 @@
  #include "mercury_trace_readline.h"
  #include "mercury_trace_completion.h"

-#ifndef MR_NO_USE_READLINE
-  #ifdef MR_HAVE_READLINE_READLINE_H
+#if defined(MR_USE_READLINE) || defined(MR_USE_EDITLINE)
+  #if defined(MR_HAVE_READLINE_READLINE_H)
      #include <readline/readline.h>
+  #elif defined(MR_HAVE_EDITLINE_READLINE_H)
+     #include <editline/readline.h>
    #else
      extern FILE         *rl_instream;
      extern FILE         *rl_outstream;
@@ -50,7 +52,7 @@ MR_trace_readline(const char *prompt, FILE *in, FILE *out)
  {
  #if (defined(isatty) || defined(MR_HAVE_ISATTY)) \
   && (defined(fileno) || defined(MR_HAVE_FILENO)) \
- && !defined(MR_NO_USE_READLINE)
+ && (defined(MR_USE_READLINE) || defined(MR_USE_EDITLINE))
      char    *line;
      MR_bool in_isatty;
      char    *last_nl;
@@ -117,7 +119,7 @@ MR_trace_readline(const char *prompt, FILE *in, FILE *out)

          return line;
      }
-#endif // have isatty && have fileno && !MR_NO_USE_READLINE
+#endif // have isatty && have fileno && (have readline || have editline)

      // Otherwise, don't use readline.
      fprintf(out, "%s", prompt);


More information about the reviews mailing list