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