xref: /vim-8.2.3635/src/vimrun.c (revision 51b6eb47)
1edf3f97aSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2071d4279SBram Moolenaar  *
3071d4279SBram Moolenaar  * VIM - Vi IMproved	by Bram Moolenaar
4071d4279SBram Moolenaar  *			this file by Vince Negri
5071d4279SBram Moolenaar  *
6071d4279SBram Moolenaar  * Do ":help uganda"  in Vim to read copying and usage conditions.
7071d4279SBram Moolenaar  * Do ":help credits" in Vim to see a list of people who contributed.
8071d4279SBram Moolenaar  * See README.txt for an overview of the Vim source code.
9071d4279SBram Moolenaar  */
10071d4279SBram Moolenaar 
11071d4279SBram Moolenaar /*
12071d4279SBram Moolenaar  * vimrun.c - Tiny Win32 program to safely run an external command in a
13071d4279SBram Moolenaar  *	      DOS console.
14071d4279SBram Moolenaar  *	      This program is required to avoid that typing CTRL-C in the DOS
15071d4279SBram Moolenaar  *	      console kills Vim.  Now it only kills vimrun.
16071d4279SBram Moolenaar  */
17071d4279SBram Moolenaar 
18071d4279SBram Moolenaar #include <stdio.h>
19071d4279SBram Moolenaar #include <stdlib.h>
20071d4279SBram Moolenaar #include <conio.h>
21bcc1dcc9SBram Moolenaar #ifndef WIN32_LEAN_AND_MEAN
22bcc1dcc9SBram Moolenaar # define WIN32_LEAN_AND_MEAN
23071d4279SBram Moolenaar #endif
24bcc1dcc9SBram Moolenaar #include <windows.h>
25071d4279SBram Moolenaar 
26071d4279SBram Moolenaar     int
main(void)27071d4279SBram Moolenaar main(void)
28071d4279SBram Moolenaar {
29bcc1dcc9SBram Moolenaar     const wchar_t   *p;
302efc44b3SBram Moolenaar     wchar_t	    *cmd;
312efc44b3SBram Moolenaar     size_t	    cmdlen;
32071d4279SBram Moolenaar     int		    retval;
33071d4279SBram Moolenaar     int		    inquote = 0;
34071d4279SBram Moolenaar     int		    silent = 0;
35bcc1dcc9SBram Moolenaar     HANDLE	    hstdout;
36bcc1dcc9SBram Moolenaar     DWORD	    written;
37071d4279SBram Moolenaar 
38bcc1dcc9SBram Moolenaar     p = (const wchar_t *)GetCommandLineW();
39bcc1dcc9SBram Moolenaar 
40071d4279SBram Moolenaar     /*
41071d4279SBram Moolenaar      * Skip the executable name, which might be in "".
42071d4279SBram Moolenaar      */
43071d4279SBram Moolenaar     while (*p)
44071d4279SBram Moolenaar     {
45bcc1dcc9SBram Moolenaar 	if (*p == L'"')
46071d4279SBram Moolenaar 	    inquote = !inquote;
47bcc1dcc9SBram Moolenaar 	else if (!inquote && *p == L' ')
48071d4279SBram Moolenaar 	{
49071d4279SBram Moolenaar 	    ++p;
50071d4279SBram Moolenaar 	    break;
51071d4279SBram Moolenaar 	}
52071d4279SBram Moolenaar 	++p;
53071d4279SBram Moolenaar     }
54bcc1dcc9SBram Moolenaar     while (*p == L' ')
55f59c73daSBram Moolenaar 	++p;
56071d4279SBram Moolenaar 
57071d4279SBram Moolenaar     /*
58071d4279SBram Moolenaar      * "-s" argument: don't wait for a key hit.
59071d4279SBram Moolenaar      */
60bcc1dcc9SBram Moolenaar     if (p[0] == L'-' && p[1] == L's' && p[2] == L' ')
61071d4279SBram Moolenaar     {
62071d4279SBram Moolenaar 	silent = 1;
63071d4279SBram Moolenaar 	p += 3;
64bcc1dcc9SBram Moolenaar 	while (*p == L' ')
65071d4279SBram Moolenaar 	    ++p;
66071d4279SBram Moolenaar     }
67071d4279SBram Moolenaar 
682efc44b3SBram Moolenaar     // Print the command, including quotes and redirection.
69bcc1dcc9SBram Moolenaar     hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
70bcc1dcc9SBram Moolenaar     WriteConsoleW(hstdout, p, wcslen(p), &written, NULL);
71bcc1dcc9SBram Moolenaar     WriteConsoleW(hstdout, L"\r\n", 2, &written, NULL);
72071d4279SBram Moolenaar 
732efc44b3SBram Moolenaar     // If the command starts and ends with double quotes,
742efc44b3SBram Moolenaar     // Enclose the command in parentheses.
752efc44b3SBram Moolenaar     cmd = NULL;
762efc44b3SBram Moolenaar     cmdlen = wcslen(p);
772efc44b3SBram Moolenaar     if (cmdlen >= 2 && p[0] == L'"' && p[cmdlen - 1] == L'"')
782efc44b3SBram Moolenaar     {
792efc44b3SBram Moolenaar 	cmdlen += 3;
80*51b6eb47SBram Moolenaar 	cmd = malloc(cmdlen * sizeof(wchar_t));
812efc44b3SBram Moolenaar 	if (cmd == NULL)
822efc44b3SBram Moolenaar 	{
832efc44b3SBram Moolenaar 	    perror("vimrun malloc(): ");
842efc44b3SBram Moolenaar 	    return -1;
852efc44b3SBram Moolenaar 	}
862efc44b3SBram Moolenaar 	_snwprintf(cmd, cmdlen, L"(%s)", p);
872efc44b3SBram Moolenaar 	p = cmd;
882efc44b3SBram Moolenaar     }
892efc44b3SBram Moolenaar 
90071d4279SBram Moolenaar     /*
91071d4279SBram Moolenaar      * Do it!
92071d4279SBram Moolenaar      */
93bcc1dcc9SBram Moolenaar     retval = _wsystem(p);
94071d4279SBram Moolenaar 
952efc44b3SBram Moolenaar     if (cmd)
962efc44b3SBram Moolenaar 	free(cmd);
972efc44b3SBram Moolenaar 
989964e468SBram Moolenaar     if (retval == -1)
999964e468SBram Moolenaar 	perror("vimrun system(): ");
1009964e468SBram Moolenaar     else if (retval != 0)
101071d4279SBram Moolenaar 	printf("shell returned %d\n", retval);
102071d4279SBram Moolenaar 
103071d4279SBram Moolenaar     if (!silent)
104071d4279SBram Moolenaar     {
105071d4279SBram Moolenaar 	puts("Hit any key to close this window...");
106071d4279SBram Moolenaar 
107071d4279SBram Moolenaar 	while (_kbhit())
108071d4279SBram Moolenaar 	    (void)_getch();
109071d4279SBram Moolenaar 	(void)_getch();
110071d4279SBram Moolenaar     }
111071d4279SBram Moolenaar 
112071d4279SBram Moolenaar     return retval;
113071d4279SBram Moolenaar }
114