Mercurial > vim
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 { |