comparison src/if_cscope.c @ 1385:d0cf8c843186 v7.1.100

updated for version 7.1-100
author vimboss
date Thu, 06 Sep 2007 15:39:22 +0000
parents 76a42a81f685
children b4791bb4fbff
comparison
equal deleted inserted replaced
1384:5ef53a1677ee 1385:d0cf8c843186
22 # include <sys/wait.h> 22 # include <sys/wait.h>
23 #else 23 #else
24 /* not UNIX, must be WIN32 */ 24 /* not UNIX, must be WIN32 */
25 # include "vimio.h" 25 # include "vimio.h"
26 # include <fcntl.h> 26 # include <fcntl.h>
27 # include <process.h>
28 # define STDIN_FILENO 0
29 # define STDOUT_FILENO 1
30 # define STDERR_FILENO 2
31 # define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT)
32 #endif 27 #endif
33 #include "if_cscope.h" 28 #include "if_cscope.h"
34 29
35 static void cs_usage_msg __ARGS((csid_e x)); 30 static void cs_usage_msg __ARGS((csid_e x));
36 static int cs_add __ARGS((exarg_T *eap)); 31 static int cs_add __ARGS((exarg_T *eap));
63 char *, char *)); 58 char *, char *));
64 static char * cs_manage_matches __ARGS((char **, char **, int, mcmd_e)); 59 static char * cs_manage_matches __ARGS((char **, char **, int, mcmd_e));
65 static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)); 60 static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search));
66 static char * cs_pathcomponents __ARGS((char *path)); 61 static char * cs_pathcomponents __ARGS((char *path));
67 static void cs_print_tags_priv __ARGS((char **, char **, int)); 62 static void cs_print_tags_priv __ARGS((char **, char **, int));
68 static int cs_read_prompt __ARGS((int )); 63 static int cs_read_prompt __ARGS((int));
69 static void cs_release_csp __ARGS((int, int freefnpp)); 64 static void cs_release_csp __ARGS((int, int freefnpp));
70 static int cs_reset __ARGS((exarg_T *eap)); 65 static int cs_reset __ARGS((exarg_T *eap));
71 static char * cs_resolve_file __ARGS((int, char *)); 66 static char * cs_resolve_file __ARGS((int, char *));
72 static int cs_show __ARGS((exarg_T *eap)); 67 static int cs_show __ARGS((exarg_T *eap));
73 68
502 i = cs_insert_filelist(fname2, ppath, flags, &statbuf); 497 i = cs_insert_filelist(fname2, ppath, flags, &statbuf);
503 } 498 }
504 #if defined(UNIX) 499 #if defined(UNIX)
505 else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) 500 else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
506 #else 501 #else
507 /* substitute define S_ISREG from os_unix.h */ 502 /* WIN32 - substitute define S_ISREG from os_unix.h */
508 else if (((statbuf.st_mode) & S_IFMT) == S_IFREG) 503 else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
509 #endif 504 #endif
510 { 505 {
511 i = cs_insert_filelist(fname, ppath, flags, &statbuf); 506 i = cs_insert_filelist(fname, ppath, flags, &statbuf);
512 } 507 }
715 */ 710 */
716 static int 711 static int
717 cs_create_connection(i) 712 cs_create_connection(i)
718 int i; 713 int i;
719 { 714 {
720 int to_cs[2], from_cs[2], len; 715 #ifdef UNIX
721 char *prog, *cmd, *ppath = NULL; 716 int to_cs[2], from_cs[2];
722 #ifndef UNIX 717 #endif
723 int in_save, out_save, err_save; 718 int len;
724 long_i ph; 719 char *prog, *cmd, *ppath = NULL;
725 # ifdef FEAT_GUI 720 #ifdef WIN32
726 HWND activewnd = NULL; 721 int fd;
727 HWND consolewnd = NULL; 722 SECURITY_ATTRIBUTES sa;
728 # endif 723 PROCESS_INFORMATION pi;
729 #endif 724 STARTUPINFO si;
730 725 BOOL pipe_stdin = FALSE, pipe_stdout = FALSE;
726 HANDLE stdin_rd, stdout_rd;
727 HANDLE stdout_wr, stdin_wr;
728 BOOL created;
729 #endif
730
731 #if defined(UNIX)
731 /* 732 /*
732 * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from 733 * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
733 * from_cs[0] and writes to to_cs[1]. 734 * from_cs[0] and writes to to_cs[1].
734 */ 735 */
735 to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1; 736 to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
746 if (from_cs[1] != -1) 747 if (from_cs[1] != -1)
747 (void)close(from_cs[1]); 748 (void)close(from_cs[1]);
748 return CSCOPE_FAILURE; 749 return CSCOPE_FAILURE;
749 } 750 }
750 751
751 #if defined(UNIX)
752 switch (csinfo[i].pid = fork()) 752 switch (csinfo[i].pid = fork())
753 { 753 {
754 case -1: 754 case -1:
755 (void)EMSG(_("E622: Could not fork for cscope")); 755 (void)EMSG(_("E622: Could not fork for cscope"));
756 goto err_closing; 756 goto err_closing;
757 case 0: /* child: run cscope. */ 757 case 0: /* child: run cscope. */
758 #else
759 in_save = dup(STDIN_FILENO);
760 out_save = dup(STDOUT_FILENO);
761 err_save = dup(STDERR_FILENO);
762 #endif
763 if (dup2(to_cs[0], STDIN_FILENO) == -1) 758 if (dup2(to_cs[0], STDIN_FILENO) == -1)
764 PERROR("cs_create_connection 1"); 759 PERROR("cs_create_connection 1");
765 if (dup2(from_cs[1], STDOUT_FILENO) == -1) 760 if (dup2(from_cs[1], STDOUT_FILENO) == -1)
766 PERROR("cs_create_connection 2"); 761 PERROR("cs_create_connection 2");
767 if (dup2(from_cs[1], STDERR_FILENO) == -1) 762 if (dup2(from_cs[1], STDERR_FILENO) == -1)
768 PERROR("cs_create_connection 3"); 763 PERROR("cs_create_connection 3");
769 764
770 /* close unused */ 765 /* close unused */
771 #if defined(UNIX)
772 (void)close(to_cs[1]); 766 (void)close(to_cs[1]);
773 (void)close(from_cs[0]); 767 (void)close(from_cs[0]);
774 #else 768 #else
775 /* On win32 we must close opposite ends because we are the parent */ 769 /* WIN32 */
776 (void)close(to_cs[0]); 770 /* Create pipes to communicate with cscope */
777 to_cs[0] = -1; 771 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
778 (void)close(from_cs[1]); 772 sa.bInheritHandle = TRUE;
779 from_cs[1] = -1; 773 sa.lpSecurityDescriptor = NULL;
774
775 if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
776 || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0)))
777 {
778 (void)EMSG(_("E566: Could not create cscope pipes"));
779 err_closing:
780 if (pipe_stdin)
781 {
782 CloseHandle(stdin_rd);
783 CloseHandle(stdin_wr);
784 }
785 if (pipe_stdout)
786 {
787 CloseHandle(stdout_rd);
788 CloseHandle(stdout_wr);
789 }
790 return CSCOPE_FAILURE;
791 }
780 #endif 792 #endif
781 /* expand the cscope exec for env var's */ 793 /* expand the cscope exec for env var's */
782 if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) 794 if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
783 { 795 {
784 #ifdef UNIX 796 #ifdef UNIX
785 return CSCOPE_FAILURE; 797 return CSCOPE_FAILURE;
786 #else 798 #else
799 /* WIN32 */
787 goto err_closing; 800 goto err_closing;
788 #endif 801 #endif
789 } 802 }
790 expand_env((char_u *)p_csprg, (char_u *)prog, MAXPATHL); 803 expand_env((char_u *)p_csprg, (char_u *)prog, MAXPATHL);
791 804
798 { 811 {
799 vim_free(prog); 812 vim_free(prog);
800 #ifdef UNIX 813 #ifdef UNIX
801 return CSCOPE_FAILURE; 814 return CSCOPE_FAILURE;
802 #else 815 #else
816 /* WIN32 */
803 goto err_closing; 817 goto err_closing;
804 #endif 818 #endif
805 } 819 }
806 expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL); 820 expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL);
807 821
816 vim_free(prog); 830 vim_free(prog);
817 vim_free(ppath); 831 vim_free(ppath);
818 #ifdef UNIX 832 #ifdef UNIX
819 return CSCOPE_FAILURE; 833 return CSCOPE_FAILURE;
820 #else 834 #else
835 /* WIN32 */
821 goto err_closing; 836 goto err_closing;
822 #endif 837 #endif
823 } 838 }
824 839
825 /* run the cscope command; is there execl for non-unix systems? */ 840 /* run the cscope command; is there execl for non-unix systems? */
826 #if defined(UNIX) 841 #if defined(UNIX)
827 (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); 842 (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
828 #else 843 #else
844 /* WIN32 */
829 (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); 845 (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
830 #endif 846 #endif
831 if (csinfo[i].ppath != NULL) 847 if (csinfo[i].ppath != NULL)
832 { 848 {
833 (void)strcat(cmd, " -P"); 849 (void)strcat(cmd, " -P");
849 PERROR(_("cs_create_connection exec failed")); 865 PERROR(_("cs_create_connection exec failed"));
850 866
851 exit(127); 867 exit(127);
852 /* NOTREACHED */ 868 /* NOTREACHED */
853 default: /* parent. */ 869 default: /* parent. */
854 #else
855 # ifdef FEAT_GUI
856 activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */
857 /* Dirty hack to hide annoying console window */
858 if (AllocConsole())
859 {
860 char *title;
861 title = (char *)alloc(1024);
862 if (title == NULL)
863 FreeConsole();
864 else
865 {
866 GetConsoleTitle(title, 1024); /* save for future restore */
867 SetConsoleTitle(
868 "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
869 Sleep(40); /* as stated in MS KB we must wait 40 ms */
870 consolewnd = FindWindow(NULL,
871 "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
872 if (consolewnd != NULL)
873 ShowWindow(consolewnd, SW_HIDE);
874 SetConsoleTitle(title);
875 vim_free(title);
876 }
877 }
878 # endif
879 /* May be use &shell, &shellquote etc */
880 # ifdef __BORLANDC__
881 /* BCC 5.5 uses a different function name for spawnlp */
882 ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL);
883 # else
884 ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL);
885 # endif
886 vim_free(prog);
887 vim_free(cmd);
888 # ifdef FEAT_GUI
889 /* Dirty hack part two */
890 if (activewnd != NULL)
891 /* restoring focus */
892 SetForegroundWindow(activewnd);
893 if (consolewnd != NULL)
894 FreeConsole();
895
896 # endif
897 if (ph == -1)
898 {
899 PERROR(_("cs_create_connection exec failed"));
900 (void)EMSG(_("E623: Could not spawn cscope process"));
901 goto err_closing;
902 }
903 /* else */
904 csinfo[i].pid = 0;
905 csinfo[i].hProc = (HANDLE)ph;
906
907 #endif /* !UNIX */
908 /* 870 /*
909 * Save the file descriptors for later duplication, and 871 * Save the file descriptors for later duplication, and
910 * reopen as streams. 872 * reopen as streams.
911 */ 873 */
912 if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) 874 if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL)
913 PERROR(_("cs_create_connection: fdopen for to_fp failed")); 875 PERROR(_("cs_create_connection: fdopen for to_fp failed"));
914 if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) 876 if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
915 PERROR(_("cs_create_connection: fdopen for fr_fp failed")); 877 PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
916 878
917 #if defined(UNIX)
918 /* close unused */ 879 /* close unused */
919 (void)close(to_cs[0]); 880 (void)close(to_cs[0]);
920 (void)close(from_cs[1]); 881 (void)close(from_cs[1]);
921 882
922 break; 883 break;
923 } 884 }
885
924 #else 886 #else
925 /* restore stdhandles */ 887 /* WIN32 */
926 dup2(in_save, STDIN_FILENO); 888 /* Create a new process to run cscope and use pipes to talk with it */
927 dup2(out_save, STDOUT_FILENO); 889 GetStartupInfo(&si);
928 dup2(err_save, STDERR_FILENO); 890 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
929 close(in_save); 891 si.wShowWindow = SW_HIDE; /* Hide child application window */
930 close(out_save); 892 si.hStdOutput = stdout_wr;
931 close(err_save); 893 si.hStdError = stdout_wr;
932 #endif 894 si.hStdInput = stdin_rd;
895 created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
896 NULL, NULL, &si, &pi);
897 vim_free(prog);
898 vim_free(cmd);
899
900 if (!created)
901 {
902 PERROR(_("cs_create_connection exec failed"));
903 (void)EMSG(_("E623: Could not spawn cscope process"));
904 goto err_closing;
905 }
906 /* else */
907 csinfo[i].pid = pi.dwProcessId;
908 csinfo[i].hProc = pi.hProcess;
909 CloseHandle(pi.hThread);
910
911 /* TODO - tidy up after failure to create files on pipe handles. */
912 if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0)
913 || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL))
914 PERROR(_("cs_create_connection: fdopen for to_fp failed"));
915 if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0)
916 || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL))
917 PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
918
919 /* Close handles for file descriptors inherited by the cscope process */
920 CloseHandle(stdin_rd);
921 CloseHandle(stdout_wr);
922
923 #endif /* !UNIX */
924
933 return CSCOPE_SUCCESS; 925 return CSCOPE_SUCCESS;
934 } /* cs_create_connection */ 926 } /* cs_create_connection */
935 927
936 928
937 /* 929 /*
2095 2087
2096 2088
2097 /* 2089 /*
2098 * PRIVATE: cs_release_csp 2090 * PRIVATE: cs_release_csp
2099 * 2091 *
2100 * does the actual free'ing for the cs ptr with an optional flag of whether 2092 * Does the actual free'ing for the cs ptr with an optional flag of whether
2101 * or not to free the filename. called by cs_kill and cs_reset. 2093 * or not to free the filename. Called by cs_kill and cs_reset.
2102 */ 2094 */
2103 static void 2095 static void
2104 cs_release_csp(i, freefnpp) 2096 cs_release_csp(i, freefnpp)
2105 int i; 2097 int i;
2106 int freefnpp; 2098 int freefnpp;
2114 if (csinfo[i].to_fp != NULL) 2106 if (csinfo[i].to_fp != NULL)
2115 { 2107 {
2116 (void)fputs("q\n", csinfo[i].to_fp); 2108 (void)fputs("q\n", csinfo[i].to_fp);
2117 (void)fflush(csinfo[i].to_fp); 2109 (void)fflush(csinfo[i].to_fp);
2118 } 2110 }
2119 /* give cscope chance to exit normally */ 2111 if (csinfo[i].hProc != NULL)
2120 if (csinfo[i].hProc != NULL 2112 {
2121 && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) 2113 /* Give cscope a chance to exit normally */
2122 TerminateProcess(csinfo[i].hProc, 0); 2114 if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
2115 TerminateProcess(csinfo[i].hProc, 0);
2116 CloseHandle(csinfo[i].hProc);
2117 }
2123 #endif 2118 #endif
2124 2119
2125 if (csinfo[i].fr_fp != NULL) 2120 if (csinfo[i].fr_fp != NULL)
2126 (void)fclose(csinfo[i].fr_fp); 2121 (void)fclose(csinfo[i].fr_fp);
2127 if (csinfo[i].to_fp != NULL) 2122 if (csinfo[i].to_fp != NULL)
2300 2295
2301 wait_return(TRUE); 2296 wait_return(TRUE);
2302 return CSCOPE_SUCCESS; 2297 return CSCOPE_SUCCESS;
2303 } /* cs_show */ 2298 } /* cs_show */
2304 2299
2300
2301 /*
2302 * PUBLIC: cs_end
2303 *
2304 * Only called when VIM exits to quit any cscope sessions.
2305 */
2306 void
2307 cs_end()
2308 {
2309 int i;
2310
2311 for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
2312 cs_release_csp(i, TRUE);
2313 }
2314
2305 #endif /* FEAT_CSCOPE */ 2315 #endif /* FEAT_CSCOPE */
2306 2316
2307 /* the end */ 2317 /* the end */