Tcl 8.5 & Vim's Tcl interface
- From: Dave <use@xxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 31 Jan 2012 13:46:08 -0600
[Pardon the leading period, but I'm hoping the indenting is
preserved to make reading easier]
.. I wanted Vim on windows (x64) that was compiled with Vim's
.. Tcl interface. All went fairly well, I was able to build
.. Vim using window's SDK command line compiler for x64, and I
.. linked against ActiveState's Tcl 8.5.11.0 for x64 using
.. tclstub85.lib to allow dynamic loading of the Tcl DLL.
..
.. [As an aside, I'm hoping to convince Vim's maintainer to
.. build the release version of Vim containing support for all
.. the language interfaces since only an error message would
.. occur if the respective DLL was not found. It appears that
.. the Vim maintainer last checked building against 8.4]
..
.. The Tcl interface works for a simple ":tcl puts Hello" but
.. when I tried anything more I get the error:
..
.. wrong # args: should be "catch command ?varName?"
..
.. This is because Vim creates a replacement "catch" command
.. (I've attached the relevant code below. As the comments
.. state, Vim needs to prevent exit() being called by Tcl. Tcl
.. 8.5 has introduced a new "catch" command that takes an
.. additional argument, and somewhere -- either the Tcl
.. library or tcl85.dll -- uses catch with four arguments. I
.. don't have 8.5's source but I see that auto.tcl, clock.tcl,
.. init.tcl, (I stopped looking) all use the four-argument catch.
..
.. So here's my question: what's the best way this could be fixed?
..
.. I see several possibilities:
..
.. 1) Compile and link Vim against Tcl 8.5 (as I've done) and
.. update Vim's catch replacement.
.. Con: Breaks run-time compatibility with Tcl versions
.. prior to 8.5 (is this correct?) If true, this would
.. be a BIG problem since a binary Vim installer
.. containing the Tcl interface would not work against
.. Tcl 8.4 or earlier.
.. Pro: Should work (I don't see any problems here)
..
.. 2) Compile and link Vim against Tcl 8.3
.. Con: I don't have a 64-bit tclstub83.lib (I've got a
.. copy of tcl-8.3.5 source but no 64-bit ActiveState installer)
.. Wouldn't the same problem occur? 8.5's library uses
.. the four-argument catch and Vim's catch would fail
..
.. 3) Compile and link Vim against Tcl 8.3/4 but use a
.. run-time test after calling Tcl_InitStubs() to find
.. out what version of Tcl and then replace catch with a
.. version specific routine.
.. Con: Can one determine the version of Tcl after
.. Tcl_InitStubs() has been called?
.. Compiling Vim against 8.3/4 but trying to back-port a
.. four-argument catch would be pretty difficult
.. since the dict stuff had not yet been invented,
.. the Tcl header files would not contain any dict
.. declarations, and tclstub83.lib would not have
.. hooks to 8.5's dict routines.
..
.. So, is anything but option #1 viable or even possible?
..
.. ===
.. === Vim's replacement for exit and catch from if_tcl.c (note that
.. === catch checks for exit having been called; this is used by Vim
.. === to determine if the current Tcl interpreter should be deleted
.. === and a new one created):
.. ===
..
.. /*
.. * Replace standard "exit" and "catch" commands.
.. *
.. * This is a design flaw in Tcl - the standard "exit" command just calls
.. * exit() and kills the application. It should return TCL_EXIT to the
.. * app, which then decides if it wants to terminate or not. In our case,
.. * we just delete the Tcl interpreter (and create a new one with the next
.. * :tcl command).
.. */
.. #define TCL_EXIT 5
..
.. static int
.. exitcmd(dummy, interp, objc, objv)
.. ClientData dummy UNUSED;
.. Tcl_Interp *interp;
.. int objc;
.. Tcl_Obj *CONST objv[];
.. {
.. int value = 0;
..
.. switch (objc)
.. {
.. case 2:
.. if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK)
.. break;
.. /* FALLTHROUGH */
.. case 1:
.. Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
.. return TCL_EXIT;
.. default:
.. Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
.. }
.. return TCL_ERROR;
.. }
..
.. static int
.. catchcmd(dummy, interp, objc, objv)
.. ClientData dummy UNUSED;
.. Tcl_Interp *interp;
.. int objc;
.. Tcl_Obj *CONST objv[];
.. {
.. char *varname = NULL;
.. int result;
..
.. switch (objc)
.. {
.. case 3:
.. varname = Tcl_GetStringFromObj(objv[2], NULL);
.. /* fallthrough */
.. case 2:
.. Tcl_ResetResult(interp);
.. Tcl_AllowExceptions(interp);
.. result = Tcl_EvalObj(interp, objv[1]);
.. if (result == TCL_EXIT)
.. return result;
.. if (varname)
.. {
.. if (Tcl_SetVar(interp, varname, Tcl_GetStringResult(interp), 0) == NULL)
.. {
.. Tcl_SetResult(interp, "couldn't save command result in variable", TCL_STATIC);
.. return TCL_ERROR;
.. }
.. }
.. Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
.. return TCL_OK;
.. default:
.. Tcl_WrongNumArgs(interp, 1, objv, "command ?varName?");
.. }
.. return TCL_ERROR;
.. }
.
- Follow-Ups:
- Re: Tcl 8.5 & Vim's Tcl interface
- From: Don Porter
- Re: Tcl 8.5 & Vim's Tcl interface
- Prev by Date: Re: Is there an existing Symbian port of tcl running on current Symbian^3 devices?
- Next by Date: Re: Tcl 8.5 & Vim's Tcl interface
- Previous by thread: TclWs (Web Services for Tcl)
- Next by thread: Re: Tcl 8.5 & Vim's Tcl interface
- Index(es):
Relevant Pages
|