From 548845673bdbe52a3cb2d7c6c2818d3202fffcba Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sun, 10 Mar 2002 20:31:23 +0000 Subject: [PATCH] initial readline support --- ChangeLog | 3 +- Makefile.am | 8 +- Makefile.in | 25 ++++--- abook_rl.c | 107 +++++++++++++++++++++++++++ abook_rl.h | 9 +++ acinclude.m4 | 96 ++++++++++++++++++++++++ aclocal.m4 | 112 ++++++++++++++++++++++++++-- config.h.in | 20 ++++- configure | 202 ++++++++++++++++++++++++++++++++++++++++++++++++--- configure.in | 8 ++ edit.c | 43 ++++------- filter.c | 4 +- list.h | 2 +- ui.c | 73 +++++-------------- ui.h | 4 +- 15 files changed, 596 insertions(+), 120 deletions(-) create mode 100644 abook_rl.c create mode 100644 abook_rl.h diff --git a/ChangeLog b/ChangeLog index a71b6ef..7980b99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ -2002-xx-xx +2002-03-10 + - readline support - abook can be compiled with g++ - attempt to improve --datafile behavior - html filter update (Morten Brix Pedersen) diff --git a/Makefile.am b/Makefile.am index 0391bc3..afd3141 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,11 +2,11 @@ bin_PROGRAMS = abook abook_SOURCES = abook.c database.c filter.c list.c misc.c conff.c \ - options.c edit.c ldif.c estr.c ui.c getname.c \ - getopt.c getopt1.c \ + options.c edit.c ldif.c ui.c getname.c \ + getopt.c getopt1.c abook_rl.c \ abook.h database.h filter.h list.h misc.h help.h conff.h \ - options.h edit.h ldif.h estr.h abook_curses.h ui.h getname.h \ - getopt.h + options.h edit.h ldif.h abook_curses.h ui.h getname.h \ + getopt.h abook_rl.h EXTRA_DIST = ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc diff --git a/Makefile.in b/Makefile.in index 30d009c..353f983 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -68,7 +68,12 @@ VERSION = @VERSION@ bin_PROGRAMS = abook -abook_SOURCES = abook.c database.c filter.c list.c misc.c conff.c options.c edit.c ldif.c estr.c ui.c getname.c getopt.c getopt1.c abook.h database.h filter.h list.h misc.h help.h conff.h options.h edit.h ldif.h estr.h abook_curses.h ui.h getname.h getopt.h +abook_SOURCES = abook.c database.c filter.c list.c misc.c conff.c \ + options.c edit.c ldif.c ui.c getname.c \ + getopt.c getopt1.c abook_rl.c \ + abook.h database.h filter.h list.h misc.h help.h conff.h \ + options.h edit.h ldif.h abook_curses.h ui.h getname.h \ + getopt.h abook_rl.h EXTRA_DIST = ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc @@ -84,7 +89,7 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ abook_OBJECTS = abook.o database.o filter.o list.o misc.o conff.o \ -options.o edit.o ldif.o estr.o ui.o getname.o getopt.o getopt1.o +options.o edit.o ldif.o ui.o getname.o getopt.o getopt1.o abook_rl.o abook_LDADD = $(LDADD) abook_DEPENDENCIES = abook_LDFLAGS = @@ -100,12 +105,12 @@ install-sh missing mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best -DEP_FILES = .deps/abook.P .deps/conff.P .deps/database.P .deps/edit.P \ -.deps/estr.P .deps/filter.P .deps/getname.P .deps/getopt.P \ -.deps/getopt1.P .deps/ldif.P .deps/list.P .deps/misc.P .deps/options.P \ -.deps/ui.P +DEP_FILES = .deps/abook.P .deps/abook_rl.P .deps/conff.P \ +.deps/database.P .deps/edit.P .deps/filter.P .deps/getname.P \ +.deps/getopt.P .deps/getopt1.P .deps/ldif.P .deps/list.P .deps/misc.P \ +.deps/options.P .deps/ui.P SOURCES = $(abook_SOURCES) OBJECTS = $(abook_OBJECTS) @@ -122,7 +127,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) $(ACLOCAL_M4): configure.in acinclude.m4 cd $(srcdir) && $(ACLOCAL) -config.status: $(srcdir)/configure.in $(CONFIG_STATUS_DEPENDENCIES) +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) diff --git a/abook_rl.c b/abook_rl.c new file mode 100644 index 0000000..0cd591e --- /dev/null +++ b/abook_rl.c @@ -0,0 +1,107 @@ +/* + * $Id$ + * + * by JH + * + * Copyright (C) Jaakko Heinonen + */ + + +#include +#include +#include +#include "abook.h" +#include "abook_rl.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(HAVE_READLINE_READLINE_H) +# include +#elif defined(HAVE_READLINE_H) +# include +#endif + +#if defined(HAVE_READLINE_HISTORY_H) +# include +#elif defined(HAVE_HISTORY_H) +# include +#endif + +#define RL_READLINE_NAME "Abook" + +static int rl_x, rl_y; +static WINDOW *rl_win; + +static void +rl_refresh() +{ + /*refresh();*/ + wrefresh(rl_win); +} + +static void +rline_update() +{ + int real_point = rl_point + rl_x; + + if(real_point > (COLS - 1)) + mvwaddnstr(rl_win, rl_y, rl_x, + rl_line_buffer + (1 + real_point - COLS), + COLS - rl_x - 1); + else + mvwaddnstr(rl_win, rl_y, rl_x, rl_line_buffer, rl_end); + + wclrtoeol(rl_win); + wmove(rl_win, rl_y, min(real_point, COLS - 1)); + + rl_refresh(); +} + +void +rline_compdisp(char **matches, int n, int max_len) +{ + /* + * dummy + */ +} + +static void +abook_rl_init(int use_completion) +{ + rl_readline_name = RL_READLINE_NAME; + + rl_already_prompted = 1; + + rl_redisplay_function = rline_update; + rl_completion_display_matches_hook = rline_compdisp; + + rl_unbind_function_in_map(rl_clear_screen, rl_get_keymap()); + + if(use_completion) + rl_bind_key('\t', rl_menu_complete); + else + rl_unbind_function_in_map(rl_complete, rl_get_keymap()); + + clear_history(); +} + +char * +abook_readline(WINDOW *w, int y, int x, char *s, int limit, int use_completion) +{ + char *ret = NULL; + + rl_win = w; + abook_rl_init(use_completion); + + wmove(rl_win, rl_y = y, rl_x = x); + rl_refresh(); + + if(s && *s) + add_history(s); + + ret = readline(NULL); + + return ret; +} diff --git a/abook_rl.h b/abook_rl.h new file mode 100644 index 0000000..d6c2c22 --- /dev/null +++ b/abook_rl.h @@ -0,0 +1,9 @@ +#ifndef _ABOOK_RL_H +#define _ABOOK_RL_H + +#include "abook_curses.h" + +char *abook_readline(WINDOW *w, int y, int x, char *s, int limit, + int use_completion); + +#endif diff --git a/acinclude.m4 b/acinclude.m4 index 5d443ec..c722454 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -81,3 +81,99 @@ if test ".$ac_cv_func_initscr" != .yes ; then fi ])]) + + + +dnl @synopsis AC_LIB_READLINE +dnl +dnl Searches for a readline compatible library. If found, defines +dnl `HAVE_LIBREADLINE'. If the found library has the `add_history' +dnl function, sets also `HAVE_READLINE_HISTORY'. Also checks for the +dnl locations of the necessary include files and sets `HAVE_READLINE_H' +dnl or `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or +dnl 'HAVE_HISTORY_H' if the corresponding include files exists. +dnl +dnl The libraries that may be readline compatible are `libedit', +dnl `libeditline' and `libreadline'. Sometimes we need to link a termcap +dnl library for readline to work, this macro tests these cases too by +dnl trying to link with `libtermcap', `libcurses' or `libncurses' before +dnl giving up. +dnl +dnl Here is an example of how to use the information provided by this +dnl macro to perform the necessary includes or declarations in a C file: +dnl +dnl #include +dnl +dnl #ifdef HAVE_LIBREADLINE +dnl #if defined(HAVE_READLINE_READLINE_H) +dnl #include +dnl #elif defined(HAVE_READLINE_H) +dnl #include +dnl #else /* !defined(HAVE_READLINE_H) */ +dnl extern char *readline (); +dnl #endif /* !defined(HAVE_READLINE_H) */ +dnl char *cmdline = NULL; +dnl #else /* !defined(HAVE_READLINE_READLINE_H) */ +dnl /* no readline */ +dnl #endif /* HAVE_LIBREADLINE */ +dnl +dnl #ifdef HAVE_READLINE_HISTORY +dnl #if defined(HAVE_READLINE_HISTORY_H) +dnl #include +dnl #elif defined(HAVE_HISTORY_H) +dnl #include +dnl #else /* !defined(HAVE_HISTORY_H) */ +dnl extern void add_history (); +dnl extern int write_history (); +dnl extern int read_history (); +dnl #endif /* defined(HAVE_READLINE_HISTORY_H) */ +dnl /* no history */ +dnl #endif /* HAVE_READLINE_HISTORY */ +dnl +dnl +dnl @version $Id$ +dnl @author Ville Laurikari +dnl +AC_DEFUN([AC_LIB_READLINE], [ + AC_CACHE_CHECK([for a readline compatible library], + ac_cv_lib_readline, [ + ORIG_LIBS=$LIBS + for readline_lib in readline edit editline; do + for termcap_lib in "" termcap curses ncurses; do + if test -z "$termcap_lib"; then + TRY_LIB="-l$readline_lib" + else + TRY_LIB="-l$readline_lib -l$termcap_lib" + fi + LIBS="$ORIG_LIBS $TRY_LIB" + AC_TRY_LINK_FUNC(readline, ac_cv_lib_readline="$TRY_LIB") + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -z "$ac_cv_lib_readline"; then + ac_cv_lib_readline="no" + LIBS=$ORIG_LIBS + fi + ]) + + if test "$ac_cv_lib_readline" != "no"; then + AC_DEFINE(HAVE_LIBREADLINE, 1, + [Define if you have a readline compatible library]) + AC_CHECK_HEADERS(readline.h readline/readline.h) + AC_CACHE_CHECK([whether readline supports history], + ac_cv_lib_readline_history, [ + ac_cv_lib_readline_history="no" + AC_TRY_LINK_FUNC(add_history, ac_cv_lib_readline_history="yes") + ]) + if test "$ac_cv_lib_readline_history" = "yes"; then + AC_DEFINE(HAVE_READLINE_HISTORY, 1, + [Define if your readline library has \`add_history']) + AC_CHECK_HEADERS(history.h readline/history.h) + fi + fi +]) diff --git a/aclocal.m4 b/aclocal.m4 index bd99458..d427868 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4-p4 +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 -dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -94,6 +94,102 @@ fi ])]) + + +dnl @synopsis AC_LIB_READLINE +dnl +dnl Searches for a readline compatible library. If found, defines +dnl `HAVE_LIBREADLINE'. If the found library has the `add_history' +dnl function, sets also `HAVE_READLINE_HISTORY'. Also checks for the +dnl locations of the necessary include files and sets `HAVE_READLINE_H' +dnl or `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or +dnl 'HAVE_HISTORY_H' if the corresponding include files exists. +dnl +dnl The libraries that may be readline compatible are `libedit', +dnl `libeditline' and `libreadline'. Sometimes we need to link a termcap +dnl library for readline to work, this macro tests these cases too by +dnl trying to link with `libtermcap', `libcurses' or `libncurses' before +dnl giving up. +dnl +dnl Here is an example of how to use the information provided by this +dnl macro to perform the necessary includes or declarations in a C file: +dnl +dnl #include +dnl +dnl #ifdef HAVE_LIBREADLINE +dnl #if defined(HAVE_READLINE_READLINE_H) +dnl #include +dnl #elif defined(HAVE_READLINE_H) +dnl #include +dnl #else /* !defined(HAVE_READLINE_H) */ +dnl extern char *readline (); +dnl #endif /* !defined(HAVE_READLINE_H) */ +dnl char *cmdline = NULL; +dnl #else /* !defined(HAVE_READLINE_READLINE_H) */ +dnl /* no readline */ +dnl #endif /* HAVE_LIBREADLINE */ +dnl +dnl #ifdef HAVE_READLINE_HISTORY +dnl #if defined(HAVE_READLINE_HISTORY_H) +dnl #include +dnl #elif defined(HAVE_HISTORY_H) +dnl #include +dnl #else /* !defined(HAVE_HISTORY_H) */ +dnl extern void add_history (); +dnl extern int write_history (); +dnl extern int read_history (); +dnl #endif /* defined(HAVE_READLINE_HISTORY_H) */ +dnl /* no history */ +dnl #endif /* HAVE_READLINE_HISTORY */ +dnl +dnl +dnl @version $Id$ +dnl @author Ville Laurikari +dnl +AC_DEFUN([AC_LIB_READLINE], [ + AC_CACHE_CHECK([for a readline compatible library], + ac_cv_lib_readline, [ + ORIG_LIBS=$LIBS + for readline_lib in readline edit editline; do + for termcap_lib in "" termcap curses ncurses; do + if test -z "$termcap_lib"; then + TRY_LIB="-l$readline_lib" + else + TRY_LIB="-l$readline_lib -l$termcap_lib" + fi + LIBS="$ORIG_LIBS $TRY_LIB" + AC_TRY_LINK_FUNC(readline, ac_cv_lib_readline="$TRY_LIB") + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -z "$ac_cv_lib_readline"; then + ac_cv_lib_readline="no" + LIBS=$ORIG_LIBS + fi + ]) + + if test "$ac_cv_lib_readline" != "no"; then + AC_DEFINE(HAVE_LIBREADLINE, 1, + [Define if you have a readline compatible library]) + AC_CHECK_HEADERS(readline.h readline/readline.h) + AC_CACHE_CHECK([whether readline supports history], + ac_cv_lib_readline_history, [ + ac_cv_lib_readline_history="no" + AC_TRY_LINK_FUNC(add_history, ac_cv_lib_readline_history="yes") + ]) + if test "$ac_cv_lib_readline_history" = "yes"; then + AC_DEFINE(HAVE_READLINE_HISTORY, 1, + [Define if your readline library has \`add_history']) + AC_CHECK_HEADERS(history.h readline/history.h) + fi + fi +]) + # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. @@ -103,7 +199,7 @@ fi dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) -AC_DEFUN(AM_INIT_AUTOMAKE, +AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) @@ -131,7 +227,7 @@ AC_REQUIRE([AC_PROG_MAKE_SET])]) # Check to make sure that the build environment is sane. # -AC_DEFUN(AM_SANITY_CHECK, +AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 @@ -172,7 +268,7 @@ AC_MSG_RESULT(yes)]) dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. -AC_DEFUN(AM_MISSING_PROG, +AC_DEFUN([AM_MISSING_PROG], [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. @@ -188,7 +284,7 @@ AC_SUBST($1)]) # Like AC_CONFIG_HEADER, but automatically create stamp file. -AC_DEFUN(AM_CONFIG_HEADER, +AC_DEFUN([AM_CONFIG_HEADER], [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. @@ -230,7 +326,7 @@ AC_DEFUN([AC_ISC_POSIX], # serial 1 -AC_DEFUN(AM_C_PROTOTYPES, +AC_DEFUN([AM_C_PROTOTYPES], [AC_REQUIRE([AM_PROG_CC_STDC]) AC_REQUIRE([AC_PROG_CPP]) AC_MSG_CHECKING([for function prototypes]) @@ -267,7 +363,7 @@ AC_SUBST(ANSI2KNR)dnl # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac -AC_DEFUN(AM_PROG_CC_STDC, +AC_DEFUN([AM_PROG_CC_STDC], [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) diff --git a/config.h.in b/config.h.in index 78dcde3..fd815a8 100644 --- a/config.h.in +++ b/config.h.in @@ -1,4 +1,4 @@ -/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if you have the strcoll function and it is properly defined. */ #undef HAVE_STRCOLL @@ -21,6 +21,9 @@ /* Define if you have the setlocale function. */ #undef HAVE_SETLOCALE +/* Define if you have the header file. */ +#undef HAVE_HISTORY_H + /* Define if you have the header file. */ #undef HAVE_LINUX_TERMIOS_H @@ -30,6 +33,15 @@ /* Define if you have the header file. */ #undef HAVE_NCURSES_H +/* Define if you have the header file. */ +#undef HAVE_READLINE_H + +/* Define if you have the header file. */ +#undef HAVE_READLINE_HISTORY_H + +/* Define if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + /* Define if you have the header file. */ #undef HAVE_STRING_H @@ -51,3 +63,9 @@ /* Define if compiler has function prototypes */ #undef PROTOTYPES +/* Define if you have a readline compatible library */ +#undef HAVE_LIBREADLINE + +/* Define if your readline library has `add_history' */ +#undef HAVE_READLINE_HISTORY + diff --git a/configure b/configure index 2027320..a4f2c48 100755 --- a/configure +++ b/configure @@ -2296,15 +2296,199 @@ fi + + echo $ac_n "checking for a readline compatible library""... $ac_c" 1>&6 +echo "configure:2302: checking for a readline compatible library" >&5 +if eval "test \"`echo '$''{'ac_cv_lib_readline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ORIG_LIBS=$LIBS + for readline_lib in readline edit editline; do + for termcap_lib in "" termcap curses ncurses; do + if test -z "$termcap_lib"; then + TRY_LIB="-l$readline_lib" + else + TRY_LIB="-l$readline_lib -l$termcap_lib" + fi + LIBS="$ORIG_LIBS $TRY_LIB" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_readline="$TRY_LIB" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -n "$ac_cv_lib_readline"; then + break + fi + done + if test -z "$ac_cv_lib_readline"; then + ac_cv_lib_readline="no" + LIBS=$ORIG_LIBS + fi + +fi + +echo "$ac_t""$ac_cv_lib_readline" 1>&6 + + if test "$ac_cv_lib_readline" != "no"; then + cat >> confdefs.h <<\EOF +#define HAVE_LIBREADLINE 1 +EOF + + for ac_hdr in readline.h readline/readline.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2362: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2372: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + echo $ac_n "checking whether readline supports history""... $ac_c" 1>&6 +echo "configure:2399: checking whether readline supports history" >&5 +if eval "test \"`echo '$''{'ac_cv_lib_readline_history'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_cv_lib_readline_history="no" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_readline_history="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_lib_readline_history" 1>&6 + if test "$ac_cv_lib_readline_history" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_READLINE_HISTORY 1 +EOF + + for ac_hdr in history.h readline/history.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2438: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2448: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + fi + fi + + +if test x$ac_lib_readline = xno -o x$ac_cv_lib_readline_history = xno; then + { echo "configure: error: *** readline library not found or it doesn't support history ***" 1>&2; exit 1; } +fi + +LDFLAGS="$ac_cv_lib_readline $LDFLAGS" + for ac_func in resizeterm do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2303: checking for $ac_func" >&5 +echo "configure:2487: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2353,12 +2537,12 @@ done echo $ac_n "checking for snprintf""... $ac_c" 1>&6 -echo "configure:2357: checking for snprintf" >&5 +echo "configure:2541: checking for snprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_snprintf=yes" else @@ -2404,12 +2588,12 @@ else fi echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6 -echo "configure:2408: checking for vsnprintf" >&5 +echo "configure:2592: checking for vsnprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vsnprintf=yes" else diff --git a/configure.in b/configure.in index 0ad64bc..d783cbe 100644 --- a/configure.in +++ b/configure.in @@ -46,6 +46,14 @@ dnl -------------------------- dnl end of (n)curses detection dnl -------------------------- +AC_LIB_READLINE + +if test x$ac_lib_readline = xno -o x$ac_cv_lib_readline_history = xno; then + AC_MSG_ERROR([*** readline library not found or it doesn't support history ***]) +fi + +LDFLAGS="$ac_cv_lib_readline $LDFLAGS" + AC_CHECK_FUNCS(resizeterm) AC_CHECK_FUNC(snprintf, [AC_DEFINE(HAVE_SNPRINTF)],) diff --git a/edit.c b/edit.c index 5edebec..90cc07d 100644 --- a/edit.c +++ b/edit.c @@ -182,42 +182,25 @@ editor_print_data(int tab, int item) } } -/* - * function: change_field - * - * parameters: - * (char *msg) - * message to display as a prompt - * (char **field) - * a pointer to pointer which will point a new string. if the latter - * pointer != NULL it will be freed (if user doesn't cancel) - * - * returns (int) - * a nonzero value if user has cancelled and zero if user has typed a - * valid string - */ - static int change_field(char *msg, char **field) { - char tmp[MAX_FIELD_LEN]; int max_len = MAX_FIELD_LEN; - int ret; + char *old; if( !strncmp("E-mail", msg, 6) ) max_len = MAX_EMAIL_LEN; - statusline_addstr(msg); - if( (ret = statusline_getnstr( tmp, max_len - 1, 0 ) ? 1:0 ) ) { - my_free(*field); - if( *tmp ) - *field = strdup(tmp); - } + old = *field; + + *field = ui_readline(msg, old, max_len - 1, 0); + + free(old); clear_statusline(); refresh_statusline(); - return !ret; + return 0; } static void @@ -246,24 +229,26 @@ fix_email_str(char *str) static void edit_emails(char c, int item) { - char *field = NULL; + char *field; char emails[MAX_EMAILS][MAX_EMAIL_LEN]; char tmp[MAX_EMAILSTR_LEN] = ""; int i, len; + int email_num = c - '2'; split_emailstr(item, emails); + field = strdup(emails[email_num]); if(change_field("E-mail: ", &field)) { #ifdef DEBUG fprintf(stderr, "change_field = TRUE\n"); #endif - return; /* user cancelled ( C-g ) */ + return; } if(field) { - strncpy(emails[c - '2'], field, MAX_EMAIL_LEN); - fix_email_str(emails[c - '2']); + strncpy(emails[email_num], field, MAX_EMAIL_LEN); + fix_email_str(emails[email_num]); } else - *emails[c - '2'] = 0; + *emails[email_num] = 0; my_free(database[item][EMAIL]); diff --git a/filter.c b/filter.c index 4a537b9..5eb1191 100644 --- a/filter.c +++ b/filter.c @@ -193,7 +193,7 @@ import_database() mvaddstr(5+filter, 2, "->"); - filename = ask_filename("Filename: ", 1); + filename = ask_filename("Filename: "); if( !filename ) { refresh_screen(); return 2; @@ -320,7 +320,7 @@ export_database() clear_statusline(); } - filename = ask_filename("Filename: ", 0); + filename = ask_filename("Filename: "); if( !filename ) { refresh_screen(); return 2; diff --git a/list.h b/list.h index 8a92dc6..d638979 100644 --- a/list.h +++ b/list.h @@ -30,7 +30,7 @@ enum { }; #define LIST_TOP 3 -#define LIST_BOTTOM (LINES-3) +#define LIST_BOTTOM (LINES-2) #define LIST_LINES (LIST_BOTTOM-LIST_TOP) #define LIST_COLS COLS diff --git a/ui.c b/ui.c index cd16862..4103eba 100644 --- a/ui.c +++ b/ui.c @@ -22,7 +22,6 @@ #include "misc.h" #include "options.h" #include "filter.h" -#include "estr.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -37,6 +36,8 @@ # include #endif +#include "abook_rl.h" + /* * external variables */ @@ -237,53 +238,21 @@ statusline_addstr(char *str) wrefresh(bottom); } -/* - * function statusline_getnstr - * - * parameters: - * (char *str) - * if n >= 0 str is a pointer which points a place where to store - * the string, else str is ignored - * (int n) - * the maximum length of the string - * If n < 0 function will allocate needed space for the string. - * Value 0 is not allowed for n. - * (int use_filesel) - * if this value is nonzero the fileselector is enabled - * - * returns (char *) - * If n < 0 a pointer to a newly allocated string is returned. - * If n > 0 a nonzero value is returned if user has typed a valid - * string. If not NULL value is returned. Never really use the - * _pointer_ if n > 0. - * - */ - char * -statusline_getnstr(char *str, int n, int use_filesel) +ui_readline(char *prompt, char *s, int limit, int use_completion) { - char *buf; int y, x; - getyx(bottom, y, x); - wmove(bottom, 1, x); - - buf = wenter_string(bottom, n, - (use_filesel ? ESTR_USE_FILESEL:0) | ESTR_DONT_WRAP); - - if(n < 0) - return buf; + mvwaddstr(bottom, 1, 0, prompt); + //mvwaddstr(stdscr, LINES - 1, 0, prompt); - if(buf == NULL) - str[0] = 0; - else - strncpy(str, buf, n); - - str[n-1] = 0; - - free(buf); + /* + * FIXME: stdscr shoulnd't be used ??? + */ +// getyx(stdscr, y, x); + getyx(bottom, y, x); - return buf; + return abook_readline(bottom, y, x, s, limit, use_completion); } int @@ -320,7 +289,6 @@ refresh_statusline() werase(bottom); mvwhline(bottom, 0, 0, UI_HLINE_CHAR, COLS); - mvwhline(bottom, 2, 0, UI_HLINE_CHAR, COLS); refresh(); wrefresh(bottom); @@ -328,16 +296,13 @@ refresh_statusline() char * -ask_filename(char *prompt, int flags) +ask_filename(char *prompt) { char *buf = NULL; clear_statusline(); - statusline_addstr(prompt); - buf = statusline_getnstr(NULL, -1, flags); - - clear_statusline(); + buf = ui_readline(prompt, NULL, -1, 1); return buf; } @@ -529,10 +494,11 @@ ui_find(int next) if( !*findstr ) return; } else { + char *s; clear_statusline(); - statusline_addstr("/"); - statusline_getnstr(findstr, MAX_FIELD_LEN - 1, 0); - clear_statusline(); + s = ui_readline("/", findstr, MAX_FIELD_LEN - 1, 0); + strncpy(findstr, s, MAX_FIELD_LEN); + refresh_screen(); } if( (item = find_item(findstr, curitem + !!next, @@ -611,9 +577,10 @@ ui_open_datafile() { char *filename; - filename = ask_filename("File to open: ", 1); + filename = ask_filename("File to open: "); - if( !filename ) { + if( !filename || ! *filename) { + free(filename); refresh_screen(); return; } diff --git a/ui.h b/ui.h index 8320079..da7cdfa 100644 --- a/ui.h +++ b/ui.h @@ -15,12 +15,12 @@ void close_ui(); void headerline(char *str); void refresh_screen(); int statusline_msg(char *msg); -char *ask_filename(char *prompt, int flags); +char *ask_filename(char *prompt); int statusline_ask_boolean(char *msg, int def); void clear_statusline(); void display_help(int help); void statusline_addstr(char *str); -char *statusline_getnstr(char *str, int n, int use_filesel); +char * ui_readline(char *prompt, char *s, int limit, int use_completion); void refresh_statusline(); void get_commands(); void ui_remove_items(); -- 2.39.2