| To: vim-dev@vim.org |
| Subject: patch 7.1.100 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=ISO-8859-1 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.1.100 |
| Problem: Win32: Executing cscope doesn't always work properly. |
| Solution: Use another way to invoke cscope. (Mike Williams) |
| Files: src/if_cscope.c, src/if_cscope.h, src/main.c, |
| src/proto/if_cscope.pro |
| |
| |
| |
| |
| |
| *** 24,34 **** |
| /* not UNIX, must be WIN32 */ |
| # include "vimio.h" |
| # include <fcntl.h> |
| - # include <process.h> |
| - # define STDIN_FILENO 0 |
| - # define STDOUT_FILENO 1 |
| - # define STDERR_FILENO 2 |
| - # define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT) |
| #endif |
| #include "if_cscope.h" |
| |
| --- 24,29 ---- |
| |
| *** 65,71 **** |
| static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); |
| static char * cs_pathcomponents __ARGS((char *path)); |
| static void cs_print_tags_priv __ARGS((char **, char **, int)); |
| ! static int cs_read_prompt __ARGS((int )); |
| static void cs_release_csp __ARGS((int, int freefnpp)); |
| static int cs_reset __ARGS((exarg_T *eap)); |
| static char * cs_resolve_file __ARGS((int, char *)); |
| --- 60,66 ---- |
| static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); |
| static char * cs_pathcomponents __ARGS((char *path)); |
| static void cs_print_tags_priv __ARGS((char **, char **, int)); |
| ! static int cs_read_prompt __ARGS((int)); |
| static void cs_release_csp __ARGS((int, int freefnpp)); |
| static int cs_reset __ARGS((exarg_T *eap)); |
| static char * cs_resolve_file __ARGS((int, char *)); |
| |
| *** 504,510 **** |
| #if defined(UNIX) |
| else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) |
| #else |
| ! /* substitute define S_ISREG from os_unix.h */ |
| else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) |
| #endif |
| { |
| --- 499,505 ---- |
| #if defined(UNIX) |
| else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) |
| #else |
| ! /* WIN32 - substitute define S_ISREG from os_unix.h */ |
| else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) |
| #endif |
| { |
| |
| *** 717,733 **** |
| cs_create_connection(i) |
| int i; |
| { |
| ! int to_cs[2], from_cs[2], len; |
| ! char *prog, *cmd, *ppath = NULL; |
| ! #ifndef UNIX |
| ! int in_save, out_save, err_save; |
| ! long_i ph; |
| ! # ifdef FEAT_GUI |
| ! HWND activewnd = NULL; |
| ! HWND consolewnd = NULL; |
| ! # endif |
| #endif |
| |
| /* |
| * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from |
| * from_cs[0] and writes to to_cs[1]. |
| --- 712,734 ---- |
| cs_create_connection(i) |
| int i; |
| { |
| ! #ifdef UNIX |
| ! int to_cs[2], from_cs[2]; |
| ! #endif |
| ! int len; |
| ! char *prog, *cmd, *ppath = NULL; |
| ! #ifdef WIN32 |
| ! int fd; |
| ! SECURITY_ATTRIBUTES sa; |
| ! PROCESS_INFORMATION pi; |
| ! STARTUPINFO si; |
| ! BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; |
| ! HANDLE stdin_rd, stdout_rd; |
| ! HANDLE stdout_wr, stdin_wr; |
| ! BOOL created; |
| #endif |
| |
| + #if defined(UNIX) |
| /* |
| * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from |
| * from_cs[0] and writes to to_cs[1]. |
| |
| *** 748,765 **** |
| return CSCOPE_FAILURE; |
| } |
| |
| - #if defined(UNIX) |
| switch (csinfo[i].pid = fork()) |
| { |
| case -1: |
| (void)EMSG(_("E622: Could not fork for cscope")); |
| goto err_closing; |
| case 0: /* child: run cscope. */ |
| - #else |
| - in_save = dup(STDIN_FILENO); |
| - out_save = dup(STDOUT_FILENO); |
| - err_save = dup(STDERR_FILENO); |
| - #endif |
| if (dup2(to_cs[0], STDIN_FILENO) == -1) |
| PERROR("cs_create_connection 1"); |
| if (dup2(from_cs[1], STDOUT_FILENO) == -1) |
| --- 749,760 ---- |
| |
| *** 768,782 **** |
| PERROR("cs_create_connection 3"); |
| |
| /* close unused */ |
| - #if defined(UNIX) |
| (void)close(to_cs[1]); |
| (void)close(from_cs[0]); |
| #else |
| ! /* On win32 we must close opposite ends because we are the parent */ |
| ! (void)close(to_cs[0]); |
| ! to_cs[0] = -1; |
| ! (void)close(from_cs[1]); |
| ! from_cs[1] = -1; |
| #endif |
| /* expand the cscope exec for env var's */ |
| if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) |
| --- 763,794 ---- |
| PERROR("cs_create_connection 3"); |
| |
| /* close unused */ |
| (void)close(to_cs[1]); |
| (void)close(from_cs[0]); |
| #else |
| ! /* WIN32 */ |
| ! /* Create pipes to communicate with cscope */ |
| ! sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| ! sa.bInheritHandle = TRUE; |
| ! sa.lpSecurityDescriptor = NULL; |
| ! |
| ! if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0)) |
| ! || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) |
| ! { |
| ! (void)EMSG(_("E566: Could not create cscope pipes")); |
| ! err_closing: |
| ! if (pipe_stdin) |
| ! { |
| ! CloseHandle(stdin_rd); |
| ! CloseHandle(stdin_wr); |
| ! } |
| ! if (pipe_stdout) |
| ! { |
| ! CloseHandle(stdout_rd); |
| ! CloseHandle(stdout_wr); |
| ! } |
| ! return CSCOPE_FAILURE; |
| ! } |
| #endif |
| /* expand the cscope exec for env var's */ |
| if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) |
| |
| *** 784,789 **** |
| --- 796,802 ---- |
| #ifdef UNIX |
| return CSCOPE_FAILURE; |
| #else |
| + /* WIN32 */ |
| goto err_closing; |
| #endif |
| } |
| |
| *** 800,805 **** |
| --- 813,819 ---- |
| #ifdef UNIX |
| return CSCOPE_FAILURE; |
| #else |
| + /* WIN32 */ |
| goto err_closing; |
| #endif |
| } |
| |
| *** 818,823 **** |
| --- 832,838 ---- |
| #ifdef UNIX |
| return CSCOPE_FAILURE; |
| #else |
| + /* WIN32 */ |
| goto err_closing; |
| #endif |
| } |
| |
| *** 826,831 **** |
| --- 841,847 ---- |
| #if defined(UNIX) |
| (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); |
| #else |
| + /* WIN32 */ |
| (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); |
| #endif |
| if (csinfo[i].ppath != NULL) |
| |
| *** 851,910 **** |
| exit(127); |
| /* NOTREACHED */ |
| default: /* parent. */ |
| - #else |
| - # ifdef FEAT_GUI |
| - activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */ |
| - /* Dirty hack to hide annoying console window */ |
| - if (AllocConsole()) |
| - { |
| - char *title; |
| - title = (char *)alloc(1024); |
| - if (title == NULL) |
| - FreeConsole(); |
| - else |
| - { |
| - GetConsoleTitle(title, 1024); /* save for future restore */ |
| - SetConsoleTitle( |
| - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); |
| - Sleep(40); /* as stated in MS KB we must wait 40 ms */ |
| - consolewnd = FindWindow(NULL, |
| - "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS"); |
| - if (consolewnd != NULL) |
| - ShowWindow(consolewnd, SW_HIDE); |
| - SetConsoleTitle(title); |
| - vim_free(title); |
| - } |
| - } |
| - # endif |
| - /* May be use &shell, &shellquote etc */ |
| - # ifdef __BORLANDC__ |
| - /* BCC 5.5 uses a different function name for spawnlp */ |
| - ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL); |
| - # else |
| - ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL); |
| - # endif |
| - vim_free(prog); |
| - vim_free(cmd); |
| - # ifdef FEAT_GUI |
| - /* Dirty hack part two */ |
| - if (activewnd != NULL) |
| - /* restoring focus */ |
| - SetForegroundWindow(activewnd); |
| - if (consolewnd != NULL) |
| - FreeConsole(); |
| - |
| - # endif |
| - if (ph == -1) |
| - { |
| - PERROR(_("cs_create_connection exec failed")); |
| - (void)EMSG(_("E623: Could not spawn cscope process")); |
| - goto err_closing; |
| - } |
| - /* else */ |
| - csinfo[i].pid = 0; |
| - csinfo[i].hProc = (HANDLE)ph; |
| - |
| - #endif /* !UNIX */ |
| /* |
| * Save the file descriptors for later duplication, and |
| * reopen as streams. |
| --- 867,872 ---- |
| |
| *** 914,935 **** |
| if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) |
| PERROR(_("cs_create_connection: fdopen for fr_fp failed")); |
| |
| - #if defined(UNIX) |
| /* close unused */ |
| (void)close(to_cs[0]); |
| (void)close(from_cs[1]); |
| |
| break; |
| } |
| #else |
| ! /* restore stdhandles */ |
| ! dup2(in_save, STDIN_FILENO); |
| ! dup2(out_save, STDOUT_FILENO); |
| ! dup2(err_save, STDERR_FILENO); |
| ! close(in_save); |
| ! close(out_save); |
| ! close(err_save); |
| ! #endif |
| return CSCOPE_SUCCESS; |
| } /* cs_create_connection */ |
| |
| --- 876,927 ---- |
| if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) |
| PERROR(_("cs_create_connection: fdopen for fr_fp failed")); |
| |
| /* close unused */ |
| (void)close(to_cs[0]); |
| (void)close(from_cs[1]); |
| |
| break; |
| } |
| + |
| #else |
| ! /* WIN32 */ |
| ! /* Create a new process to run cscope and use pipes to talk with it */ |
| ! GetStartupInfo(&si); |
| ! si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; |
| ! si.wShowWindow = SW_HIDE; /* Hide child application window */ |
| ! si.hStdOutput = stdout_wr; |
| ! si.hStdError = stdout_wr; |
| ! si.hStdInput = stdin_rd; |
| ! created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, |
| ! NULL, NULL, &si, &pi); |
| ! vim_free(prog); |
| ! vim_free(cmd); |
| ! |
| ! if (!created) |
| ! { |
| ! PERROR(_("cs_create_connection exec failed")); |
| ! (void)EMSG(_("E623: Could not spawn cscope process")); |
| ! goto err_closing; |
| ! } |
| ! /* else */ |
| ! csinfo[i].pid = pi.dwProcessId; |
| ! csinfo[i].hProc = pi.hProcess; |
| ! CloseHandle(pi.hThread); |
| ! |
| ! /* TODO - tidy up after failure to create files on pipe handles. */ |
| ! if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0) |
| ! || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL)) |
| ! PERROR(_("cs_create_connection: fdopen for to_fp failed")); |
| ! if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0) |
| ! || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL)) |
| ! PERROR(_("cs_create_connection: fdopen for fr_fp failed")); |
| ! |
| ! /* Close handles for file descriptors inherited by the cscope process */ |
| ! CloseHandle(stdin_rd); |
| ! CloseHandle(stdout_wr); |
| ! |
| ! #endif /* !UNIX */ |
| ! |
| return CSCOPE_SUCCESS; |
| } /* cs_create_connection */ |
| |
| |
| *** 2097,2104 **** |
| /* |
| * PRIVATE: cs_release_csp |
| * |
| ! * does the actual free'ing for the cs ptr with an optional flag of whether |
| ! * or not to free the filename. called by cs_kill and cs_reset. |
| */ |
| static void |
| cs_release_csp(i, freefnpp) |
| --- 2089,2096 ---- |
| /* |
| * PRIVATE: cs_release_csp |
| * |
| ! * Does the actual free'ing for the cs ptr with an optional flag of whether |
| ! * or not to free the filename. Called by cs_kill and cs_reset. |
| */ |
| static void |
| cs_release_csp(i, freefnpp) |
| |
| *** 2116,2125 **** |
| (void)fputs("q\n", csinfo[i].to_fp); |
| (void)fflush(csinfo[i].to_fp); |
| } |
| ! /* give cscope chance to exit normally */ |
| ! if (csinfo[i].hProc != NULL |
| ! && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) |
| ! TerminateProcess(csinfo[i].hProc, 0); |
| #endif |
| |
| if (csinfo[i].fr_fp != NULL) |
| --- 2108,2120 ---- |
| (void)fputs("q\n", csinfo[i].to_fp); |
| (void)fflush(csinfo[i].to_fp); |
| } |
| ! if (csinfo[i].hProc != NULL) |
| ! { |
| ! /* Give cscope a chance to exit normally */ |
| ! if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) |
| ! TerminateProcess(csinfo[i].hProc, 0); |
| ! CloseHandle(csinfo[i].hProc); |
| ! } |
| #endif |
| |
| if (csinfo[i].fr_fp != NULL) |
| |
| *** 2301,2306 **** |
| --- 2296,2316 ---- |
| wait_return(TRUE); |
| return CSCOPE_SUCCESS; |
| } /* cs_show */ |
| + |
| + |
| + /* |
| + * PUBLIC: cs_end |
| + * |
| + * Only called when VIM exits to quit any cscope sessions. |
| + */ |
| + void |
| + cs_end() |
| + { |
| + int i; |
| + |
| + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) |
| + cs_release_csp(i, TRUE); |
| + } |
| |
| #endif /* FEAT_CSCOPE */ |
| |
| |
| |
| |
| *** 72,78 **** |
| ino_t st_ino; /* inode number of cscope db */ |
| #else |
| # if defined(WIN32) |
| ! int pid; /* Can't get pid so set it to 0 ;) */ |
| HANDLE hProc; /* cscope process handle */ |
| DWORD nVolume; /* Volume serial number, instead of st_dev */ |
| DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ |
| --- 72,78 ---- |
| ino_t st_ino; /* inode number of cscope db */ |
| #else |
| # if defined(WIN32) |
| ! DWORD pid; /* PID of the connected cscope process. */ |
| HANDLE hProc; /* cscope process handle */ |
| DWORD nVolume; /* Volume serial number, instead of st_dev */ |
| DWORD nIndexHigh; /* st_ino has no meaning in the Windows */ |
| |
| |
| |
| *** 1331,1336 **** |
| --- 1331,1339 ---- |
| #ifdef FEAT_NETBEANS_INTG |
| netbeans_end(); |
| #endif |
| + #ifdef FEAT_CSCOPE |
| + cs_end(); |
| + #endif |
| |
| mch_exit(exitval); |
| } |
| |
| *** 3671,3677 **** |
| mainerr_arg_missing((char_u *)filev[-1]); |
| if (mch_dirname(cwd, MAXPATHL) != OK) |
| return NULL; |
| ! if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL) |
| return NULL; |
| ga_init2(&ga, 1, 100); |
| ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd "); |
| --- 3674,3686 ---- |
| mainerr_arg_missing((char_u *)filev[-1]); |
| if (mch_dirname(cwd, MAXPATHL) != OK) |
| return NULL; |
| ! if ((p = vim_strsave_escaped_ext(cwd, |
| ! #ifdef BACKSLASH_IN_FILENAME |
| ! "", /* rem_backslash() will tell what chars to escape */ |
| ! #else |
| ! PATH_ESC_CHARS, |
| ! #endif |
| ! '\\', TRUE)) == NULL) |
| return NULL; |
| ga_init2(&ga, 1, 100); |
| ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd "); |
| |
| |
| |
| *** 6,9 **** |
| --- 6,10 ---- |
| void cs_free_tags __ARGS((void)); |
| void cs_print_tags __ARGS((void)); |
| int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath)); |
| + void cs_end __ARGS((void)); |
| /* vim: set ft=c : */ |
| |
| |
| |
| *** 668,669 **** |
| --- 668,671 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 100, |
| /**/ |
| |
| -- |
| I have to exercise early in the morning before my brain |
| figures out what I'm doing. |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ download, build and distribute -- http://www.A-A-P.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |