summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-01-09 19:41:11 +0100
committerBram Moolenaar <Bram@vim.org>2016-01-09 19:41:11 +0100
commit8a5115cf18751022387af2085f374d38c60dde83 (patch)
tree626c3e93cd3127931c85e631d50d6ced1b5f6380 /src
parent5f24542e5eda590acdbee89b120fa2e19ec7596e (diff)
downloadvim-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/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
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,