]>
Commit | Line | Data |
---|---|---|
c6060300 MT |
1 | To: vim_dev@googlegroups.com |
2 | Subject: Patch 7.3.451 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.3.451 | |
11 | Problem: Tcl doesn't work on 64 bit MS-Windows. | |
12 | Solution: Make it work. (Dave Bodenstab) | |
13 | Files: src/Make_mvc.mak, src/if_tcl.c | |
14 | ||
15 | ||
16 | *** ../vim-7.3.450/src/Make_mvc.mak 2012-02-12 01:55:50.000000000 +0100 | |
17 | --- src/Make_mvc.mak 2012-02-22 15:43:01.000000000 +0100 | |
18 | *************** | |
19 | *** 616,622 **** | |
20 | -DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\" | |
21 | TCL_OBJ = $(OUTDIR)\if_tcl.obj | |
22 | TCL_INC = /I "$(TCL)\Include" /I "$(TCL)" | |
23 | ! TCL_LIB = $(TCL)\lib\tclstub$(TCL_VER).lib | |
24 | !else | |
25 | CFLAGS = $(CFLAGS) -DFEAT_TCL | |
26 | TCL_OBJ = $(OUTDIR)\if_tcl.obj | |
27 | --- 616,622 ---- | |
28 | -DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\" | |
29 | TCL_OBJ = $(OUTDIR)\if_tcl.obj | |
30 | TCL_INC = /I "$(TCL)\Include" /I "$(TCL)" | |
31 | ! TCL_LIB = "$(TCL)\lib\tclstub$(TCL_VER).lib" | |
32 | !else | |
33 | CFLAGS = $(CFLAGS) -DFEAT_TCL | |
34 | TCL_OBJ = $(OUTDIR)\if_tcl.obj | |
35 | *** ../vim-7.3.450/src/if_tcl.c 2011-07-27 14:15:41.000000000 +0200 | |
36 | --- src/if_tcl.c 2012-02-22 15:47:00.000000000 +0100 | |
37 | *************** | |
38 | *** 79,90 **** | |
39 | typedef struct | |
40 | { | |
41 | Tcl_Interp *interp; | |
42 | int range_start, range_end; | |
43 | int lbase; | |
44 | char *curbuf, *curwin; | |
45 | } tcl_info; | |
46 | ||
47 | ! static tcl_info tclinfo = { NULL, 0, 0, 0, NULL, NULL }; | |
48 | ||
49 | #define VAR_RANGE1 "::vim::range(start)" | |
50 | #define VAR_RANGE2 "::vim::range(begin)" | |
51 | --- 79,91 ---- | |
52 | typedef struct | |
53 | { | |
54 | Tcl_Interp *interp; | |
55 | + int exitvalue; | |
56 | int range_start, range_end; | |
57 | int lbase; | |
58 | char *curbuf, *curwin; | |
59 | } tcl_info; | |
60 | ||
61 | ! static tcl_info tclinfo = { NULL, 0, 0, 0, 0, NULL, NULL }; | |
62 | ||
63 | #define VAR_RANGE1 "::vim::range(start)" | |
64 | #define VAR_RANGE2 "::vim::range(begin)" | |
65 | *************** | |
66 | *** 279,294 **** | |
67 | ****************************************************************************/ | |
68 | ||
69 | /* | |
70 | ! * Replace standard "exit" and "catch" commands. | |
71 | * | |
72 | ! * This is a design flaw in Tcl - the standard "exit" command just calls | |
73 | ! * exit() and kills the application. It should return TCL_EXIT to the | |
74 | ! * app, which then decides if it wants to terminate or not. In our case, | |
75 | ! * we just delete the Tcl interpreter (and create a new one with the next | |
76 | ! * :tcl command). | |
77 | */ | |
78 | - #define TCL_EXIT 5 | |
79 | - | |
80 | static int | |
81 | exitcmd(dummy, interp, objc, objv) | |
82 | ClientData dummy UNUSED; | |
83 | --- 280,298 ---- | |
84 | ****************************************************************************/ | |
85 | ||
86 | /* | |
87 | ! * Replace standard "exit" command. | |
88 | * | |
89 | ! * Delete the Tcl interpreter; a new one will be created with the next | |
90 | ! * :tcl command). The exit code is saved (and retrieved in tclexit()). | |
91 | ! * Since Tcl's exit is never expected to return and this replacement | |
92 | ! * does, then (except for a trivial case) additional Tcl commands will | |
93 | ! * be run. Since the interpreter is now marked as deleted, an error | |
94 | ! * will be returned -- typically "attempt to call eval in deleted | |
95 | ! * interpreter". Hopefully, at this point, checks for TCL_ERROR take | |
96 | ! * place and control percolates back up to Vim -- but with this new error | |
97 | ! * string in the interpreter's result value. Therefore it would be | |
98 | ! * useless for this routine to return the exit code via Tcl_SetResult(). | |
99 | */ | |
100 | static int | |
101 | exitcmd(dummy, interp, objc, objv) | |
102 | ClientData dummy UNUSED; | |
103 | *************** | |
104 | *** 305,351 **** | |
105 | break; | |
106 | /* FALLTHROUGH */ | |
107 | case 1: | |
108 | ! Tcl_SetObjResult(interp, Tcl_NewIntObj(value)); | |
109 | ! return TCL_EXIT; | |
110 | ! default: | |
111 | ! Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?"); | |
112 | ! } | |
113 | ! return TCL_ERROR; | |
114 | ! } | |
115 | ||
116 | ! static int | |
117 | ! catchcmd(dummy, interp, objc, objv) | |
118 | ! ClientData dummy UNUSED; | |
119 | ! Tcl_Interp *interp; | |
120 | ! int objc; | |
121 | ! Tcl_Obj *CONST objv[]; | |
122 | ! { | |
123 | ! char *varname = NULL; | |
124 | ! int result; | |
125 | ! | |
126 | ! switch (objc) | |
127 | ! { | |
128 | ! case 3: | |
129 | ! varname = Tcl_GetStringFromObj(objv[2], NULL); | |
130 | ! /* fallthrough */ | |
131 | ! case 2: | |
132 | ! Tcl_ResetResult(interp); | |
133 | ! Tcl_AllowExceptions(interp); | |
134 | ! result = Tcl_EvalObj(interp, objv[1]); | |
135 | ! if (result == TCL_EXIT) | |
136 | ! return result; | |
137 | ! if (varname) | |
138 | ! { | |
139 | ! if (Tcl_SetVar(interp, varname, Tcl_GetStringResult(interp), 0) == NULL) | |
140 | ! { | |
141 | ! Tcl_SetResult(interp, "couldn't save command result in variable", TCL_STATIC); | |
142 | ! return TCL_ERROR; | |
143 | ! } | |
144 | ! } | |
145 | ! Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); | |
146 | ! return TCL_OK; | |
147 | default: | |
148 | ! Tcl_WrongNumArgs(interp, 1, objv, "command ?varName?"); | |
149 | } | |
150 | return TCL_ERROR; | |
151 | } | |
152 | --- 309,320 ---- | |
153 | break; | |
154 | /* FALLTHROUGH */ | |
155 | case 1: | |
156 | ! tclinfo.exitvalue = value; | |
157 | ||
158 | ! Tcl_DeleteInterp(interp); | |
159 | ! break; | |
160 | default: | |
161 | ! Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?"); | |
162 | } | |
163 | return TCL_ERROR; | |
164 | } | |
165 | *************** | |
166 | *** 372,377 **** | |
167 | --- 341,347 ---- | |
168 | /* | |
169 | * "::vim::buffer list" - create a list of buffer commands. | |
170 | * "::vim::buffer {N}" - create buffer command for buffer N. | |
171 | + * "::vim::buffer exists {N}" - test if buffer N exists. | |
172 | * "::vim::buffer new" - create a new buffer (not implemented) | |
173 | */ | |
174 | static int | |
175 | *************** | |
176 | *** 1663,1669 **** | |
177 | static Tcl_ChannelType channel_type = | |
178 | { | |
179 | "vimmessage", /* typeName */ | |
180 | ! NULL, /* version */ | |
181 | channel_close, /* closeProc */ | |
182 | channel_input, /* inputProc */ | |
183 | channel_output, /* outputProc */ | |
184 | --- 1633,1639 ---- | |
185 | static Tcl_ChannelType channel_type = | |
186 | { | |
187 | "vimmessage", /* typeName */ | |
188 | ! TCL_CHANNEL_VERSION_2, /* version */ | |
189 | channel_close, /* closeProc */ | |
190 | channel_input, /* inputProc */ | |
191 | channel_output, /* outputProc */ | |
192 | *************** | |
193 | *** 1678,1683 **** | |
194 | --- 1648,1655 ---- | |
195 | NULL, /* flushProc */ | |
196 | NULL, /* handlerProc */ | |
197 | #endif | |
198 | + /* The following should not be necessary since TCL_CHANNEL_VERSION_2 was | |
199 | + * set above */ | |
200 | #ifdef TCL_CHANNEL_VERSION_3 | |
201 | NULL, /* wideSeekProc */ | |
202 | #endif | |
203 | *************** | |
204 | *** 1741,1747 **** | |
205 | Tcl_Interp *interp; | |
206 | static Tcl_Channel ch1, ch2; | |
207 | ||
208 | ! /* replace stdout and stderr */ | |
209 | ch1 = Tcl_CreateChannel(&channel_type, "vimout", VIMOUT, TCL_WRITABLE); | |
210 | ch2 = Tcl_CreateChannel(&channel_type, "vimerr", VIMERR, TCL_WRITABLE); | |
211 | Tcl_SetStdChannel(ch1, TCL_STDOUT); | |
212 | --- 1713,1721 ---- | |
213 | Tcl_Interp *interp; | |
214 | static Tcl_Channel ch1, ch2; | |
215 | ||
216 | ! /* Create replacement channels for stdout and stderr; this has to be | |
217 | ! * done each time an interpreter is created since the channels are closed | |
218 | ! * when the interpreter is deleted */ | |
219 | ch1 = Tcl_CreateChannel(&channel_type, "vimout", VIMOUT, TCL_WRITABLE); | |
220 | ch2 = Tcl_CreateChannel(&channel_type, "vimerr", VIMERR, TCL_WRITABLE); | |
221 | Tcl_SetStdChannel(ch1, TCL_STDOUT); | |
222 | *************** | |
223 | *** 1761,1775 **** | |
224 | #endif | |
225 | ||
226 | Tcl_SetChannelOption(interp, ch1, "-buffering", "line"); | |
227 | Tcl_SetChannelOption(interp, ch2, "-buffering", "line"); | |
228 | ||
229 | ! /* replace some standard Tcl commands */ | |
230 | Tcl_DeleteCommand(interp, "exit"); | |
231 | Tcl_CreateObjCommand(interp, "exit", exitcmd, | |
232 | (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); | |
233 | - Tcl_DeleteCommand(interp, "catch"); | |
234 | - Tcl_CreateObjCommand(interp, "catch", catchcmd, | |
235 | - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); | |
236 | ||
237 | /* new commands, in ::vim namespace */ | |
238 | Tcl_CreateObjCommand(interp, "::vim::buffer", buffercmd, | |
239 | --- 1735,1752 ---- | |
240 | #endif | |
241 | ||
242 | Tcl_SetChannelOption(interp, ch1, "-buffering", "line"); | |
243 | + #ifdef WIN3264 | |
244 | + Tcl_SetChannelOption(interp, ch1, "-translation", "lf"); | |
245 | + #endif | |
246 | Tcl_SetChannelOption(interp, ch2, "-buffering", "line"); | |
247 | + #ifdef WIN3264 | |
248 | + Tcl_SetChannelOption(interp, ch2, "-translation", "lf"); | |
249 | + #endif | |
250 | ||
251 | ! /* replace standard Tcl exit command */ | |
252 | Tcl_DeleteCommand(interp, "exit"); | |
253 | Tcl_CreateObjCommand(interp, "exit", exitcmd, | |
254 | (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); | |
255 | ||
256 | /* new commands, in ::vim namespace */ | |
257 | Tcl_CreateObjCommand(interp, "::vim::buffer", buffercmd, | |
258 | *************** | |
259 | *** 1821,1826 **** | |
260 | --- 1798,1805 ---- | |
261 | tclinfo.range_end = row2tcl(eap->line2); | |
262 | tclupdatevars(); | |
263 | } | |
264 | + | |
265 | + tclinfo.exitvalue = 0; | |
266 | return OK; | |
267 | } | |
268 | ||
269 | *************** | |
270 | *** 1884,1913 **** | |
271 | { | |
272 | int newerr = OK; | |
273 | ||
274 | ! if (error == TCL_EXIT) | |
275 | { | |
276 | - int retval; | |
277 | char buf[50]; | |
278 | - Tcl_Obj *robj; | |
279 | ||
280 | ! robj = Tcl_GetObjResult(tclinfo.interp); | |
281 | ! if (Tcl_GetIntFromObj(tclinfo.interp, robj, &retval) != TCL_OK) | |
282 | { | |
283 | ! EMSG(_("E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org")); | |
284 | ! newerr = FAIL; | |
285 | } | |
286 | else | |
287 | ! { | |
288 | ! sprintf(buf, _("E572: exit code %d"), retval); | |
289 | ! tclerrmsg(buf); | |
290 | ! if (retval == 0) | |
291 | ! { | |
292 | ! did_emsg = 0; | |
293 | ! newerr = OK; | |
294 | ! } | |
295 | ! else | |
296 | ! newerr = FAIL; | |
297 | ! } | |
298 | ||
299 | tcldelthisinterp(); | |
300 | } | |
301 | --- 1863,1885 ---- | |
302 | { | |
303 | int newerr = OK; | |
304 | ||
305 | ! if (Tcl_InterpDeleted(tclinfo.interp) /* True if we intercepted Tcl's exit command */ | |
306 | ! #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) || TCL_MAJOR_VERSION > 8 | |
307 | ! || Tcl_LimitExceeded(tclinfo.interp) /* True if the interpreter cannot continue */ | |
308 | ! #endif | |
309 | ! ) | |
310 | { | |
311 | char buf[50]; | |
312 | ||
313 | ! sprintf(buf, _("E572: exit code %d"), tclinfo.exitvalue); | |
314 | ! tclerrmsg(buf); | |
315 | ! if (tclinfo.exitvalue == 0) | |
316 | { | |
317 | ! did_emsg = 0; | |
318 | ! newerr = OK; | |
319 | } | |
320 | else | |
321 | ! newerr = FAIL; | |
322 | ||
323 | tcldelthisinterp(); | |
324 | } | |
325 | *************** | |
326 | *** 2021,2027 **** | |
327 | Tcl_SetVar(tclinfo.interp, var_line, line, 0); | |
328 | Tcl_AllowExceptions(tclinfo.interp); | |
329 | err = Tcl_Eval(tclinfo.interp, script); | |
330 | ! if (err != TCL_OK) | |
331 | break; | |
332 | line = (char *)Tcl_GetVar(tclinfo.interp, var_line, 0); | |
333 | if (line) | |
334 | --- 1993,2004 ---- | |
335 | Tcl_SetVar(tclinfo.interp, var_line, line, 0); | |
336 | Tcl_AllowExceptions(tclinfo.interp); | |
337 | err = Tcl_Eval(tclinfo.interp, script); | |
338 | ! if (err != TCL_OK | |
339 | ! || Tcl_InterpDeleted(tclinfo.interp) | |
340 | ! #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) || TCL_MAJOR_VERSION > 8 | |
341 | ! || Tcl_LimitExceeded(tclinfo.interp) | |
342 | ! #endif | |
343 | ! ) | |
344 | break; | |
345 | line = (char *)Tcl_GetVar(tclinfo.interp, var_line, 0); | |
346 | if (line) | |
347 | *** ../vim-7.3.450/src/version.c 2012-02-22 15:34:05.000000000 +0100 | |
348 | --- src/version.c 2012-02-22 16:00:49.000000000 +0100 | |
349 | *************** | |
350 | *** 716,717 **** | |
351 | --- 716,719 ---- | |
352 | { /* Add new patch number below this line */ | |
353 | + /**/ | |
354 | + 451, | |
355 | /**/ | |
356 | ||
357 | -- | |
358 | Where do you want to crash today? | |
359 | ||
360 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
361 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
362 | \\\ an exciting new programming language -- http://www.Zimbu.org /// | |
363 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |