4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
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
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
21 /* not UNIX, must be WIN32 */
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)
30 #include "if_cscope.h"
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 *));
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 *));
53 else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
55 ! /* substitute define S_ISREG from os_unix.h */
56 else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
61 else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
63 ! /* WIN32 - substitute define S_ISREG from os_unix.h */
64 else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
69 cs_create_connection(i)
72 ! int to_cs[2], from_cs[2], len;
73 ! char *prog, *cmd, *ppath = NULL;
75 ! int in_save, out_save, err_save;
78 ! HWND activewnd = NULL;
79 ! HWND consolewnd = NULL;
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].
87 cs_create_connection(i)
91 ! int to_cs[2], from_cs[2];
94 ! char *prog, *cmd, *ppath = NULL;
97 ! SECURITY_ATTRIBUTES sa;
98 ! PROCESS_INFORMATION pi;
100 ! BOOL pipe_stdin = FALSE, pipe_stdout = FALSE;
101 ! HANDLE stdin_rd, stdout_rd;
102 ! HANDLE stdout_wr, stdin_wr;
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].
112 return CSCOPE_FAILURE;
116 switch (csinfo[i].pid = fork())
119 (void)EMSG(_("E622: Could not fork for cscope"));
121 case 0: /* child: run cscope. */
123 - in_save = dup(STDIN_FILENO);
124 - out_save = dup(STDOUT_FILENO);
125 - err_save = dup(STDERR_FILENO);
127 if (dup2(to_cs[0], STDIN_FILENO) == -1)
128 PERROR("cs_create_connection 1");
129 if (dup2(from_cs[1], STDOUT_FILENO) == -1)
133 PERROR("cs_create_connection 3");
137 (void)close(to_cs[1]);
138 (void)close(from_cs[0]);
140 ! /* On win32 we must close opposite ends because we are the parent */
141 ! (void)close(to_cs[0]);
143 ! (void)close(from_cs[1]);
146 /* expand the cscope exec for env var's */
147 if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
149 PERROR("cs_create_connection 3");
152 (void)close(to_cs[1]);
153 (void)close(from_cs[0]);
156 ! /* Create pipes to communicate with cscope */
157 ! sa.nLength = sizeof(SECURITY_ATTRIBUTES);
158 ! sa.bInheritHandle = TRUE;
159 ! sa.lpSecurityDescriptor = NULL;
161 ! if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
162 ! || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0)))
164 ! (void)EMSG(_("E566: Could not create cscope pipes"));
168 ! CloseHandle(stdin_rd);
169 ! CloseHandle(stdin_wr);
173 ! CloseHandle(stdout_rd);
174 ! CloseHandle(stdout_wr);
176 ! return CSCOPE_FAILURE;
179 /* expand the cscope exec for env var's */
180 if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
185 return CSCOPE_FAILURE;
195 return CSCOPE_FAILURE;
205 return CSCOPE_FAILURE;
215 (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
218 (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
220 if (csinfo[i].ppath != NULL)
225 default: /* parent. */
228 - activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */
229 - /* Dirty hack to hide annoying console window */
230 - if (AllocConsole())
233 - title = (char *)alloc(1024);
238 - GetConsoleTitle(title, 1024); /* save for future restore */
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);
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);
256 - ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL);
261 - /* Dirty hack part two */
262 - if (activewnd != NULL)
263 - /* restoring focus */
264 - SetForegroundWindow(activewnd);
265 - if (consolewnd != NULL)
271 - PERROR(_("cs_create_connection exec failed"));
272 - (void)EMSG(_("E623: Could not spawn cscope process"));
277 - csinfo[i].hProc = (HANDLE)ph;
281 * Save the file descriptors for later duplication, and
286 if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
287 PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
291 (void)close(to_cs[0]);
292 (void)close(from_cs[1]);
297 ! /* restore stdhandles */
298 ! dup2(in_save, STDIN_FILENO);
299 ! dup2(out_save, STDOUT_FILENO);
300 ! dup2(err_save, STDERR_FILENO);
305 return CSCOPE_SUCCESS;
306 } /* cs_create_connection */
309 if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
310 PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
313 (void)close(to_cs[0]);
314 (void)close(from_cs[1]);
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);
335 ! PERROR(_("cs_create_connection exec failed"));
336 ! (void)EMSG(_("E623: Could not spawn cscope process"));
340 ! csinfo[i].pid = pi.dwProcessId;
341 ! csinfo[i].hProc = pi.hProcess;
342 ! CloseHandle(pi.hThread);
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"));
352 ! /* Close handles for file descriptors inherited by the cscope process */
353 ! CloseHandle(stdin_rd);
354 ! CloseHandle(stdout_wr);
358 return CSCOPE_SUCCESS;
359 } /* cs_create_connection */
364 * PRIVATE: cs_release_csp
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.
370 cs_release_csp(i, freefnpp)
373 * PRIVATE: cs_release_csp
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.
379 cs_release_csp(i, freefnpp)
382 (void)fputs("q\n", csinfo[i].to_fp);
383 (void)fflush(csinfo[i].to_fp);
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);
391 if (csinfo[i].fr_fp != NULL)
393 (void)fputs("q\n", csinfo[i].to_fp);
394 (void)fflush(csinfo[i].to_fp);
396 ! if (csinfo[i].hProc != NULL)
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);
405 if (csinfo[i].fr_fp != NULL)
410 return CSCOPE_SUCCESS;
417 + * Only called when VIM exits to quit any cscope sessions.
424 + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
425 + cs_release_csp(i, TRUE);
428 #endif /* FEAT_CSCOPE */
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
434 ino_t st_ino; /* inode number of cscope db */
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 */
442 ino_t st_ino; /* inode number of cscope db */
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
454 #ifdef FEAT_NETBEANS_INTG
465 mainerr_arg_missing((char_u *)filev[-1]);
466 if (mch_dirname(cwd, MAXPATHL) != OK)
468 ! if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL)
470 ga_init2(&ga, 1, 100);
471 ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
473 mainerr_arg_missing((char_u *)filev[-1]);
474 if (mch_dirname(cwd, MAXPATHL) != OK)
476 ! if ((p = vim_strsave_escaped_ext(cwd,
477 ! #ifdef BACKSLASH_IN_FILENAME
478 ! "", /* rem_backslash() will tell what chars to escape */
482 ! '\\', TRUE)) == 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
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
501 { /* Add new patch number below this line */
507 I have to exercise early in the morning before my brain
508 figures out what I'm doing.
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 ///