1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * Copyright 2003 by MIT Student Information Processing Board
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Permission to use, copy, modify, and distribute this software and
5*6a54128fSAndroid Build Coastguard Worker * its documentation for any purpose is hereby granted, provided that
6*6a54128fSAndroid Build Coastguard Worker * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
7*6a54128fSAndroid Build Coastguard Worker * advertising or publicity pertaining to distribution of the software
8*6a54128fSAndroid Build Coastguard Worker * without specific, written prior permission. M.I.T. and the
9*6a54128fSAndroid Build Coastguard Worker * M.I.T. S.I.P.B. make no representations about the suitability of
10*6a54128fSAndroid Build Coastguard Worker * this software for any purpose. It is provided "as is" without
11*6a54128fSAndroid Build Coastguard Worker * express or implied warranty.
12*6a54128fSAndroid Build Coastguard Worker */
13*6a54128fSAndroid Build Coastguard Worker
14*6a54128fSAndroid Build Coastguard Worker #include "config.h"
15*6a54128fSAndroid Build Coastguard Worker #ifdef HAS_STDLIB_H
16*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker #include "ss_internal.h"
19*6a54128fSAndroid Build Coastguard Worker #define size sizeof(ss_data *)
20*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_DLOPEN
21*6a54128fSAndroid Build Coastguard Worker #include <dlfcn.h>
22*6a54128fSAndroid Build Coastguard Worker #endif
23*6a54128fSAndroid Build Coastguard Worker
24*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_DLOPEN
ss_release_readline(ss_data * info)25*6a54128fSAndroid Build Coastguard Worker static void ss_release_readline(ss_data *info)
26*6a54128fSAndroid Build Coastguard Worker {
27*6a54128fSAndroid Build Coastguard Worker if (!info->readline_handle)
28*6a54128fSAndroid Build Coastguard Worker return;
29*6a54128fSAndroid Build Coastguard Worker
30*6a54128fSAndroid Build Coastguard Worker info->readline = 0;
31*6a54128fSAndroid Build Coastguard Worker info->add_history = 0;
32*6a54128fSAndroid Build Coastguard Worker info->redisplay = 0;
33*6a54128fSAndroid Build Coastguard Worker info->rl_completion_matches = 0;
34*6a54128fSAndroid Build Coastguard Worker dlclose(info->readline_handle);
35*6a54128fSAndroid Build Coastguard Worker info->readline_handle = 0;
36*6a54128fSAndroid Build Coastguard Worker }
37*6a54128fSAndroid Build Coastguard Worker #endif
38*6a54128fSAndroid Build Coastguard Worker
39*6a54128fSAndroid Build Coastguard Worker /* Libraries we will try to use for readline/editline functionality */
40*6a54128fSAndroid Build Coastguard Worker #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"
41*6a54128fSAndroid Build Coastguard Worker
42*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_DLOPEN
ss_get_readline(int sci_idx)43*6a54128fSAndroid Build Coastguard Worker void ss_get_readline(int sci_idx)
44*6a54128fSAndroid Build Coastguard Worker {
45*6a54128fSAndroid Build Coastguard Worker void *handle = NULL;
46*6a54128fSAndroid Build Coastguard Worker ss_data *info = ss_info(sci_idx);
47*6a54128fSAndroid Build Coastguard Worker const char **t, *libpath = 0;
48*6a54128fSAndroid Build Coastguard Worker char *tmp, *cp, *next;
49*6a54128fSAndroid Build Coastguard Worker char **(**completion_func)(const char *, int, int);
50*6a54128fSAndroid Build Coastguard Worker
51*6a54128fSAndroid Build Coastguard Worker if (info->readline_handle)
52*6a54128fSAndroid Build Coastguard Worker return;
53*6a54128fSAndroid Build Coastguard Worker
54*6a54128fSAndroid Build Coastguard Worker libpath = ss_safe_getenv("SS_READLINE_PATH");
55*6a54128fSAndroid Build Coastguard Worker if (!libpath)
56*6a54128fSAndroid Build Coastguard Worker libpath = DEFAULT_LIBPATH;
57*6a54128fSAndroid Build Coastguard Worker if (*libpath == 0 || !strcmp(libpath, "none"))
58*6a54128fSAndroid Build Coastguard Worker return;
59*6a54128fSAndroid Build Coastguard Worker
60*6a54128fSAndroid Build Coastguard Worker tmp = malloc(strlen(libpath)+1);
61*6a54128fSAndroid Build Coastguard Worker if (!tmp)
62*6a54128fSAndroid Build Coastguard Worker return;
63*6a54128fSAndroid Build Coastguard Worker strcpy(tmp, libpath);
64*6a54128fSAndroid Build Coastguard Worker for (cp = tmp; cp; cp = next) {
65*6a54128fSAndroid Build Coastguard Worker next = strchr(cp, ':');
66*6a54128fSAndroid Build Coastguard Worker if (next)
67*6a54128fSAndroid Build Coastguard Worker *next++ = 0;
68*6a54128fSAndroid Build Coastguard Worker if (*cp == 0)
69*6a54128fSAndroid Build Coastguard Worker continue;
70*6a54128fSAndroid Build Coastguard Worker if ((handle = dlopen(cp, RTLD_NOW))) {
71*6a54128fSAndroid Build Coastguard Worker /* printf("Using %s for readline library\n", cp); */
72*6a54128fSAndroid Build Coastguard Worker break;
73*6a54128fSAndroid Build Coastguard Worker }
74*6a54128fSAndroid Build Coastguard Worker }
75*6a54128fSAndroid Build Coastguard Worker free(tmp);
76*6a54128fSAndroid Build Coastguard Worker if (!handle)
77*6a54128fSAndroid Build Coastguard Worker return;
78*6a54128fSAndroid Build Coastguard Worker
79*6a54128fSAndroid Build Coastguard Worker info->readline_handle = handle;
80*6a54128fSAndroid Build Coastguard Worker info->readline = (char *(*)(const char *))
81*6a54128fSAndroid Build Coastguard Worker dlsym(handle, "readline");
82*6a54128fSAndroid Build Coastguard Worker info->add_history = (void (*)(const char *))
83*6a54128fSAndroid Build Coastguard Worker dlsym(handle, "add_history");
84*6a54128fSAndroid Build Coastguard Worker info->redisplay = (void (*)(void))
85*6a54128fSAndroid Build Coastguard Worker dlsym(handle, "rl_forced_update_display");
86*6a54128fSAndroid Build Coastguard Worker info->rl_completion_matches = (char **(*)(const char *,
87*6a54128fSAndroid Build Coastguard Worker char *(*)(const char *, int)))
88*6a54128fSAndroid Build Coastguard Worker dlsym(handle, "rl_completion_matches");
89*6a54128fSAndroid Build Coastguard Worker if ((t = dlsym(handle, "rl_readline_name")) != NULL)
90*6a54128fSAndroid Build Coastguard Worker *t = info->subsystem_name;
91*6a54128fSAndroid Build Coastguard Worker if ((completion_func =
92*6a54128fSAndroid Build Coastguard Worker dlsym(handle, "rl_attempted_completion_function")) != NULL)
93*6a54128fSAndroid Build Coastguard Worker *completion_func = ss_rl_completion;
94*6a54128fSAndroid Build Coastguard Worker info->readline_shutdown = ss_release_readline;
95*6a54128fSAndroid Build Coastguard Worker }
96*6a54128fSAndroid Build Coastguard Worker #else
ss_get_readline(int sci_idx __SS_ATTR ((unused)))97*6a54128fSAndroid Build Coastguard Worker void ss_get_readline(int sci_idx __SS_ATTR((unused)))
98*6a54128fSAndroid Build Coastguard Worker {
99*6a54128fSAndroid Build Coastguard Worker }
100*6a54128fSAndroid Build Coastguard Worker #endif
101