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 #ifdef HAS_STDLIB_H 15 #include <stdlib.h> 16 #endif 17 #include "ss_internal.h" 18 #define size sizeof(ss_data *) 19 #ifdef HAVE_DLOPEN 20 #include <dlfcn.h> 21 #endif 22 23 static void ss_release_readline(ss_data *info) 24 { 25 #ifdef HAVE_DLOPEN 26 if (!info->readline_handle) 27 return; 28 29 info->readline = 0; 30 info->add_history = 0; 31 info->redisplay = 0; 32 info->rl_completion_matches = 0; 33 dlclose(info->readline_handle); 34 info->readline_handle = 0; 35 #endif 36 } 37 38 /* Libraries we will try to use for readline/editline functionality */ 39 #define DEFAULT_LIBPATH "libreadline.so.6:libreadline.so.5:libreadline.so.4:libreadline.so:libedit.so.2:libedit.so:libeditline.so.0:libeditline.so" 40 41 void ss_get_readline(int sci_idx) 42 { 43 #ifdef HAVE_DLOPEN 44 void *handle = NULL; 45 ss_data *info = ss_info(sci_idx); 46 const char **t, *libpath = 0; 47 char *tmp, *cp, *next; 48 char **(**completion_func)(const char *, int, int); 49 50 if (info->readline_handle) 51 return; 52 53 libpath = ss_safe_getenv("SS_READLINE_PATH"); 54 if (!libpath) 55 libpath = DEFAULT_LIBPATH; 56 if (*libpath == 0 || !strcmp(libpath, "none")) 57 return; 58 59 tmp = malloc(strlen(libpath)+1); 60 if (!tmp) 61 return; 62 strcpy(tmp, libpath); 63 for (cp = tmp; cp; cp = next) { 64 next = strchr(cp, ':'); 65 if (next) 66 *next++ = 0; 67 if (*cp == 0) 68 continue; 69 if ((handle = dlopen(cp, RTLD_NOW))) { 70 /* printf("Using %s for readline library\n", cp); */ 71 break; 72 } 73 } 74 free(tmp); 75 if (!handle) 76 return; 77 78 info->readline_handle = handle; 79 info->readline = (char *(*)(const char *)) 80 dlsym(handle, "readline"); 81 info->add_history = (void (*)(const char *)) 82 dlsym(handle, "add_history"); 83 info->redisplay = (void (*)(void)) 84 dlsym(handle, "rl_forced_update_display"); 85 info->rl_completion_matches = (char **(*)(const char *, 86 char *(*)(const char *, int))) 87 dlsym(handle, "rl_completion_matches"); 88 if ((t = dlsym(handle, "rl_readline_name")) != NULL) 89 *t = info->subsystem_name; 90 if ((completion_func = 91 dlsym(handle, "rl_attempted_completion_function")) != NULL) 92 *completion_func = ss_rl_completion; 93 info->readline_shutdown = ss_release_readline; 94 #endif 95 } 96 97 98