Generalized readline support to dynamically load the readline library and avoid the symbol conflicts which happen on some platforms and some simulators with a global PC variable.

This commit is contained in:
Mark Pizzolato 2011-11-17 08:46:15 -08:00
parent 2d4d248ae3
commit 8b01b90008
2 changed files with 49 additions and 31 deletions

View file

@ -15,9 +15,6 @@
# In general, the logic below will detect and build with the available # In general, the logic below will detect and build with the available
# features which the host build environment provides. # features which the host build environment provides.
# #
# Readline support can be disabled if GNU make is invoked with
# DONT_USE_READLINE=1 on the command line.
#
# Internal ROM support can be disabled if GNU make is invoked with # Internal ROM support can be disabled if GNU make is invoked with
# DONT_USE_ROMS=1 on the command line. # DONT_USE_ROMS=1 on the command line.
# #
@ -67,7 +64,11 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
LIBPATH += /usr/pkg/lib LIBPATH += /usr/pkg/lib
OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib
endif endif
LIBEXT = a ifneq (,$(findstring NetBSD,$(shell uname))$(findstring FreeBSD,$(shell uname)))
LIBEXT = so
else
LIBEXT = a
endif
endif endif
endif endif
endif endif
@ -92,21 +93,15 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
$(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread)) $(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread))
endif endif
endif endif
ifeq ($(DONT_USE_READLINE),) ifneq (,$(call find_include,dlfcn))
ifneq (,$(call find_include,readline/readline)) ifneq (,$(call find_lib,dl))
ifneq (,$(call find_lib,readline)) OS_CCDEFS += -DHAVE_DLOPEN=$(LIBEXT)
# Use Locally installed and available readline support OS_LDFLAGS += -ldl
ifneq (,$(call find_lib,ncurses)) $(info using libdl: $(call find_lib,dl) $(call find_include,dlfcn))
OS_CCDEFS += -DHAVE_READLINE else
OS_LDFLAGS += -lreadline -lncurses ifeq (BSD,$(findstring BSD,$(shell uname)))
$(info using libreadline and libncurses: $(call find_lib,readline) $(call find_lib,ncurses) $(call find_include,readline/readline)) OS_CCDEFS += -DHAVE_DLOPEN=so
else $(info using libdl: $(call find_include,dlfcn))
ifneq (,$(call find_lib,curses))
OS_CCDEFS += -DHAVE_READLINE
OS_LDFLAGS += -lreadline -lcurses
$(info using libreadline and libcurses: $(call find_lib,readline) $(call find_lib,curses) $(call find_include,readline/readline))
endif
endif
endif endif
endif endif
endif endif

47
scp.c
View file

@ -213,9 +213,8 @@
#include <ctype.h> #include <ctype.h>
#include <time.h> #include <time.h>
#if defined(HAVE_READLINE) #if defined(HAVE_DLOPEN) /* Dynamic Readline support */
#include <readline/readline.h> #include <dlfcn.h>
#include <readline/history.h>
#endif #endif
#define EX_D 0 /* deposit */ #define EX_D 0 /* deposit */
@ -3841,15 +3840,39 @@ return read_line_p (NULL, cptr, size, stream);
char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream) char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream)
{ {
char *tptr; char *tptr;
#if defined(HAVE_DLOPEN)
static int initialized = 0;
static char *(*p_readline)(const char *) = NULL;
static void (*p_add_history)(const char *) = NULL;
#if defined(HAVE_READLINE) if (!initialized) {
initialized = 1;
void *handle;
#define __STR_QUOTE(tok) #tok
#define __STR(tok) __STR_QUOTE(tok)
handle = dlopen("libncurses." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL);
handle = dlopen("libreadline." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL);
if (handle) {
p_readline = dlsym(handle, "readline");
p_add_history = dlsym(handle, "add_history");
}
}
if (prompt) { /* interactive? */ if (prompt) { /* interactive? */
char *tmpc = readline (prompt); /* get cmd line */ char *tmpc;
if (tmpc == NULL) /* bad result? */
cptr = NULL; if (p_readline) {
char *tmpc = p_readline (prompt); /* get cmd line */
if (tmpc == NULL) /* bad result? */
cptr = NULL;
else {
strncpy (cptr, tmpc, size); /* copy result */
free (tmpc) ; /* free temp */
}
}
else { else {
strncpy (cptr, tmpc, size); /* copy result */ printf ("%s", prompt); /* display prompt */
free (tmpc) ; /* free temp */ cptr = fgets (cptr, size, stream); /* get cmd line */
} }
} }
else cptr = fgets (cptr, size, stream); /* get cmd line */ else cptr = fgets (cptr, size, stream); /* get cmd line */
@ -3875,9 +3898,9 @@ while (isspace (*cptr)) /* trim leading spc */
if (*cptr == ';') /* ignore comment */ if (*cptr == ';') /* ignore comment */
*cptr = 0; *cptr = 0;
#if defined (HAVE_READLINE) #if defined (HAVE_DLOPEN)
if (prompt) if (prompt && p_add_history && *cptr) /* Save non blank lines in history */
add_history (cptr); p_add_history (cptr);
#endif #endif
return cptr; return cptr;