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