summaryrefslogtreecommitdiffstats
path: root/lib/ss/get_readline.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ss/get_readline.c')
-rw-r--r--lib/ss/get_readline.c100
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