]>
Commit | Line | Data |
---|---|---|
0a7814d6 AG |
1 | To: vim-dev@vim.org |
2 | Subject: patch 7.1.100 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.1.100 | |
11 | Problem: Win32: Executing cscope doesn't always work properly. | |
12 | Solution: Use another way to invoke cscope. (Mike Williams) | |
13 | Files: src/if_cscope.c, src/if_cscope.h, src/main.c, | |
14 | src/proto/if_cscope.pro | |
15 | ||
16 | ||
17 | *** ../vim-7.1.099/src/if_cscope.c Tue Aug 21 18:02:58 2007 | |
18 | --- src/if_cscope.c Sun Sep 2 16:50:50 2007 | |
19 | *************** | |
20 | *** 24,34 **** | |
21 | /* not UNIX, must be WIN32 */ | |
22 | # include "vimio.h" | |
23 | # include <fcntl.h> | |
24 | - # include <process.h> | |
25 | - # define STDIN_FILENO 0 | |
26 | - # define STDOUT_FILENO 1 | |
27 | - # define STDERR_FILENO 2 | |
28 | - # define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT) | |
29 | #endif | |
30 | #include "if_cscope.h" | |
31 | ||
32 | --- 24,29 ---- | |
33 | *************** | |
34 | *** 65,71 **** | |
35 | static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); | |
36 | static char * cs_pathcomponents __ARGS((char *path)); | |
37 | static void cs_print_tags_priv __ARGS((char **, char **, int)); | |
38 | ! static int cs_read_prompt __ARGS((int )); | |
39 | static void cs_release_csp __ARGS((int, int freefnpp)); | |
40 | static int cs_reset __ARGS((exarg_T *eap)); | |
41 | static char * cs_resolve_file __ARGS((int, char *)); | |
42 | --- 60,66 ---- | |
43 | static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); | |
44 | static char * cs_pathcomponents __ARGS((char *path)); | |
45 | static void cs_print_tags_priv __ARGS((char **, char **, int)); | |
46 | ! static int cs_read_prompt __ARGS((int)); | |
47 | static void cs_release_csp __ARGS((int, int freefnpp)); | |
48 | static int cs_reset __ARGS((exarg_T *eap)); | |
49 | static char * cs_resolve_file __ARGS((int, char *)); | |
50 | *************** | |
51 | *** 504,510 **** | |
52 | #if defined(UNIX) | |
53 | else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) | |
54 | #else | |
55 | ! /* substitute define S_ISREG from os_unix.h */ | |
56 | else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) | |
57 | #endif | |
58 | { | |
59 | --- 499,505 ---- | |
60 | #if defined(UNIX) | |
61 | else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) | |
62 | #else | |
63 | ! /* WIN32 - substitute define S_ISREG from os_unix.h */ | |
64 | else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) | |
65 | #endif | |
66 | { | |
67 | *************** | |
68 | *** 717,733 **** | |
69 | cs_create_connection(i) | |
70 | int i; | |
71 | { | |
72 | ! int to_cs[2], from_cs[2], len; | |
73 | ! char *prog, *cmd, *ppath = NULL; | |
74 | ! #ifndef UNIX | |
75 | ! int in_save, out_save, err_save; | |
76 | ! long_i ph; | |
77 | ! # ifdef FEAT_GUI | |
78 | ! HWND activewnd = NULL; | |
79 | ! HWND consolewnd = NULL; | |
80 | ! # endif | |
81 | #endif | |
82 | ||
83 | /* | |
84 | * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from | |
85 | * from_cs[0] and writes to to_cs[1]. | |
86 | --- 712,734 ---- | |
87 | cs_create_connection(i) | |
88 | int i; | |
89 | { | |
90 | ! #ifdef UNIX | |
91 | ! int to_cs[2], from_cs[2]; | |
92 | ! #endif | |
93 | ! int len; | |
94 | ! char *prog, *cmd, *ppath = NULL; | |
95 | ! #ifdef WIN32 | |
96 | ! int fd; | |
97 | ! SECURITY_ATTRIBUTES sa; | |
98 | ! PROCESS_INFORMATION pi; | |
99 | ! STARTUPINFO si; | |
100 | ! BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; | |
101 | ! HANDLE stdin_rd, stdout_rd; | |
102 | ! HANDLE stdout_wr, stdin_wr; | |
103 | ! BOOL created; | |
104 | #endif | |
105 | ||
106 | + #if defined(UNIX) | |
107 | /* | |
108 | * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from | |
109 | * from_cs[0] and writes to to_cs[1]. | |
110 | *************** | |
111 | *** 748,765 **** | |
112 | return CSCOPE_FAILURE; | |
113 | } | |
114 | ||
115 | - #if defined(UNIX) | |
116 | switch (csinfo[i].pid = fork()) | |
117 | { | |
118 | case -1: | |
119 | (void)EMSG(_("E622: Could not fork for cscope")); | |
120 | goto err_closing; | |
121 | case 0: /* child: run cscope. */ | |
122 | - #else | |
123 | - in_save = dup(STDIN_FILENO); | |
124 | - out_save = dup(STDOUT_FILENO); | |
125 | - err_save = dup(STDERR_FILENO); | |
126 | - #endif | |
127 | if (dup2(to_cs[0], STDIN_FILENO) == -1) | |
128 | PERROR("cs_create_connection 1"); | |
129 | if (dup2(from_cs[1], STDOUT_FILENO) == -1) | |
130 | --- 749,760 ---- | |
131 | *************** | |
132 | *** 768,782 **** | |
133 | PERROR("cs_create_connection 3"); | |
134 | ||
135 | /* close unused */ | |
136 | - #if defined(UNIX) | |
137 | (void)close(to_cs[1]); | |
138 | (void)close(from_cs[0]); | |
139 | #else | |
140 | ! /* On win32 we must close opposite ends because we are the parent */ | |
141 | ! (void)close(to_cs[0]); | |
142 | ! to_cs[0] = -1; | |
143 | ! (void)close(from_cs[1]); | |
144 | ! from_cs[1] = -1; | |
145 | #endif | |
146 | /* expand the cscope exec for env var's */ | |
147 | if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) | |
148 | --- 763,794 ---- | |
149 | PERROR("cs_create_connection 3"); | |
150 | ||
151 | /* close unused */ | |
152 | (void)close(to_cs[1]); | |
153 | (void)close(from_cs[0]); | |
154 | #else | |
155 | ! /* WIN32 */ | |
156 | ! /* Create pipes to communicate with cscope */ | |
157 | ! sa.nLength = sizeof(SECURITY_ATTRIBUTES); | |
158 | ! sa.bInheritHandle = TRUE; | |
159 | ! sa.lpSecurityDescriptor = NULL; | |
160 | ! | |
161 | ! if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0)) | |
162 | ! || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) | |
163 | ! { | |
164 | ! (void)EMSG(_("E566: Could not create cscope pipes")); | |
165 | ! err_closing: | |
166 | ! if (pipe_stdin) | |
167 | ! { | |
168 | ! CloseHandle(stdin_rd); | |
169 | ! CloseHandle(stdin_wr); | |
170 | ! } | |
171 | ! if (pipe_stdout) | |
172 | ! { | |
173 | ! CloseHandle(stdout_rd); | |
174 | ! CloseHandle(stdout_wr); | |
175 | ! } | |
176 | ! return CSCOPE_FAILURE; | |
177 | ! } | |
178 | #endif | |
179 | /* expand the cscope exec for env var's */ | |
180 | if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) | |
181 | *************** | |
182 | *** 784,789 **** | |
183 | --- 796,802 ---- | |
184 | #ifdef UNIX | |
185 | return CSCOPE_FAILURE; | |
186 | #else | |
187 | + /* WIN32 */ | |
188 | goto err_closing; | |
189 | #endif | |
190 | } | |
191 | *************** | |
192 | *** 800,805 **** | |
193 | --- 813,819 ---- | |
194 | #ifdef UNIX | |
195 | return CSCOPE_FAILURE; | |
196 | #else | |
197 | + /* WIN32 */ | |
198 | goto err_closing; | |
199 | #endif | |
200 | } | |
201 | *************** | |
202 | *** 818,823 **** | |
203 | --- 832,838 ---- | |
204 | #ifdef UNIX | |
205 | return CSCOPE_FAILURE; | |
206 | #else | |
207 | + /* WIN32 */ | |
208 | goto err_closing; | |
209 | #endif | |
210 | } | |
211 | *************** | |
212 | *** 826,831 **** | |
213 | --- 841,847 ---- | |
214 | #if defined(UNIX) | |
215 | (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); | |
216 | #else | |
217 | + /* WIN32 */ | |
218 | (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); | |
219 | #endif | |
220 | if (csinfo[i].ppath != NULL) | |
221 | *************** | |
222 | *** 851,910 **** | |
223 | exit(127); | |
224 | /* NOTREACHED */ | |
225 | default: /* parent. */ | |
226 | - #else | |
227 | - # ifdef FEAT_GUI | |
228 | - activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */ | |
229 | - /* Dirty hack to hide annoying console window */ | |
230 | - if (AllocConsole()) | |
231 | - { | |
232 | - char *title; | |
233 | - title = (char *)alloc(1024); | |
234 | - if (title == NULL) | |
235 | - FreeConsole(); | |
236 | - else | |
237 | - { | |
238 | - GetConsoleTitle(title, 1024); /* save for future restore */ | |
239 | - SetConsoleTitle( | |
240 | - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); | |
241 | - Sleep(40); /* as stated in MS KB we must wait 40 ms */ | |
242 | - consolewnd = FindWindow(NULL, | |
243 | - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); | |
244 | - if (consolewnd != NULL) | |
245 | - ShowWindow(consolewnd, SW_HIDE); | |
246 | - SetConsoleTitle(title); | |
247 | - vim_free(title); | |
248 | - } | |
249 | - } | |
250 | - # endif | |
251 | - /* May be use &shell, &shellquote etc */ | |
252 | - # ifdef __BORLANDC__ | |
253 | - /* BCC 5.5 uses a different function name for spawnlp */ | |
254 | - ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL); | |
255 | - # else | |
256 | - ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL); | |
257 | - # endif | |
258 | - vim_free(prog); | |
259 | - vim_free(cmd); | |
260 | - # ifdef FEAT_GUI | |
261 | - /* Dirty hack part two */ | |
262 | - if (activewnd != NULL) | |
263 | - /* restoring focus */ | |
264 | - SetForegroundWindow(activewnd); | |
265 | - if (consolewnd != NULL) | |
266 | - FreeConsole(); | |
267 | - | |
268 | - # endif | |
269 | - if (ph == -1) | |
270 | - { | |
271 | - PERROR(_("cs_create_connection exec failed")); | |
272 | - (void)EMSG(_("E623: Could not spawn cscope process")); | |
273 | - goto err_closing; | |
274 | - } | |
275 | - /* else */ | |
276 | - csinfo[i].pid = 0; | |
277 | - csinfo[i].hProc = (HANDLE)ph; | |
278 | - | |
279 | - #endif /* !UNIX */ | |
280 | /* | |
281 | * Save the file descriptors for later duplication, and | |
282 | * reopen as streams. | |
283 | --- 867,872 ---- | |
284 | *************** | |
285 | *** 914,935 **** | |
286 | if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) | |
287 | PERROR(_("cs_create_connection: fdopen for fr_fp failed")); | |
288 | ||
289 | - #if defined(UNIX) | |
290 | /* close unused */ | |
291 | (void)close(to_cs[0]); | |
292 | (void)close(from_cs[1]); | |
293 | ||
294 | break; | |
295 | } | |
296 | #else | |
297 | ! /* restore stdhandles */ | |
298 | ! dup2(in_save, STDIN_FILENO); | |
299 | ! dup2(out_save, STDOUT_FILENO); | |
300 | ! dup2(err_save, STDERR_FILENO); | |
301 | ! close(in_save); | |
302 | ! close(out_save); | |
303 | ! close(err_save); | |
304 | ! #endif | |
305 | return CSCOPE_SUCCESS; | |
306 | } /* cs_create_connection */ | |
307 | ||
308 | --- 876,927 ---- | |
309 | if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) | |
310 | PERROR(_("cs_create_connection: fdopen for fr_fp failed")); | |
311 | ||
312 | /* close unused */ | |
313 | (void)close(to_cs[0]); | |
314 | (void)close(from_cs[1]); | |
315 | ||
316 | break; | |
317 | } | |
318 | + | |
319 | #else | |
320 | ! /* WIN32 */ | |
321 | ! /* Create a new process to run cscope and use pipes to talk with it */ | |
322 | ! GetStartupInfo(&si); | |
323 | ! si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; | |
324 | ! si.wShowWindow = SW_HIDE; /* Hide child application window */ | |
325 | ! si.hStdOutput = stdout_wr; | |
326 | ! si.hStdError = stdout_wr; | |
327 | ! si.hStdInput = stdin_rd; | |
328 | ! created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, | |
329 | ! NULL, NULL, &si, &pi); | |
330 | ! vim_free(prog); | |
331 | ! vim_free(cmd); | |
332 | ! | |
333 | ! if (!created) | |
334 | ! { | |
335 | ! PERROR(_("cs_create_connection exec failed")); | |
336 | ! (void)EMSG(_("E623: Could not spawn cscope process")); | |
337 | ! goto err_closing; | |
338 | ! } | |
339 | ! /* else */ | |
340 | ! csinfo[i].pid = pi.dwProcessId; | |
341 | ! csinfo[i].hProc = pi.hProcess; | |
342 | ! CloseHandle(pi.hThread); | |
343 | ! | |
344 | ! /* TODO - tidy up after failure to create files on pipe handles. */ | |
345 | ! if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0) | |
346 | ! || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL)) | |
347 | ! PERROR(_("cs_create_connection: fdopen for to_fp failed")); | |
348 | ! if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0) | |
349 | ! || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL)) | |
350 | ! PERROR(_("cs_create_connection: fdopen for fr_fp failed")); | |
351 | ! | |
352 | ! /* Close handles for file descriptors inherited by the cscope process */ | |
353 | ! CloseHandle(stdin_rd); | |
354 | ! CloseHandle(stdout_wr); | |
355 | ! | |
356 | ! #endif /* !UNIX */ | |
357 | ! | |
358 | return CSCOPE_SUCCESS; | |
359 | } /* cs_create_connection */ | |
360 | ||
361 | *************** | |
362 | *** 2097,2104 **** | |
363 | /* | |
364 | * PRIVATE: cs_release_csp | |
365 | * | |
366 | ! * does the actual free'ing for the cs ptr with an optional flag of whether | |
367 | ! * or not to free the filename. called by cs_kill and cs_reset. | |
368 | */ | |
369 | static void | |
370 | cs_release_csp(i, freefnpp) | |
371 | --- 2089,2096 ---- | |
372 | /* | |
373 | * PRIVATE: cs_release_csp | |
374 | * | |
375 | ! * Does the actual free'ing for the cs ptr with an optional flag of whether | |
376 | ! * or not to free the filename. Called by cs_kill and cs_reset. | |
377 | */ | |
378 | static void | |
379 | cs_release_csp(i, freefnpp) | |
380 | *************** | |
381 | *** 2116,2125 **** | |
382 | (void)fputs("q\n", csinfo[i].to_fp); | |
383 | (void)fflush(csinfo[i].to_fp); | |
384 | } | |
385 | ! /* give cscope chance to exit normally */ | |
386 | ! if (csinfo[i].hProc != NULL | |
387 | ! && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) | |
388 | ! TerminateProcess(csinfo[i].hProc, 0); | |
389 | #endif | |
390 | ||
391 | if (csinfo[i].fr_fp != NULL) | |
392 | --- 2108,2120 ---- | |
393 | (void)fputs("q\n", csinfo[i].to_fp); | |
394 | (void)fflush(csinfo[i].to_fp); | |
395 | } | |
396 | ! if (csinfo[i].hProc != NULL) | |
397 | ! { | |
398 | ! /* Give cscope a chance to exit normally */ | |
399 | ! if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) | |
400 | ! TerminateProcess(csinfo[i].hProc, 0); | |
401 | ! CloseHandle(csinfo[i].hProc); | |
402 | ! } | |
403 | #endif | |
404 | ||
405 | if (csinfo[i].fr_fp != NULL) | |
406 | *************** | |
407 | *** 2301,2306 **** | |
408 | --- 2296,2316 ---- | |
409 | wait_return(TRUE); | |
410 | return CSCOPE_SUCCESS; | |
411 | } /* cs_show */ | |
412 | + | |
413 | + | |
414 | + /* | |
415 | + * PUBLIC: cs_end | |
416 | + * | |
417 | + * Only called when VIM exits to quit any cscope sessions. | |
418 | + */ | |
419 | + void | |
420 | + cs_end() | |
421 | + { | |
422 | + int i; | |
423 | + | |
424 | + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) | |
425 | + cs_release_csp(i, TRUE); | |
426 | + } | |
427 | ||
428 | #endif /* FEAT_CSCOPE */ | |
429 | ||
430 | *** ../vim-7.1.099/src/if_cscope.h Thu Jun 30 23:59:58 2005 | |
431 | --- src/if_cscope.h Sun Sep 2 16:51:08 2007 | |
432 | *************** | |
433 | *** 72,78 **** | |
434 | ino_t st_ino; /* inode number of cscope db */ | |
435 | #else | |
436 | # if defined(WIN32) | |
437 | ! int pid; /* Can't get pid so set it to 0 ;) */ | |
438 | HANDLE hProc; /* cscope process handle */ | |
439 | DWORD nVolume; /* Volume serial number, instead of st_dev */ | |
440 | DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ | |
441 | --- 72,78 ---- | |
442 | ino_t st_ino; /* inode number of cscope db */ | |
443 | #else | |
444 | # if defined(WIN32) | |
445 | ! DWORD pid; /* PID of the connected cscope process. */ | |
446 | HANDLE hProc; /* cscope process handle */ | |
447 | DWORD nVolume; /* Volume serial number, instead of st_dev */ | |
448 | DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ | |
449 | *** ../vim-7.1.099/src/main.c Thu Aug 30 12:24:21 2007 | |
450 | --- src/main.c Sun Sep 2 16:44:36 2007 | |
451 | *************** | |
452 | *** 1331,1336 **** | |
453 | --- 1331,1339 ---- | |
454 | #ifdef FEAT_NETBEANS_INTG | |
455 | netbeans_end(); | |
456 | #endif | |
457 | + #ifdef FEAT_CSCOPE | |
458 | + cs_end(); | |
459 | + #endif | |
460 | ||
461 | mch_exit(exitval); | |
462 | } | |
463 | *************** | |
464 | *** 3671,3677 **** | |
465 | mainerr_arg_missing((char_u *)filev[-1]); | |
466 | if (mch_dirname(cwd, MAXPATHL) != OK) | |
467 | return NULL; | |
468 | ! if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL) | |
469 | return NULL; | |
470 | ga_init2(&ga, 1, 100); | |
471 | ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd "); | |
472 | --- 3674,3686 ---- | |
473 | mainerr_arg_missing((char_u *)filev[-1]); | |
474 | if (mch_dirname(cwd, MAXPATHL) != OK) | |
475 | return NULL; | |
476 | ! if ((p = vim_strsave_escaped_ext(cwd, | |
477 | ! #ifdef BACKSLASH_IN_FILENAME | |
478 | ! "", /* rem_backslash() will tell what chars to escape */ | |
479 | ! #else | |
480 | ! PATH_ESC_CHARS, | |
481 | ! #endif | |
482 | ! '\\', TRUE)) == NULL) | |
483 | return NULL; | |
484 | ga_init2(&ga, 1, 100); | |
485 | ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd "); | |
486 | *** ../vim-7.1.099/src/proto/if_cscope.pro Sat May 5 19:15:39 2007 | |
487 | --- src/proto/if_cscope.pro Sun Sep 2 16:51:34 2007 | |
488 | *************** | |
489 | *** 6,9 **** | |
490 | --- 6,10 ---- | |
491 | void cs_free_tags __ARGS((void)); | |
492 | void cs_print_tags __ARGS((void)); | |
493 | int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath)); | |
494 | + void cs_end __ARGS((void)); | |
495 | /* vim: set ft=c : */ | |
496 | *** ../vim-7.1.099/src/version.c Thu Sep 6 16:33:47 2007 | |
497 | --- src/version.c Thu Sep 6 17:27:51 2007 | |
498 | *************** | |
499 | *** 668,669 **** | |
500 | --- 668,671 ---- | |
501 | { /* Add new patch number below this line */ | |
502 | + /**/ | |
503 | + 100, | |
504 | /**/ | |
505 | ||
506 | -- | |
507 | I have to exercise early in the morning before my brain | |
508 | figures out what I'm doing. | |
509 | ||
510 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
511 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
512 | \\\ download, build and distribute -- http://www.A-A-P.org /// | |
513 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |