diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-01-09 19:41:11 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-01-09 19:41:11 +0100 |
commit | 8a5115cf18751022387af2085f374d38c60dde83 (patch) | |
tree | 626c3e93cd3127931c85e631d50d6ced1b5f6380 /src | |
parent | 5f24542e5eda590acdbee89b120fa2e19ec7596e (diff) | |
download | vim-git-8a5115cf18751022387af2085f374d38c60dde83.tar.gz |
patch 7.4.1070v7.4.1070
Problem: The Tcl interface can't be loaded dynamically on Unix.
Solution: Make it possible to load it dynamically. (Ken Takata)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 10 | ||||
-rwxr-xr-x | src/auto/configure | 18 | ||||
-rw-r--r-- | src/config.h.in | 3 | ||||
-rw-r--r-- | src/configure.in | 17 | ||||
-rw-r--r-- | src/if_tcl.c | 31 | ||||
-rw-r--r-- | src/option.c | 6 | ||||
-rw-r--r-- | src/option.h | 3 | ||||
-rw-r--r-- | src/version.c | 2 |
8 files changed, 73 insertions, 17 deletions
diff --git a/src/Makefile b/src/Makefile index 5cf116d5a..72f0eaaf2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -445,7 +445,9 @@ CClink = $(CC) # TCL # Uncomment this when you want to include the Tcl interface. +# First one is for static linking, second one for dynamic loading. #CONF_OPT_TCL = --enable-tclinterp +#CONF_OPT_TCL = --enable-tclinterp=dynamic #CONF_OPT_TCL = --enable-tclinterp --with-tclsh=tclsh8.4 # CSCOPE @@ -1375,7 +1377,7 @@ SHELL = /bin/sh .SUFFIXES: .c .o .pro PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) $(EXTRA_IPATHS) -POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(TCL_CFLAGS) $(EXTRA_DEFS) +POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(EXTRA_DEFS) ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(SANITIZER_CFLAGS) $(LEAK_CFLAGS) $(POST_DEFS) @@ -1383,7 +1385,7 @@ ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(SANITIZER_CFLAGS) $(LEAK_ # with "-E". OSDEF_CFLAGS = $(PRE_DEFS) $(POST_DEFS) -LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(RUBY_CFLAGS) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca +LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(RUBY_CFLAGS) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(TCL_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca LINT_EXTRA = -DUSE_SNIFF -DHANGUL_INPUT -D"__attribute__(x)=" @@ -2756,7 +2758,7 @@ objects/if_sniff.o: if_sniff.c $(CCC) -o $@ if_sniff.c objects/if_tcl.o: if_tcl.c - $(CCC) -o $@ if_tcl.c + $(CCC) $(TCL_CFLAGS) -o $@ if_tcl.c objects/integration.o: integration.c $(CCC) -o $@ integration.c @@ -2801,7 +2803,7 @@ objects/ops.o: ops.c $(CCC) -o $@ ops.c objects/option.o: option.c - $(CCC) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) -o $@ option.c + $(CCC) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) $(TCL_CFLAGS) -o $@ option.c objects/os_beos.o: os_beos.c $(CCC) -o $@ os_beos.c diff --git a/src/auto/configure b/src/auto/configure index a0452795a..e07d7ecf3 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -1468,7 +1468,7 @@ Optional Features: --enable-perlinterp=OPTS Include Perl interpreter. default=no OPTS=no/yes/dynamic --enable-pythoninterp=OPTS Include Python interpreter. default=no OPTS=no/yes/dynamic --enable-python3interp=OPTS Include Python3 interpreter. default=no OPTS=no/yes/dynamic - --enable-tclinterp Include Tcl interpreter. + --enable-tclinterp=OPTS Include Tcl interpreter. default=no OPTS=no/yes/dynamic --enable-rubyinterp=OPTS Include Ruby interpreter. default=no OPTS=no/yes/dynamic --enable-cscope Include cscope interface. --enable-workshop Include Sun Visual Workshop support. @@ -6616,7 +6616,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_tclinterp" >&5 $as_echo "$enable_tclinterp" >&6; } -if test "$enable_tclinterp" = "yes"; then +if test "$enable_tclinterp" = "yes" -o "$enable_tclinterp" = "dynamic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking --with-tclsh argument" >&5 $as_echo_n "checking --with-tclsh argument... " >&6; } @@ -6852,6 +6852,7 @@ $as_echo_n "checking Tcl version... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tclver - OK" >&5 $as_echo "$tclver - OK" >&6; }; tclloc=`echo 'set l [info library];set i [string last lib $l];incr i -2;puts [string range $l 0 $i]' | $vi_cv_path_tcl -` + tcldll=`echo 'puts libtcl[info tclversion][info sharedlibextension]' | $vi_cv_path_tcl -` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for location of Tcl include" >&5 $as_echo_n "checking for location of Tcl include... " >&6; } @@ -6888,7 +6889,11 @@ $as_echo_n "checking for location of tclConfig.sh script... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try/tclConfig.sh" >&5 $as_echo "$try/tclConfig.sh" >&6; } . "$try/tclConfig.sh" - TCL_LIBS=`eval echo "$TCL_LIB_SPEC $TCL_LIBS"` + if test "$enable_tclinterp" = "dynamic"; then + TCL_LIBS=`eval echo "$TCL_STUB_LIB_SPEC $TCL_LIBS"` + else + TCL_LIBS=`eval echo "$TCL_LIB_SPEC $TCL_LIBS"` + fi TCL_DEFS=`echo $TCL_DEFS | sed -e 's/\\\\ /\\\\X/g' | tr ' ' '\012' | sed -e '/^[^-]/d' -e '/^-[^D]/d' -e '/-D[^_]/d' -e 's/-D_/ -D_/' | tr '\012' ' ' | sed -e 's/\\\\X/\\\\ /g'` break fi @@ -6937,6 +6942,13 @@ $as_echo "<not found>" >&6; } $as_echo "too old; need Tcl version 8.0 or later" >&6; } fi fi + if test "$enable_tclinterp" = "dynamic"; then + if test "X$TCL_SRC" != "X" -a "X$tcldll" != "X"; then + $as_echo "#define DYNAMIC_TCL 1" >>confdefs.h + + TCL_CFLAGS="-DDYNAMIC_TCL_DLL=\\\"$tcldll\\\" -DDYNAMIC_TCL_VER=\\\"$tclver\\\" $TCL_CFLAGS" + fi + fi if test "$fail_if_missing" = "yes" -a -z "$TCL_SRC"; then as_fn_error $? "could not configure Tcl" "$LINENO" 5 fi diff --git a/src/config.h.in b/src/config.h.in index e92cc5e9f..d4fd50a37 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -360,6 +360,9 @@ /* Define if you want to include the Tcl interpreter. */ #undef FEAT_TCL +/* Define for linking via dlopen() or LoadLibrary() */ +#undef DYNAMIC_TCL + /* Define if you want to include the Sniff interface. */ #undef FEAT_SNIFF diff --git a/src/configure.in b/src/configure.in index 17368c1ac..6048e8f9c 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1622,11 +1622,11 @@ fi AC_MSG_CHECKING(--enable-tclinterp argument) AC_ARG_ENABLE(tclinterp, - [ --enable-tclinterp Include Tcl interpreter.], , + [ --enable-tclinterp[=OPTS] Include Tcl interpreter. [default=no] [OPTS=no/yes/dynamic]], , [enable_tclinterp="no"]) AC_MSG_RESULT($enable_tclinterp) -if test "$enable_tclinterp" = "yes"; then +if test "$enable_tclinterp" = "yes" -o "$enable_tclinterp" = "dynamic"; then dnl on FreeBSD tclsh is a silly script, look for tclsh8.[5420] AC_MSG_CHECKING(--with-tclsh argument) @@ -1660,6 +1660,7 @@ if test "$enable_tclinterp" = "yes"; then tclver=`echo 'puts [[info tclversion]]' | $vi_cv_path_tcl -` AC_MSG_RESULT($tclver - OK); tclloc=`echo 'set l [[info library]];set i [[string last lib $l]];incr i -2;puts [[string range $l 0 $i]]' | $vi_cv_path_tcl -` + tcldll=`echo 'puts libtcl[[info tclversion]][[info sharedlibextension]]' | $vi_cv_path_tcl -` AC_MSG_CHECKING(for location of Tcl include) if test "x$MACOSX" != "xyes"; then @@ -1694,7 +1695,11 @@ if test "$enable_tclinterp" = "yes"; then AC_MSG_RESULT($try/tclConfig.sh) . "$try/tclConfig.sh" dnl use eval, because tcl 8.2 includes ${TCL_DBGX} - TCL_LIBS=`eval echo "$TCL_LIB_SPEC $TCL_LIBS"` + if test "$enable_tclinterp" = "dynamic"; then + TCL_LIBS=`eval echo "$TCL_STUB_LIB_SPEC $TCL_LIBS"` + else + TCL_LIBS=`eval echo "$TCL_LIB_SPEC $TCL_LIBS"` + fi dnl Use $TCL_DEFS for -D_THREAD_SAFE et al. But only use the dnl "-D_ABC" items. Watch out for -DFOO=long\ long. TCL_DEFS=`echo $TCL_DEFS | sed -e 's/\\\\ /\\\\X/g' | tr ' ' '\012' | sed -e '/^[[^-]]/d' -e '/^-[[^D]]/d' -e '/-D[[^_]]/d' -e 's/-D_/ -D_/' | tr '\012' ' ' | sed -e 's/\\\\X/\\\\ /g'` @@ -1739,6 +1744,12 @@ if test "$enable_tclinterp" = "yes"; then AC_MSG_RESULT(too old; need Tcl version 8.0 or later) fi fi + if test "$enable_tclinterp" = "dynamic"; then + if test "X$TCL_SRC" != "X" -a "X$tcldll" != "X"; then + AC_DEFINE(DYNAMIC_TCL) + TCL_CFLAGS="-DDYNAMIC_TCL_DLL=\\\"$tcldll\\\" -DDYNAMIC_TCL_VER=\\\"$tclver\\\" $TCL_CFLAGS" + fi + fi if test "$fail_if_missing" = "yes" -a -z "$TCL_SRC"; then AC_MSG_ERROR([could not configure Tcl]) fi diff --git a/src/if_tcl.c b/src/if_tcl.c index 1f37e1277..995a5c727 100644 --- a/src/if_tcl.c +++ b/src/if_tcl.c @@ -160,6 +160,20 @@ static struct ref refsdeleted; /* dummy object for deleted ref list */ typedef int HANDLE; # endif +# ifndef WIN3264 +# include <dlfcn.h> +# define HANDLE void* +# define TCL_PROC void* +# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL) +# define symbol_from_dll dlsym +# define close_dll dlclose +# else +# define TCL_PROC FARPROC +# define load_dll vimLoadLib +# define symbol_from_dll GetProcAddress +# define close_dll FreeLibrary +# endif + /* * Declare HANDLE for tcl.dll and function pointers. */ @@ -170,7 +184,6 @@ void (*dll_Tcl_FindExecutable)(const void *); /* * Table of name to function pointer of tcl. */ -#define TCL_PROC FARPROC static struct { char* name; TCL_PROC* ptr; @@ -197,7 +210,7 @@ tcl_runtime_link_init(char *libname, int verbose) if (hTclLib) return OK; - if (!(hTclLib = vimLoadLib(libname))) + if (!(hTclLib = load_dll(libname))) { if (verbose) EMSG2(_(e_loadlib), libname); @@ -205,10 +218,10 @@ tcl_runtime_link_init(char *libname, int verbose) } for (i = 0; tcl_funcname_table[i].ptr; ++i) { - if (!(*tcl_funcname_table[i].ptr = GetProcAddress(hTclLib, + if (!(*tcl_funcname_table[i].ptr = symbol_from_dll(hTclLib, tcl_funcname_table[i].name))) { - FreeLibrary(hTclLib); + close_dll(hTclLib); hTclLib = NULL; if (verbose) EMSG2(_(e_loadfunc), tcl_funcname_table[i].name); @@ -246,13 +259,13 @@ tcl_enabled(verbose) int verbose; { if (!stubs_initialized && find_executable_arg != NULL - && tcl_runtime_link_init(DYNAMIC_TCL_DLL, verbose) == OK) + && tcl_runtime_link_init((char *)p_tcldll, verbose) == OK) { Tcl_Interp *interp; dll_Tcl_FindExecutable(find_executable_arg); - if (interp = dll_Tcl_CreateInterp()) + if ((interp = dll_Tcl_CreateInterp()) != NULL) { if (Tcl_InitStubs(interp, DYNAMIC_TCL_VER, 0)) { @@ -272,7 +285,7 @@ tcl_end() #ifdef DYNAMIC_TCL if (hTclLib) { - FreeLibrary(hTclLib); + close_dll(hTclLib); hTclLib = NULL; } #endif @@ -2039,6 +2052,10 @@ tcldelallrefs(ref) int err; char *result; + /* TODO: this code currently crashes Vim on exit */ + if (exiting) + return; + while (ref != NULL) { next = ref->next; diff --git a/src/option.c b/src/option.c index 9e7f30327..bc88d4554 100644 --- a/src/option.c +++ b/src/option.c @@ -2609,6 +2609,12 @@ static struct vimoption {"tagstack", "tgst", P_BOOL|P_VI_DEF, (char_u *)&p_tgst, PV_NONE, {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT}, +#if defined(DYNAMIC_TCL) + {"tcldll", NULL, P_STRING|P_VI_DEF|P_SECURE, + (char_u *)&p_tcldll, PV_NONE, + {(char_u *)DYNAMIC_TCL_DLL, (char_u *)0L} + SCRIPTID_INIT}, +#endif {"term", NULL, P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL, (char_u *)&T_NAME, PV_NONE, {(char_u *)"", (char_u *)0L} SCRIPTID_INIT}, diff --git a/src/option.h b/src/option.h index af5b98896..f178ea7f8 100644 --- a/src/option.h +++ b/src/option.h @@ -832,6 +832,9 @@ EXTERN long p_tl; /* 'taglength' */ EXTERN int p_tr; /* 'tagrelative' */ EXTERN char_u *p_tags; /* 'tags' */ EXTERN int p_tgst; /* 'tagstack' */ +#if defined(DYNAMIC_TCL) +EXTERN char_u *p_tcldll; /* 'tcldll' */ +#endif #ifdef FEAT_ARABIC EXTERN int p_tbidi; /* 'termbidi' */ #endif diff --git a/src/version.c b/src/version.c index e2013d1aa..af26ae370 100644 --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1070, +/**/ 1069, /**/ 1068, |