]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.451 v7.3.451
authorBram Moolenaar <Bram@vim.org>
Wed, 22 Feb 2012 15:01:56 +0000 (16:01 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 22 Feb 2012 15:01:56 +0000 (16:01 +0100)
Problem:    Tcl doesn't work on 64 MS-Windows.
Solution:   Make it work. (Dave Bodenstab)

src/Make_mvc.mak
src/if_tcl.c
src/version.c

index c6a8e3158b4bf962c81ec452d2d7dcdb7fd19232..092e2b57111f417b4d06b48fd0c1f0c03eae0fdc 100644 (file)
@@ -616,7 +616,7 @@ CFLAGS  = $(CFLAGS) -DFEAT_TCL -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"$(TCL_DLL)\" \
                -DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\"
 TCL_OBJ        = $(OUTDIR)\if_tcl.obj
 TCL_INC        = /I "$(TCL)\Include" /I "$(TCL)"
-TCL_LIB = $(TCL)\lib\tclstub$(TCL_VER).lib
+TCL_LIB = "$(TCL)\lib\tclstub$(TCL_VER).lib"
 !else
 CFLAGS  = $(CFLAGS) -DFEAT_TCL
 TCL_OBJ        = $(OUTDIR)\if_tcl.obj
index 5537b6356e3be167f5382116819bafaf0d3480da..36ff32063f71e7078aee6bf32ce56d8ebd29b448 100644 (file)
@@ -79,12 +79,13 @@ TODO:
 typedef struct
 {
     Tcl_Interp *interp;
+    int exitvalue;
     int range_start, range_end;
     int lbase;
     char *curbuf, *curwin;
 } tcl_info;
 
-static tcl_info tclinfo = { NULL, 0, 0, 0, NULL, NULL };
+static tcl_info tclinfo = { NULL, 0, 0, 0, 0, NULL, NULL };
 
 #define VAR_RANGE1     "::vim::range(start)"
 #define VAR_RANGE2     "::vim::range(begin)"
@@ -279,16 +280,19 @@ tcl_end()
  ****************************************************************************/
 
 /*
- * Replace standard "exit" and "catch" commands.
+ * Replace standard "exit" command.
  *
- * 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).
+ * Delete the Tcl interpreter; a new one will be created with the next
+ * :tcl command). The exit code is saved (and retrieved in tclexit()).
+ * Since Tcl's exit is never expected to return and this replacement
+ * does, then (except for a trivial case) additional Tcl commands will
+ * be run. Since the interpreter is now marked as deleted, an error
+ * will be returned -- typically "attempt to call eval in deleted
+ * interpreter". Hopefully, at this point, checks for TCL_ERROR take
+ * place and control percolates back up to Vim -- but with this new error
+ * string in the interpreter's result value. Therefore it would be
+ * useless for this routine to return the exit code via Tcl_SetResult().
  */
-#define TCL_EXIT       5
-
     static int
 exitcmd(dummy, interp, objc, objv)
     ClientData dummy UNUSED;
@@ -305,47 +309,12 @@ exitcmd(dummy, interp, objc, objv)
                break;
            /* FALLTHROUGH */
        case 1:
-           Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
-           return TCL_EXIT;
-       default:
-           Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
-    }
-    return TCL_ERROR;
-}
+           tclinfo.exitvalue = value;
 
-    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;
+           Tcl_DeleteInterp(interp);
+           break;
        default:
-           Tcl_WrongNumArgs(interp, 1, objv, "command ?varName?");
+           Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
     }
     return TCL_ERROR;
 }
@@ -372,6 +341,7 @@ beepcmd(dummy, interp, objc, objv)
 /*
  *  "::vim::buffer list" - create a list of buffer commands.
  *  "::vim::buffer {N}" - create buffer command for buffer N.
+ *  "::vim::buffer exists {N}" - test if buffer N exists.
  *  "::vim::buffer new" - create a new buffer (not implemented)
  */
     static int
@@ -1663,7 +1633,7 @@ channel_gethandle(instance, direction, handleptr)
 static Tcl_ChannelType channel_type =
 {
     "vimmessage",      /* typeName */
-    NULL,              /* version */
+    TCL_CHANNEL_VERSION_2, /* version */
     channel_close,     /* closeProc */
     channel_input,     /* inputProc */
     channel_output,    /* outputProc */
@@ -1678,6 +1648,8 @@ static Tcl_ChannelType channel_type =
     NULL,              /* flushProc */
     NULL,              /* handlerProc */
 #endif
+/* The following should not be necessary since TCL_CHANNEL_VERSION_2 was
+ * set above */
 #ifdef TCL_CHANNEL_VERSION_3
     NULL,              /* wideSeekProc */
 #endif
@@ -1741,7 +1713,9 @@ tclinit(eap)
        Tcl_Interp *interp;
        static Tcl_Channel ch1, ch2;
 
-       /* replace stdout and stderr */
+       /* Create replacement channels for stdout and stderr; this has to be
+        * done each time an interpreter is created since the channels are closed
+        * when the interpreter is deleted */
        ch1 = Tcl_CreateChannel(&channel_type, "vimout", VIMOUT, TCL_WRITABLE);
        ch2 = Tcl_CreateChannel(&channel_type, "vimerr", VIMERR, TCL_WRITABLE);
        Tcl_SetStdChannel(ch1, TCL_STDOUT);
@@ -1761,15 +1735,18 @@ tclinit(eap)
 #endif
 
        Tcl_SetChannelOption(interp, ch1, "-buffering", "line");
+#ifdef WIN3264
+       Tcl_SetChannelOption(interp, ch1, "-translation", "lf");
+#endif
        Tcl_SetChannelOption(interp, ch2, "-buffering", "line");
+#ifdef WIN3264
+       Tcl_SetChannelOption(interp, ch2, "-translation", "lf");
+#endif
 
-       /* replace some standard Tcl commands */
+       /* replace standard Tcl exit command */
        Tcl_DeleteCommand(interp, "exit");
        Tcl_CreateObjCommand(interp, "exit", exitcmd,
            (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
-       Tcl_DeleteCommand(interp, "catch");
-       Tcl_CreateObjCommand(interp, "catch", catchcmd,
-           (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
 
        /* new commands, in ::vim namespace */
        Tcl_CreateObjCommand(interp, "::vim::buffer", buffercmd,
@@ -1821,6 +1798,8 @@ tclinit(eap)
        tclinfo.range_end = row2tcl(eap->line2);
        tclupdatevars();
     }
+
+    tclinfo.exitvalue = 0;
     return OK;
 }
 
@@ -1884,30 +1863,23 @@ tclexit(error)
 {
     int newerr = OK;
 
-    if (error == TCL_EXIT)
+    if (Tcl_InterpDeleted(tclinfo.interp)     /* True if we intercepted Tcl's exit command */
+#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) || TCL_MAJOR_VERSION > 8
+       || Tcl_LimitExceeded(tclinfo.interp)  /* True if the interpreter cannot continue */
+#endif
+       )
     {
-       int retval;
        char buf[50];
-       Tcl_Obj *robj;
 
-       robj = Tcl_GetObjResult(tclinfo.interp);
-       if (Tcl_GetIntFromObj(tclinfo.interp, robj, &retval) != TCL_OK)
+       sprintf(buf, _("E572: exit code %d"), tclinfo.exitvalue);
+       tclerrmsg(buf);
+       if (tclinfo.exitvalue == 0)
        {
-           EMSG(_("E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"));
-           newerr = FAIL;
+           did_emsg = 0;
+           newerr = OK;
        }
        else
-       {
-           sprintf(buf, _("E572: exit code %d"), retval);
-           tclerrmsg(buf);
-           if (retval == 0)
-           {
-               did_emsg = 0;
-               newerr = OK;
-           }
-           else
-               newerr = FAIL;
-       }
+           newerr = FAIL;
 
        tcldelthisinterp();
     }
@@ -2021,7 +1993,12 @@ ex_tcldo(eap)
        Tcl_SetVar(tclinfo.interp, var_line, line, 0);
        Tcl_AllowExceptions(tclinfo.interp);
        err = Tcl_Eval(tclinfo.interp, script);
-       if (err != TCL_OK)
+       if (err != TCL_OK
+           || Tcl_InterpDeleted(tclinfo.interp)
+#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) || TCL_MAJOR_VERSION > 8
+           || Tcl_LimitExceeded(tclinfo.interp)
+#endif
+          )
            break;
        line = (char *)Tcl_GetVar(tclinfo.interp, var_line, 0);
        if (line)
index 119ad48764403b68ead7cd85229e4d565a9b1f20..f9da5db7aca2de478cf9f7b4bfffc0974d870396 100644 (file)
@@ -714,6 +714,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    451,
 /**/
     450,
 /**/