editline 0.1 → 0.2
raw patch · 9 files changed
+375/−66 lines, 9 filessetup-changed
Files
- Setup.hs +0/−6
- Setup.lhs +6/−0
- System/Console/Editline/Readline.hsc +82/−0
- aclocal.m4 +43/−4
- configure +165/−44
- configure.ac +12/−7
- editline.cabal +3/−2
- include/HsEditlineConfig.h +6/−3
- include/HsEditlineConfig.h.in +58/−0
− Setup.hs
@@ -1,6 +0,0 @@-module Main (main) where--import Distribution.Simple--main :: IO ()-main = defaultMainWithHooks defaultUserHooks
+ Setup.lhs view
@@ -0,0 +1,6 @@+#!/usr/local/bin/runhaskell++\begin{code}+import Distribution.Simple+main = defaultMainWithHooks defaultUserHooks+\end{code}
System/Console/Editline/Readline.hsc view
@@ -36,21 +36,38 @@ -- -----------------------------------------------------------------------------+#include "HsEditlineConfig.h" #ifdef HAVE_EDITLINE_READLINE_H #include <editline/readline.h> #else #ifdef HAVE_READLINE_READLINE_H #include <readline/readline.h>+#else+#ifdef HAVE_EDITLINE_EDITLINE_H+#include <editline/editline.h> #endif #endif+#endif + module System.Console.Editline.Readline ( -------------------------------------------------------------------- -- Basic Behavior. readline, -- :: String -> IO (Maybe String)++ --------------------------------------------------------------------+ -- History Functionality.+ addHistory, -- :: String -> IO ()+ readHistory, -- :: String -> IO ()+ writeHistory, -- :: String -> IO ()+ clearHistory, -- :: IO ()+ stifleHistory, -- :: Int -> IO ()+ unstifleHistory, -- :: IO Int+ historyIsStifled, -- :: IO Bool+ historyMaxEntries, -- IO Int -------------------------------------------------------------------- -- Readline Variables.@@ -185,13 +202,78 @@ return line foreign import ccall "readline" readlineC :: Ptr CChar -> IO (Ptr CChar) +--------------------------------------------------------------------------+-- History functionality +-- TODO: older versions of libedit don't return errors correctly...+ -- |Add this command to the history. This allows users to search backward -- through history with C-r and step through with up and down arrows, among -- other things. addHistory :: String -> IO () addHistory line = withCString line add_history foreign import ccall unsafe add_history :: Ptr CChar -> IO ()++-- |Read in a history file, throwing an error on failure.+readHistory :: FilePath -- ^ The file to read (if null, read ~/.history)+ -> IO ()+readHistory fp = do+ ok <- withCString fp read_history+ unless (histResultIsOK ok) $ fail "Can't read history file"+foreign import ccall unsafe read_history :: Ptr CChar -> IO CInt++-- |Write out a history file, throwing an error on failure.+writeHistory :: FilePath -- ^ The file to write (if null, write ~/.history+ -> IO ()+writeHistory fp = do+ ok <- withCString fp write_history+ unless (histResultIsOK ok) $ fail "Can't write history file"+foreign import ccall unsafe write_history :: Ptr CChar -> IO CInt++histResultIsOK :: CInt -> Bool+#ifdef NEGATIVE_HIST_ERROR+-- Old way that libedit handled errors; different from readline+histResultIsOK = (>=0)+#else+histResultIsOK = (==0)+#endif++-- |Clear the history.+clearHistory :: IO ()+clearHistory = clear_history+foreign import ccall unsafe clear_history :: IO ()++-- |Stifle the history list, remembering only a certain number of entries.+stifleHistory :: Int -> IO ()+stifleHistory n = stifle_history n+foreign import ccall unsafe stifle_history :: Int -> IO ()++-- |Stop stifling the history, returning the previous amount the history was+-- stifled by. +unstifleHistory :: IO Int+unstifleHistory = unstifle_history+foreign import ccall unsafe unstifle_history :: IO Int++-- |Check whether the history is stifled or not. True if stifled, False if not.+historyIsStifled :: IO Bool+historyIsStifled = do+ isStifledInt <- history_is_stifled+ let isStifled = case isStifledInt of+ 0 -> False+ 1 -> True+ _ -> error "historyIsStifled: history_is_stifled returned unexpected value (expected 0 or 1, received other)" -- just for completeness - there is no conceivable way readline would not return either 0 or 1 here+ return isStifled+foreign import ccall unsafe history_is_stifled :: IO Int++-- |Get the maximum number of history entries, returning 0 if the history is +-- unstifled.+historyMaxEntries :: IO Int+historyMaxEntries = liftM fromIntegral (peek max_input_history)++-- Note: this variable is different than history_max_entries, but has the same+-- use.+foreign import ccall "&" max_input_history :: Ptr CInt+ ------------------------------------------------------------------------ -- Readline Variables.
aclocal.m4 view
@@ -15,8 +15,47 @@ [editline_libraries=NONE]) ])# FP_ARG_EDITLINE -AC_DEFUN([CHECK_EDITLINE],-[AC_REQUIRE([AC_PROG_CPP])-AC_REQUIRE([AC_PROG_CC])+AC_DEFUN([CHECK_HIST_ERRORS],+[+dnl Older versions of libedit (up to at least 2.6.9) don't handle errors in+dnl functions like read_history the same way that readline does; whereas+dnl readline returns a positive errno on error and zero otherwise, +dnl editline may return -1 on error and a nonnegative value otherwise.+AC_MSG_CHECKING(for sign of read_history result on error)+AC_RUN_IFELSE(+ [AC_LANG_SOURCE([[+#include <stdio.h>+#ifdef HAVE_EDITLINE_READLINE_H+#include <editline/readline.h>+#else+#ifdef HAVE_READLINE_READLINE_H+#include <readline/readline.h>+#else+#ifdef HAVE_EDITLINE_EDITLINE_H+#include <editline/editline.h>+#endif+#endif+#endif -])+int main(void) {+ int ret;+ rl_initialize();+ ret = read_history("this/should/not/be/valid");+ return (ret < 0);+}+]])],+ [error_is_negative=NO],+ [error_is_negative=YES]+)++if test "x$error_is_negative" = "xYES"; then+ AC_DEFINE([NEGATIVE_HIST_ERROR],[1],+ [Define if read_history returns a positive value on error])+ AC_MSG_RESULT(negative)+else+ AC_MSG_RESULT(positive)+fi++++])# CHECK_HIST_ERRORS
configure view
@@ -2493,35 +2493,61 @@ fi -HaveLibEdit=YES if test "x$HaveLibTermcap" = xYES ; then- LIBS="-l$LibTermcap $LIBS"--echo "$as_me:$LINENO: checking for el_init in -ledit" >&5-echo $ECHO_N "checking for el_init in -ledit... $ECHO_C" >&6-if test "${ac_cv_lib_edit_el_init+set}" = set; then+ HaveLibEdit=YES+ LIBS="$LIBS -l$LibTermcap -ledit"+ echo "$as_me:$LINENO: checking for el_init" >&5+echo $ECHO_N "checking for el_init... $ECHO_C" >&6+if test "${ac_cv_func_el_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else- ac_check_lib_save_LIBS=$LIBS-LIBS="-ledit $LIBS"-cat >conftest.$ac_ext <<_ACEOF+ cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */+/* Define el_init to an innocuous variant, in case <limits.h> declares el_init.+ For example, HP-UX 11i <limits.h> declares gettimeofday. */+#define el_init innocuous_el_init +/* System header to define __stub macros and hopefully few prototypes,+ which can conflict with char el_init (); below.+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+ <limits.h> exists even on freestanding compilers. */++#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif++#undef el_init+ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C"+{ #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char el_init ();+/* The GNU C library defines this for functions which it implements+ to always fail with ENOSYS. Some functions are actually named+ something starting with __ and the normal name is an alias. */+#if defined (__stub_el_init) || defined (__stub___el_init)+choke me+#else+char (*f) () = el_init;+#endif+#ifdef __cplusplus+}+#endif+ int main () {-el_init ();+return f != el_init; ; return 0; }@@ -2548,56 +2574,76 @@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then- ac_cv_lib_edit_el_init=yes+ ac_cv_func_el_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_lib_edit_el_init=no+ac_cv_func_el_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext-LIBS=$ac_check_lib_save_LIBS fi-echo "$as_me:$LINENO: result: $ac_cv_lib_edit_el_init" >&5-echo "${ECHO_T}$ac_cv_lib_edit_el_init" >&6-if test $ac_cv_lib_edit_el_init = yes; then- cat >>confdefs.h <<_ACEOF-#define HAVE_LIBEDIT 1-_ACEOF-- LIBS="-ledit $LIBS"-+echo "$as_me:$LINENO: result: $ac_cv_func_el_init" >&5+echo "${ECHO_T}$ac_cv_func_el_init" >&6+if test $ac_cv_func_el_init = yes; then+ : else HaveLibEdit=NO fi --echo "$as_me:$LINENO: checking for readline in -ledit" >&5-echo $ECHO_N "checking for readline in -ledit... $ECHO_C" >&6-if test "${ac_cv_lib_edit_readline+set}" = set; then+ echo "$as_me:$LINENO: checking for readline" >&5+echo $ECHO_N "checking for readline... $ECHO_C" >&6+if test "${ac_cv_func_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else- ac_check_lib_save_LIBS=$LIBS-LIBS="-ledit $LIBS"-cat >conftest.$ac_ext <<_ACEOF+ cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */+/* Define readline to an innocuous variant, in case <limits.h> declares readline.+ For example, HP-UX 11i <limits.h> declares gettimeofday. */+#define readline innocuous_readline +/* System header to define __stub macros and hopefully few prototypes,+ which can conflict with char readline (); below.+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+ <limits.h> exists even on freestanding compilers. */++#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif++#undef readline+ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C"+{ #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char readline ();+/* The GNU C library defines this for functions which it implements+ to always fail with ENOSYS. Some functions are actually named+ something starting with __ and the normal name is an alias. */+#if defined (__stub_readline) || defined (__stub___readline)+choke me+#else+char (*f) () = readline;+#endif+#ifdef __cplusplus+}+#endif+ int main () {-readline ();+return f != readline; ; return 0; }@@ -2624,32 +2670,27 @@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then- ac_cv_lib_edit_readline=yes+ ac_cv_func_readline=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_lib_edit_readline=no+ac_cv_func_readline=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext-LIBS=$ac_check_lib_save_LIBS fi-echo "$as_me:$LINENO: result: $ac_cv_lib_edit_readline" >&5-echo "${ECHO_T}$ac_cv_lib_edit_readline" >&6-if test $ac_cv_lib_edit_readline = yes; then- cat >>confdefs.h <<_ACEOF-#define HAVE_LIBEDIT 1-_ACEOF-- LIBS="-ledit $LIBS"-+echo "$as_me:$LINENO: result: $ac_cv_func_readline" >&5+echo "${ECHO_T}$ac_cv_func_readline" >&6+if test $ac_cv_func_readline = yes; then+ : else HaveLibEdit=NO fi EDITLINE_LIBS="edit $LibTermcap"- LIBS="$LIBS -ledit"+else+ HaveLibEdit=NO fi ac_ext=c@@ -3142,7 +3183,8 @@ -for ac_header in editline/readline.h readline/readline.h++for ac_header in editline/readline.h editline/editline.h readline/readline.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then@@ -3290,6 +3332,85 @@ fi done++++echo "$as_me:$LINENO: checking for sign of read_history result on error" >&5+echo $ECHO_N "checking for sign of read_history result on error... $ECHO_C" >&6+if test "$cross_compiling" = yes; then+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling+See \`config.log' for more details." >&5+echo "$as_me: error: cannot run test program while cross compiling+See \`config.log' for more details." >&2;}+ { (exit 1); exit 1; }; }+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++#include <stdio.h>+#ifdef HAVE_EDITLINE_READLINE_H+#include <editline/readline.h>+#else+#ifdef HAVE_READLINE_READLINE_H+#include <readline/readline.h>+#else+#ifdef HAVE_EDITLINE_EDITLINE_H+#include <editline/editline.h>+#endif+#endif+#endif++int main(void) {+ int ret;+ rl_initialize();+ ret = read_history("this/should/not/be/valid");+ return (ret < 0);+}++_ACEOF+rm -f conftest$ac_exeext+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5+ (eval $ac_link) 2>&5+ ac_status=$?+ echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5+ (eval $ac_try) 2>&5+ ac_status=$?+ echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; }; then+ error_is_negative=NO+else+ echo "$as_me: program exited with status $ac_status" >&5+echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++( exit $ac_status )+error_is_negative=YES++fi+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext+fi++if test "x$error_is_negative" = "xYES"; then++cat >>confdefs.h <<\_ACEOF+#define NEGATIVE_HIST_ERROR 1+_ACEOF++ echo "$as_me:$LINENO: result: negative" >&5+echo "${ECHO_T}negative" >&6+else+ echo "$as_me:$LINENO: result: positive" >&5+echo "${ECHO_T}positive" >&6+fi+++ if test "x$HaveLibEdit" = xYES ; then
configure.ac view
@@ -31,17 +31,22 @@ AC_CHECK_LIB(curses, tputs, HaveLibTermcap=YES; LibTermcap=curses, HaveLibTermcap=NO; LibTermcap=not-installed))) -HaveLibEdit=YES if test "x$HaveLibTermcap" = xYES ; then- LIBS="-l$LibTermcap $LIBS"- AC_CHECK_LIB(edit, el_init, , HaveLibEdit=NO)- AC_CHECK_LIB(edit, readline, , HaveLibEdit=NO)+ HaveLibEdit=YES+ LIBS="$LIBS -l$LibTermcap -ledit"+ AC_CHECK_FUNC(el_init, , HaveLibEdit=NO)+ AC_CHECK_FUNC(readline, , HaveLibEdit=NO) EDITLINE_LIBS="edit $LibTermcap"- LIBS="$LIBS -ledit"+else+ HaveLibEdit=NO fi -dnl Look for the equivalent of <readline.readline.h>-AC_CHECK_HEADERS([editline/readline.h readline/readline.h], [break])+dnl Look for the equivalent of <readline/readline.h>+dnl Make sure to check <readline/readline.h> last, so that if both readline and+dnl editline are installed, we'll pick the right one.+AC_CHECK_HEADERS([editline/readline.h editline/editline.h readline/readline.h], [break])++CHECK_HIST_ERRORS if test "x$HaveLibEdit" = xYES ; then BUILD_PACKAGE_BOOL=True
editline.cabal view
@@ -1,5 +1,5 @@ name: editline-version: 0.1+version: 0.2 license: BSD3 license-file: LICENSE maintainer: Judah Jacobson <judah.jacobson@gmail.com>@@ -16,8 +16,9 @@ readline package. homepage: http://code.haskell.org/editline extra-source-files:- aclocal.m4 configure.ac configure+ aclocal.m4 configure.ac editline.buildinfo.in+ configure include/HsEditlineConfig.h.in extra-tmp-files: config.log config.status autom4te.cache editline.buildinfo include/HsEditlineConfig.h
include/HsEditlineConfig.h view
@@ -1,15 +1,15 @@ /* include/HsEditlineConfig.h. Generated by configure. */ /* include/HsEditlineConfig.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if you have the <editline/editline.h> header file. */+/* #undef HAVE_EDITLINE_EDITLINE_H */+ /* Define to 1 if you have the <editline/readline.h> header file. */ /* #undef HAVE_EDITLINE_READLINE_H */ /* Define to 1 if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H 1 -/* Define to 1 if you have the `edit' library (-ledit). */-#define HAVE_LIBEDIT 1- /* Define to 1 if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 @@ -36,6 +36,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1++/* Define if read_history returns a positive value on error */+#define NEGATIVE_HIST_ERROR 1 /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "libraries@haskell.org"
+ include/HsEditlineConfig.h.in view
@@ -0,0 +1,58 @@+/* include/HsEditlineConfig.h.in. Generated from configure.ac by autoheader. */++/* Define to 1 if you have the <editline/editline.h> header file. */+#undef HAVE_EDITLINE_EDITLINE_H++/* Define to 1 if you have the <editline/readline.h> header file. */+#undef HAVE_EDITLINE_READLINE_H++/* Define to 1 if you have the <inttypes.h> header file. */+#undef HAVE_INTTYPES_H++/* Define to 1 if you have the <memory.h> header file. */+#undef HAVE_MEMORY_H++/* Define to 1 if you have the <readline/readline.h> header file. */+#undef HAVE_READLINE_READLINE_H++/* Define to 1 if you have the <stdint.h> header file. */+#undef HAVE_STDINT_H++/* Define to 1 if you have the <stdlib.h> header file. */+#undef HAVE_STDLIB_H++/* Define to 1 if you have the <strings.h> header file. */+#undef HAVE_STRINGS_H++/* Define to 1 if you have the <string.h> header file. */+#undef HAVE_STRING_H++/* Define to 1 if you have the <sys/stat.h> header file. */+#undef HAVE_SYS_STAT_H++/* Define to 1 if you have the <sys/types.h> header file. */+#undef HAVE_SYS_TYPES_H++/* Define to 1 if you have the <unistd.h> header file. */+#undef HAVE_UNISTD_H++/* Define if read_history returns a positive value on error */+#undef NEGATIVE_HIST_ERROR++/* Define to the address where bug reports for this package should be sent. */+#undef PACKAGE_BUGREPORT++/* Define to the full name of this package. */+#undef PACKAGE_NAME++/* Define to the full name and version of this package. */+#undef PACKAGE_STRING++/* Define to the one symbol short name of this package. */+#undef PACKAGE_TARNAME++/* Define to the version of this package. */+#undef PACKAGE_VERSION++/* Define to 1 if you have the ANSI C header files. */+#undef STDC_HEADERS