diff --git a/configure b/configure index baaaaef8..7b249289 100755 --- a/configure +++ b/configure @@ -2477,6 +2477,8 @@ as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H" +as_fn_append ac_header_c_list " readline/readline.h readline_readline_h HAVE_READLINE_READLINE_H" +as_fn_append ac_header_c_list " readline/history.h readline_history_h HAVE_READLINE_HISTORY_H" # Auxiliary files required by this configure script. ac_aux_files="install-sh" @@ -3941,6 +3943,57 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +printf %s "checking for readline in -lreadline... " >&6; } +if test ${ac_cv_lib_readline_readline+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char readline (void); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_readline_readline=yes +else case e in #( + e) ac_cv_lib_readline_readline=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +printf "%s\n" "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes +then : + printf "%s\n" "#define HAVE_LIBREADLINE 1" >>confdefs.h + + LIBS="-lreadline $LIBS" + +fi + ac_header= ac_cache= for ac_item in $ac_header_c_list do @@ -3973,6 +4026,8 @@ fi + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -4270,6 +4325,12 @@ then : printf "%s\n" "#define HAVE_INOTIFY_INIT1 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "readline" "ac_cv_func_readline" +if test "x$ac_cv_func_readline" = xyes +then : + printf "%s\n" "#define HAVE_READLINE 1" >>confdefs.h + +fi VERSION=$PACKAGE_VERSION diff --git a/configure.ac b/configure.ac index 060877ae..ed00f9db 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,8 @@ AC_PATH_PROG([PERL], [perl]) dnl Checks for libraries. AC_CHECK_LIB(m, sqrt) -AC_CHECK_HEADERS_ONCE([sys/time.h stdint.h]) +AC_CHECK_LIB(readline, readline) +AC_CHECK_HEADERS_ONCE([sys/time.h stdint.h readline/readline.h readline/history.h]) dnl Integer sizes AC_CHECK_SIZEOF(unsigned int) @@ -84,7 +85,7 @@ if test "$?" != 0 ; then echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!" exit 1 fi -AC_CHECK_FUNCS(strdup strcasecmp strncasecmp setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1) +AC_CHECK_FUNCS(strdup strcasecmp strncasecmp setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1 readline) VERSION=$PACKAGE_VERSION CONFIG_CMD="$0$ac_configure_args_raw" diff --git a/src/config.h.in b/src/config.h.in index 8eac8818..d1905b27 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -45,6 +45,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `readline' function. */ +#undef HAVE_READLINE + /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP @@ -81,6 +84,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_HISTORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT diff --git a/src/custom.h b/src/custom.h index 896fc5a6..5c6ff063 100644 --- a/src/custom.h +++ b/src/custom.h @@ -159,3 +159,15 @@ #else #undef REM_USE_WCHAR #endif + +#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) +#define USE_READLINE 1 +#else +#undef USE_READLINE 1 +#endif + +#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) && defined(HAVE_READLINE_HISTORY_H) +#define USE_READLINE_HISTORY 1 +#else +#undef USE_READLINE_HISTORY 1 +#endif diff --git a/src/custom.h.in b/src/custom.h.in index 35c8676b..5c6ff063 100644 --- a/src/custom.h.in +++ b/src/custom.h.in @@ -22,8 +22,8 @@ /* The default values are initially set to the city hall in Ottawa, */ /* Ontario, Canada. */ /*---------------------------------------------------------------------*/ -#define DEFAULT_LATITUDE 45.420556 -#define DEFAULT_LONGITUDE -75.689722 +#define DEFAULT_LATITUDE 45.42055555555555 +#define DEFAULT_LONGITUDE -75.68944444444445 #define LOCATION "Ottawa" /*---------------------------------------------------------------------*/ @@ -159,3 +159,15 @@ #else #undef REM_USE_WCHAR #endif + +#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) +#define USE_READLINE 1 +#else +#undef USE_READLINE 1 +#endif + +#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) && defined(HAVE_READLINE_HISTORY_H) +#define USE_READLINE_HISTORY 1 +#else +#undef USE_READLINE_HISTORY 1 +#endif diff --git a/src/files.c b/src/files.c index eb63c5cc..1cbcf738 100644 --- a/src/files.c +++ b/src/files.c @@ -41,6 +41,13 @@ #include "globals.h" #include "err.h" +#ifdef USE_READLINE +#include +#endif +#ifdef USE_READLINE_HISTORY +#include +#endif + /* Convenient macros for closing files */ #define FCLOSE(fp) ((((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL)) @@ -134,6 +141,9 @@ void InitFiles(void) fprintf(ErrFp, "Unable to initialize filename hash table: Out of memory. Exiting.\n"); exit(1); } +#ifdef USE_READLINE_HISTORY + using_history(); +#endif } void SetCurrentFilename(char const *fname) @@ -280,7 +290,9 @@ static int ReadLineFromFile(int use_pclose) int l; char copy_buffer[4096]; size_t n; + int force_eof = 0; + int read_some = 0; DynamicBuffer buf; DBufInit(&buf); @@ -288,17 +300,48 @@ static int ReadLineFromFile(int use_pclose) LineNoStart = LineNo+1; while(fp) { +#ifdef USE_READLINE + if (fileno(fp) == STDIN_FILENO && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { + char *l; + if (read_some) { + l = readline("Rem...> "); + } else { + l = readline("Remind> "); + read_some = 1; + } + if (l) { +#ifdef USE_READLINE_HISTORY + if (*l) { + add_history(l); + } +#endif + DBufFree(&buf); + if (DBufPuts(&buf, l) != OK) { + free(l); + DBufFree(&buf); + return E_NO_MEM; + } + free(l); + force_eof = 0; + } else { + force_eof = 1; + } + } else { +#endif if (DBufGets(&buf, fp) != OK) { DBufFree(&LineBuffer); return E_NO_MEM; } +#ifdef USE_READLINE + } +#endif LineNo++; if (ferror(fp)) { DBufFree(&buf); DBufFree(&LineBuffer); return E_IO_ERR; } - if (feof(fp)) { + if (feof(fp) || force_eof) { if (use_pclose) { PCLOSE(fp); } else {