Mercurial > vim
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 */ |