Patch 7.3.451
Problem:    Tcl doesn't work on 64 MS-Windows.
Solution:   Make it work. (Dave Bodenstab)
Files:      src/Make_mvc.mak, src/if_tcl.c


*** ../vim-7.3.450/src/Make_mvc.mak     2012-02-12 01:55:50.000000000 +0100
--- src/Make_mvc.mak    2012-02-22 15:43:01.000000000 +0100
***************
*** 616,622 ****
                -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
  !else
  CFLAGS  = $(CFLAGS) -DFEAT_TCL
  TCL_OBJ       = $(OUTDIR)\if_tcl.obj
--- 616,622 ----
                -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"
  !else
  CFLAGS  = $(CFLAGS) -DFEAT_TCL
  TCL_OBJ       = $(OUTDIR)\if_tcl.obj
*** ../vim-7.3.450/src/if_tcl.c 2011-07-27 14:15:41.000000000 +0200
--- src/if_tcl.c        2012-02-22 15:47:00.000000000 +0100
***************
*** 79,90 ****
  typedef struct
  {
      Tcl_Interp *interp;
      int range_start, range_end;
      int lbase;
      char *curbuf, *curwin;
  } tcl_info;
  
! static tcl_info tclinfo = { NULL, 0, 0, 0, NULL, NULL };
  
  #define VAR_RANGE1    "::vim::range(start)"
  #define VAR_RANGE2    "::vim::range(begin)"
--- 79,91 ----
  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, 0, NULL, NULL };
  
  #define VAR_RANGE1    "::vim::range(start)"
  #define VAR_RANGE2    "::vim::range(begin)"
***************
*** 279,294 ****
   ****************************************************************************/
  
  /*
!  * 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;
--- 280,298 ----
   ****************************************************************************/
  
  /*
!  * Replace standard "exit" 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().
   */
      static int
  exitcmd(dummy, interp, objc, objv)
      ClientData dummy UNUSED;
***************
*** 305,351 ****
                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;
  }
--- 309,320 ----
                break;
            /* FALLTHROUGH */
        case 1:
!           tclinfo.exitvalue = value;
  
!           Tcl_DeleteInterp(interp);
!           break;
        default:
!           Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
      }
      return TCL_ERROR;
  }
***************
*** 372,377 ****
--- 341,347 ----
  /*
   *  "::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,1669 ****
  static Tcl_ChannelType channel_type =
  {
      "vimmessage",     /* typeName */
!     NULL,             /* version */
      channel_close,    /* closeProc */
      channel_input,    /* inputProc */
      channel_output,   /* outputProc */
--- 1633,1639 ----
  static Tcl_ChannelType channel_type =
  {
      "vimmessage",     /* typeName */
!     TCL_CHANNEL_VERSION_2, /* version */
      channel_close,    /* closeProc */
      channel_input,    /* inputProc */
      channel_output,   /* outputProc */
***************
*** 1678,1683 ****
--- 1648,1655 ----
      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,1747 ****
        Tcl_Interp *interp;
        static Tcl_Channel ch1, ch2;
  
!       /* replace stdout and stderr */
        ch1 = Tcl_CreateChannel(&channel_type, "vimout", VIMOUT, TCL_WRITABLE);
        ch2 = Tcl_CreateChannel(&channel_type, "vimerr", VIMERR, TCL_WRITABLE);
        Tcl_SetStdChannel(ch1, TCL_STDOUT);
--- 1713,1721 ----
        Tcl_Interp *interp;
        static Tcl_Channel ch1, ch2;
  
!       /* 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,1775 ****
  #endif
  
        Tcl_SetChannelOption(interp, ch1, "-buffering", "line");
        Tcl_SetChannelOption(interp, ch2, "-buffering", "line");
  
!       /* replace some standard Tcl commands */
        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,
--- 1735,1752 ----
  #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 standard Tcl exit command */
        Tcl_DeleteCommand(interp, "exit");
        Tcl_CreateObjCommand(interp, "exit", exitcmd,
            (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
  
        /* new commands, in ::vim namespace */
        Tcl_CreateObjCommand(interp, "::vim::buffer", buffercmd,
***************
*** 1821,1826 ****
--- 1798,1805 ----
        tclinfo.range_end = row2tcl(eap->line2);
        tclupdatevars();
      }
+ 
+     tclinfo.exitvalue = 0;
      return OK;
  }
  
***************
*** 1884,1913 ****
  {
      int newerr = OK;
  
!     if (error == TCL_EXIT)
      {
-       int retval;
        char buf[50];
-       Tcl_Obj *robj;
  
!       robj = Tcl_GetObjResult(tclinfo.interp);
!       if (Tcl_GetIntFromObj(tclinfo.interp, robj, &retval) != TCL_OK)
        {
!           EMSG(_("E281: TCL ERROR: exit code is not int!? Please report this 
to [email protected]"));
!           newerr = FAIL;
        }
        else
!       {
!           sprintf(buf, _("E572: exit code %d"), retval);
!           tclerrmsg(buf);
!           if (retval == 0)
!           {
!               did_emsg = 0;
!               newerr = OK;
!           }
!           else
!               newerr = FAIL;
!       }
  
        tcldelthisinterp();
      }
--- 1863,1885 ----
  {
      int newerr = OK;
  
!     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
!       )
      {
        char buf[50];
  
!       sprintf(buf, _("E572: exit code %d"), tclinfo.exitvalue);
!       tclerrmsg(buf);
!       if (tclinfo.exitvalue == 0)
        {
!           did_emsg = 0;
!           newerr = OK;
        }
        else
!           newerr = FAIL;
  
        tcldelthisinterp();
      }
***************
*** 2021,2027 ****
        Tcl_SetVar(tclinfo.interp, var_line, line, 0);
        Tcl_AllowExceptions(tclinfo.interp);
        err = Tcl_Eval(tclinfo.interp, script);
!       if (err != TCL_OK)
            break;
        line = (char *)Tcl_GetVar(tclinfo.interp, var_line, 0);
        if (line)
--- 1993,2004 ----
        Tcl_SetVar(tclinfo.interp, var_line, line, 0);
        Tcl_AllowExceptions(tclinfo.interp);
        err = Tcl_Eval(tclinfo.interp, script);
!       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)
*** ../vim-7.3.450/src/version.c        2012-02-22 15:34:05.000000000 +0100
--- src/version.c       2012-02-22 16:00:49.000000000 +0100
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     451,
  /**/

-- 
Where do you want to crash today?

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui