From 8b01b900086f83c7f59aa128fbda0b390a0178ed Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 17 Nov 2011 08:46:15 -0800 Subject: [PATCH] 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. --- makefile | 33 ++++++++++++++------------------- scp.c | 47 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/makefile b/makefile index 15d8375f..b7499af5 100644 --- a/makefile +++ b/makefile @@ -15,9 +15,6 @@ # In general, the logic below will detect and build with the available # 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 # DONT_USE_ROMS=1 on the command line. # @@ -67,7 +64,11 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) LIBPATH += /usr/pkg/lib OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib endif - LIBEXT = a + ifneq (,$(findstring NetBSD,$(shell uname))$(findstring FreeBSD,$(shell uname))) + LIBEXT = so + else + LIBEXT = a + endif endif endif endif @@ -92,21 +93,15 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) $(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread)) endif endif - ifeq ($(DONT_USE_READLINE),) - ifneq (,$(call find_include,readline/readline)) - ifneq (,$(call find_lib,readline)) - # Use Locally installed and available readline support - ifneq (,$(call find_lib,ncurses)) - OS_CCDEFS += -DHAVE_READLINE - OS_LDFLAGS += -lreadline -lncurses - $(info using libreadline and libncurses: $(call find_lib,readline) $(call find_lib,ncurses) $(call find_include,readline/readline)) - else - 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 + ifneq (,$(call find_include,dlfcn)) + ifneq (,$(call find_lib,dl)) + OS_CCDEFS += -DHAVE_DLOPEN=$(LIBEXT) + OS_LDFLAGS += -ldl + $(info using libdl: $(call find_lib,dl) $(call find_include,dlfcn)) + else + ifeq (BSD,$(findstring BSD,$(shell uname))) + OS_CCDEFS += -DHAVE_DLOPEN=so + $(info using libdl: $(call find_include,dlfcn)) endif endif endif diff --git a/scp.c b/scp.c index 9473b947..3920db7d 100644 --- a/scp.c +++ b/scp.c @@ -213,9 +213,8 @@ #include #include -#if defined(HAVE_READLINE) -#include -#include +#if defined(HAVE_DLOPEN) /* Dynamic Readline support */ +#include #endif #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 *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? */ - char *tmpc = readline (prompt); /* get cmd line */ - if (tmpc == NULL) /* bad result? */ - cptr = NULL; + char *tmpc; + + 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 { - strncpy (cptr, tmpc, size); /* copy result */ - free (tmpc) ; /* free temp */ + printf ("%s", prompt); /* display prompt */ + 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 */ *cptr = 0; -#if defined (HAVE_READLINE) -if (prompt) - add_history (cptr); +#if defined (HAVE_DLOPEN) +if (prompt && p_add_history && *cptr) /* Save non blank lines in history */ + p_add_history (cptr); #endif return cptr;