summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/if_tcl.txt20
-rw-r--r--runtime/doc/options.txt11
-rw-r--r--runtime/doc/quickref.txt1
-rw-r--r--runtime/optwin.vim4
-rw-r--r--src/Makefile10
-rwxr-xr-xsrc/auto/configure18
-rw-r--r--src/config.h.in3
-rw-r--r--src/configure.in17
-rw-r--r--src/if_tcl.c31
-rw-r--r--src/option.c6
-rw-r--r--src/option.h3
-rw-r--r--src/version.c2
12 files changed, 104 insertions, 22 deletions
diff --git a/runtime/doc/if_tcl.txt b/runtime/doc/if_tcl.txt
index bc9d3b8e2..4d02233f0 100644
--- a/runtime/doc/if_tcl.txt
+++ b/runtime/doc/if_tcl.txt
@@ -515,12 +515,15 @@ startup file (usually "~/.vimrc" on Unix):
==============================================================================
9. Dynamic loading *tcl-dynamic*
-On MS-Windows the Tcl library can be loaded dynamically. The |:version|
-output then includes |+tcl/dyn|.
+On MS-Windows and Unix the Tcl library can be loaded dynamically. The
+|:version| output then includes |+tcl/dyn|.
-This means that Vim will search for the Tcl DLL file only when needed. When
-you don't use the Tcl interface you don't need it, thus you can use Vim
-without this DLL file.
+This means that Vim will search for the Tcl DLL or shared library file only
+when needed. When you don't use the Tcl interface you don't need it, thus you
+can use Vim without this file.
+
+
+MS-Windows ~
To use the Tcl interface the Tcl DLL must be in your search path. In a
console window type "path" to see what directories are used.
@@ -529,5 +532,12 @@ The name of the DLL must match the Tcl version Vim was compiled with.
Currently the name is "tcl86.dll". That is for Tcl 8.6. To know for sure
edit "gvim.exe" and search for "tcl\d*.dll\c".
+
+Unix ~
+
+The 'tcldll' option can be used to specify the Tcl shared library file instead
+of DYNAMIC_TCL_DLL file what was specified at compile time. The version of
+the shared library must match the Tcl version Vim was compiled with.
+
==============================================================================
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index a17cf71c8..8cf2aa7bd 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -7437,6 +7437,17 @@ A jump table for the options with a short description can be found at |Q_op|.
Resetting this option is useful when using a ":tag" command in a
mapping which should not change the tagstack.
+ *'tcldll'*
+'tcldll' string (default depends on the build)
+ global
+ {not in Vi}
+ {only available when compiled with the |+tcl/dyn|
+ feature}
+ Specifies the name of the Tcl shared library. The default is
+ DYNAMIC_TCL_DLL, which was specified at compile time.
+ This option cannot be set from a |modeline| or in the |sandbox|, for
+ security reasons.
+
*'term'* *E529* *E530* *E531*
'term' string (default is $TERM, if that fails:
in the GUI: "builtin_gui"
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index fb10cccda..8450cdd89 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -909,6 +909,7 @@ Short explanation of each option: *option-list*
'tagrelative' 'tr' file names in tag file are relative
'tags' 'tag' list of file names used by the tag command
'tagstack' 'tgst' push tags onto the tag stack
+'tcldll' name of the Tcl dynamic library
'term' name of the terminal
'termbidi' 'tbidi' terminal takes care of bi-directionality
'termencoding' 'tenc' character encoding used by the terminal
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 731848330..314e7f3e0 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -1331,6 +1331,10 @@ if exists("&rubydll")
call append("$", "rubydll\tname of the Ruby dynamic library")
call <SID>OptionG("rubydll", &rubydll)
endif
+if exists("&tcldll")
+ call append("$", "tcldll\tname of the Tcl dynamic library")
+ call <SID>OptionG("tcldll", &tcldll)
+endif
set cpo&vim
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,