comparison src/if_tcl.c @ 7538:c9fc24b76293 v7.4.1070

commit https://github.com/vim/vim/commit/8a5115cf18751022387af2085f374d38c60dde83 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 9 19:41:11 2016 +0100 patch 7.4.1070 Problem: The Tcl interface can't be loaded dynamically on Unix. Solution: Make it possible to load it dynamically. (Ken Takata)
author Christian Brabandt <cb@256bit.org>
date Sat, 09 Jan 2016 19:45:05 +0100
parents 1e621b31948b
children aee06f1762e0
comparison
equal deleted inserted replaced
7537:e1a5a830aebb 7538:c9fc24b76293
158 158
159 # ifndef DYNAMIC_TCL /* Just generating prototypes */ 159 # ifndef DYNAMIC_TCL /* Just generating prototypes */
160 typedef int HANDLE; 160 typedef int HANDLE;
161 # endif 161 # endif
162 162
163 # ifndef WIN3264
164 # include <dlfcn.h>
165 # define HANDLE void*
166 # define TCL_PROC void*
167 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
168 # define symbol_from_dll dlsym
169 # define close_dll dlclose
170 # else
171 # define TCL_PROC FARPROC
172 # define load_dll vimLoadLib
173 # define symbol_from_dll GetProcAddress
174 # define close_dll FreeLibrary
175 # endif
176
163 /* 177 /*
164 * Declare HANDLE for tcl.dll and function pointers. 178 * Declare HANDLE for tcl.dll and function pointers.
165 */ 179 */
166 static HANDLE hTclLib = NULL; 180 static HANDLE hTclLib = NULL;
167 Tcl_Interp* (*dll_Tcl_CreateInterp)(); 181 Tcl_Interp* (*dll_Tcl_CreateInterp)();
168 void (*dll_Tcl_FindExecutable)(const void *); 182 void (*dll_Tcl_FindExecutable)(const void *);
169 183
170 /* 184 /*
171 * Table of name to function pointer of tcl. 185 * Table of name to function pointer of tcl.
172 */ 186 */
173 #define TCL_PROC FARPROC
174 static struct { 187 static struct {
175 char* name; 188 char* name;
176 TCL_PROC* ptr; 189 TCL_PROC* ptr;
177 } tcl_funcname_table[] = { 190 } tcl_funcname_table[] = {
178 {"Tcl_CreateInterp", (TCL_PROC*)&dll_Tcl_CreateInterp}, 191 {"Tcl_CreateInterp", (TCL_PROC*)&dll_Tcl_CreateInterp},
195 { 208 {
196 int i; 209 int i;
197 210
198 if (hTclLib) 211 if (hTclLib)
199 return OK; 212 return OK;
200 if (!(hTclLib = vimLoadLib(libname))) 213 if (!(hTclLib = load_dll(libname)))
201 { 214 {
202 if (verbose) 215 if (verbose)
203 EMSG2(_(e_loadlib), libname); 216 EMSG2(_(e_loadlib), libname);
204 return FAIL; 217 return FAIL;
205 } 218 }
206 for (i = 0; tcl_funcname_table[i].ptr; ++i) 219 for (i = 0; tcl_funcname_table[i].ptr; ++i)
207 { 220 {
208 if (!(*tcl_funcname_table[i].ptr = GetProcAddress(hTclLib, 221 if (!(*tcl_funcname_table[i].ptr = symbol_from_dll(hTclLib,
209 tcl_funcname_table[i].name))) 222 tcl_funcname_table[i].name)))
210 { 223 {
211 FreeLibrary(hTclLib); 224 close_dll(hTclLib);
212 hTclLib = NULL; 225 hTclLib = NULL;
213 if (verbose) 226 if (verbose)
214 EMSG2(_(e_loadfunc), tcl_funcname_table[i].name); 227 EMSG2(_(e_loadfunc), tcl_funcname_table[i].name);
215 return FAIL; 228 return FAIL;
216 } 229 }
244 int 257 int
245 tcl_enabled(verbose) 258 tcl_enabled(verbose)
246 int verbose; 259 int verbose;
247 { 260 {
248 if (!stubs_initialized && find_executable_arg != NULL 261 if (!stubs_initialized && find_executable_arg != NULL
249 && tcl_runtime_link_init(DYNAMIC_TCL_DLL, verbose) == OK) 262 && tcl_runtime_link_init((char *)p_tcldll, verbose) == OK)
250 { 263 {
251 Tcl_Interp *interp; 264 Tcl_Interp *interp;
252 265
253 dll_Tcl_FindExecutable(find_executable_arg); 266 dll_Tcl_FindExecutable(find_executable_arg);
254 267
255 if (interp = dll_Tcl_CreateInterp()) 268 if ((interp = dll_Tcl_CreateInterp()) != NULL)
256 { 269 {
257 if (Tcl_InitStubs(interp, DYNAMIC_TCL_VER, 0)) 270 if (Tcl_InitStubs(interp, DYNAMIC_TCL_VER, 0))
258 { 271 {
259 Tcl_DeleteInterp(interp); 272 Tcl_DeleteInterp(interp);
260 stubs_initialized = TRUE; 273 stubs_initialized = TRUE;
270 tcl_end() 283 tcl_end()
271 { 284 {
272 #ifdef DYNAMIC_TCL 285 #ifdef DYNAMIC_TCL
273 if (hTclLib) 286 if (hTclLib)
274 { 287 {
275 FreeLibrary(hTclLib); 288 close_dll(hTclLib);
276 hTclLib = NULL; 289 hTclLib = NULL;
277 } 290 }
278 #endif 291 #endif
279 } 292 }
280 293
2037 { 2050 {
2038 struct ref *next; 2051 struct ref *next;
2039 int err; 2052 int err;
2040 char *result; 2053 char *result;
2041 2054
2055 /* TODO: this code currently crashes Vim on exit */
2056 if (exiting)
2057 return;
2058
2042 while (ref != NULL) 2059 while (ref != NULL)
2043 { 2060 {
2044 next = ref->next; 2061 next = ref->next;
2045 if (ref->interp) 2062 if (ref->interp)
2046 { 2063 {