diff options
Diffstat (limited to 'lib/ss/get_readline.c')
-rw-r--r-- | lib/ss/get_readline.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/ss/get_readline.c b/lib/ss/get_readline.c new file mode 100644 index 0000000..aa16157 --- /dev/null +++ b/lib/ss/get_readline.c @@ -0,0 +1,100 @@ +/* + * Copyright 2003 by MIT Student Information Processing Board + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose is hereby granted, provided that + * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. M.I.T. and the + * M.I.T. S.I.P.B. make no representations about the suitability of + * this software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include "config.h" +#ifdef HAS_STDLIB_H +#include <stdlib.h> +#endif +#include "ss_internal.h" +#define size sizeof(ss_data *) +#ifdef HAVE_DLOPEN +#include <dlfcn.h> +#endif + +#ifdef HAVE_DLOPEN +static void ss_release_readline(ss_data *info) +{ + if (!info->readline_handle) + return; + + info->readline = 0; + info->add_history = 0; + info->redisplay = 0; + info->rl_completion_matches = 0; + dlclose(info->readline_handle); + info->readline_handle = 0; +} +#endif + +/* Libraries we will try to use for readline/editline functionality */ +#define DEFAULT_LIBPATH "libreadline.so.8:libreadline.so.7:libreadline.so.6:libreadline.so.5:libreadline.so.4:libreadline.so:libedit.so.2:libedit.so:libeditline.so.0:libeditline.so" + +#ifdef HAVE_DLOPEN +void ss_get_readline(int sci_idx) +{ + void *handle = NULL; + ss_data *info = ss_info(sci_idx); + const char **t, *libpath = 0; + char *tmp, *cp, *next; + char **(**completion_func)(const char *, int, int); + + if (info->readline_handle) + return; + + libpath = ss_safe_getenv("SS_READLINE_PATH"); + if (!libpath) + libpath = DEFAULT_LIBPATH; + if (*libpath == 0 || !strcmp(libpath, "none")) + return; + + tmp = malloc(strlen(libpath)+1); + if (!tmp) + return; + strcpy(tmp, libpath); + for (cp = tmp; cp; cp = next) { + next = strchr(cp, ':'); + if (next) + *next++ = 0; + if (*cp == 0) + continue; + if ((handle = dlopen(cp, RTLD_NOW))) { + /* printf("Using %s for readline library\n", cp); */ + break; + } + } + free(tmp); + if (!handle) + return; + + info->readline_handle = handle; + info->readline = (char *(*)(const char *)) + dlsym(handle, "readline"); + info->add_history = (void (*)(const char *)) + dlsym(handle, "add_history"); + info->redisplay = (void (*)(void)) + dlsym(handle, "rl_forced_update_display"); + info->rl_completion_matches = (char **(*)(const char *, + char *(*)(const char *, int))) + dlsym(handle, "rl_completion_matches"); + if ((t = dlsym(handle, "rl_readline_name")) != NULL) + *t = info->subsystem_name; + if ((completion_func = + dlsym(handle, "rl_attempted_completion_function")) != NULL) + *completion_func = ss_rl_completion; + info->readline_shutdown = ss_release_readline; +} +#else +void ss_get_readline(int sci_idx __SS_ATTR((unused))) +{ +} +#endif |