Module: wine
Branch: master
Commit: 88f14bb59045e1d8c8bb0a71abb50f505620c420
URL: http://source.winehq.org/git/wine.git/?a=commit;h=88f14bb59045e1d8c8bb0a71a…
Author: Jason Edmeades <jason(a)edmeades.me.uk>
Date: Tue Oct 2 00:35:47 2012 +0100
cmd: Fix basic cmd.exe /c "echo hello" type syntax.
Add checks for existance of command to run in order to keep the
new quote handling capabilities of cmd.exe /C or /K. If the command
cannot be found, drop back to /S processing mode as per cmd.exe help.
---
programs/cmd/tests/test_builtins.cmd | 1 +
programs/cmd/tests/test_builtins.cmd.exp | 7 ++-
programs/cmd/wcmdmain.c | 71 +++++++++++++++++++++++++++++-
3 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 1c0f875..3e064b9 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -1829,6 +1829,7 @@ rem Basic test of command line. Note a section prefix per command
rem to resync, as wine does not output anything in these cases yet.
echo --- Test 1
cmd.exe /c echo Line1
+cmd.exe /c echo "Line2"
echo --- Test 2
cmd.exe /c echo Test quotes "&" work
echo --- Test 3
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index e817706..6483f1e 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -910,6 +910,7 @@ value1
------------ cmd.exe command lines ------------
--- Test 1
Line1
+@todo_wine@"Line2"
--- Test 2
@todo_wine@Test quotes "&" work
--- Test 3
@@ -929,11 +930,11 @@ Line1
--- Test 10
--- Test 11
--- Test 12
-@todo_wine@passed1
+passed1
--- Test 13
-@todo_wine@passed2@space@
+passed2@space@
--- Test 14
-@todo_wine@foobar
+foobar
--- Test 15
No prompts or I would not get here1
No prompts or I would not get here2
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 0e7a197..675256b 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -2419,10 +2419,12 @@ int wmain (int argc, WCHAR *argvW[])
}
}
+ /* If there is not exactly 2 quote characters, then /S (old behaviour) is enabled */
if (qcount!=2)
opt_s = TRUE;
- /* check argvW[0] for a space and invalid characters */
+ /* check argvW[0] for a space and invalid characters. There must not be any invalid
+ * characters, but there must be one or more whitespace */
if (!opt_s) {
opt_s = TRUE;
p=*argvW;
@@ -2432,7 +2434,7 @@ int wmain (int argc, WCHAR *argvW[])
opt_s = TRUE;
break;
}
- if (*p==' ')
+ if (*p==' ' || *p=='\t')
opt_s = FALSE;
p++;
}
@@ -2507,6 +2509,71 @@ int wmain (int argc, WCHAR *argvW[])
WINE_TRACE("/c command line: '%s'\n", wine_dbgstr_w(cmd));
+ /* Finally, we only stay in new mode IF the first parameter is quoted and
+ is a valid executable, ie must exist, otherwise drop back to old mode */
+ if (!opt_s) {
+ WCHAR *thisArg = WCMD_parameter(cmd, 0, NULL, NULL, FALSE);
+ static const WCHAR extEXEW[] = {'.','e','x','e','\0'};
+ static const WCHAR extCOMW[] = {'.','c','o','m','\0'};
+ BOOL found = FALSE;
+
+ /* If the supplied parameter has any directory information, look there */
+ WINE_TRACE("First parameter is '%s'\n", wine_dbgstr_w(thisArg));
+ if (strchrW(thisArg, '\\') != NULL) {
+
+ GetFullPathNameW(thisArg, sizeof(string)/sizeof(WCHAR), string, NULL);
+ WINE_TRACE("Full path name '%s'\n", wine_dbgstr_w(string));
+ p = string + strlenW(string);
+
+ /* Does file exist with this name? */
+ if (GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ } else strcpyW(p, extEXEW);
+
+ /* Does file exist with .exe appended */
+ if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ } else strcpyW(p, extCOMW);
+
+ /* Does file exist with .com appended */
+ if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Otherwise we now need to look in the path to see if we can find it */
+ } else {
+ p = thisArg + strlenW(thisArg);
+
+ /* Does file exist with this name? */
+ if (SearchPathW(NULL, thisArg, NULL, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Does file exist plus an extension of .exe? */
+ if (SearchPathW(NULL, thisArg, extEXEW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Does file exist plus an extension of .com? */
+ if (SearchPathW(NULL, thisArg, extCOMW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+ }
+
+ /* If not found, drop back to old behaviour */
+ if (!found) {
+ WINE_TRACE("Binary not found, dropping back to old behaviour\n");
+ opt_s = TRUE;
+ }
+
+ }
+
/* strip first and last quote characters if opt_s; check for invalid
* executable is done later */
if (opt_s && *cmd=='\"')