Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/cmd/batch.c | 54 +--------------------------------------- programs/cmd/builtins.c | 10 ++++---- programs/cmd/directory.c | 6 ++--- programs/cmd/wcmd.h | 1 - 4 files changed, 9 insertions(+), 62 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index 371f75af54..06437ecf1b 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -301,58 +301,6 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) return buf; }
-/* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */ -void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext) -{ - const WCHAR* end; /* end of processed string */ - const WCHAR* p; /* search pointer */ - const WCHAR* s; /* copy pointer */ - - /* extract drive name */ - if (path[0] && path[1]==':') { - if (drv) { - *drv++ = *path++; - *drv++ = *path++; - *drv = '\0'; - } - } else if (drv) - *drv = '\0'; - - end = path + lstrlenW(path); - - /* search for begin of file extension */ - for(p=end; p>path && *--p!='\' && *p!='/'; ) - if (*p == '.') { - end = p; - break; - } - - if (ext) - for(s=end; (*ext=*s++); ) - ext++; - - /* search for end of directory name */ - for(p=end; p>path; ) - if (*--p=='\' || *p=='/') { - p++; - break; - } - - if (name) { - for(s=p; s<end; ) - *name++ = *s++; - - *name = '\0'; - } - - if (dir) { - for(s=path; s<p; ) - *dir++ = *s++; - - *dir = '\0'; - } -} - /**************************************************************************** * WCMD_HandleTildaModifiers * @@ -627,7 +575,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, BOOL atExecute) BOOL addSpace = (finaloutput[0] != 0x00);
/* Split into components */ - WCMD_splitpath(fullfilename, drive, dir, fname, ext); + _wsplitpath(fullfilename, drive, dir, fname, ext);
/* 5. Handle 'd' : Drive Letter */ if (wmemchr(firstModifier, 'd', modifierLen) != NULL) { diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 43c4d9efef..1870e5688d 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1217,7 +1217,7 @@ static BOOL WCMD_delete_confirm_wildcard(const WCHAR *filename, BOOL *pPrompted)
/* Convert path into actual directory spec */ GetFullPathNameW(filename, ARRAY_SIZE(fpath), fpath, NULL); - WCMD_splitpath(fpath, drive, dir, fname, ext); + _wsplitpath(fpath, drive, dir, fname, ext);
/* Only prompt for * and *.*, not *a, a*, *.a* etc */ if ((lstrcmpW(fname, starW) == 0) && @@ -1352,7 +1352,7 @@ static BOOL WCMD_delete_one (const WCHAR *thisArg) {
/* Convert path into actual directory spec */ GetFullPathNameW(argCopy, ARRAY_SIZE(thisDir), thisDir, NULL); - WCMD_splitpath(thisDir, drive, dir, fname, ext); + _wsplitpath(thisDir, drive, dir, fname, ext);
lstrcpyW(thisDir, drive); lstrcatW(thisDir, dir); @@ -2986,7 +2986,7 @@ void WCMD_move (void) wine_dbgstr_w(param1), wine_dbgstr_w(output));
/* Split into components */ - WCMD_splitpath(input, drive, dir, fname, ext); + _wsplitpath(input, drive, dir, fname, ext);
hff = FindFirstFileW(input, &fd); if (hff == INVALID_HANDLE_VALUE) @@ -3207,7 +3207,7 @@ void WCMD_rename (void) dotDst = wcschr(param2, '.');
/* Split into components */ - WCMD_splitpath(input, drive, dir, fname, ext); + _wsplitpath(input, drive, dir, fname, ext);
hff = FindFirstFileW(input, &fd); if (hff == INVALID_HANDLE_VALUE) @@ -3492,7 +3492,7 @@ void WCMD_setshow_default (const WCHAR *args) {
/* Convert path into actual directory spec */ GetFullPathNameW(string, ARRAY_SIZE(fpath), fpath, NULL); - WCMD_splitpath(fpath, drive, dir, fname, ext); + _wsplitpath(fpath, drive, dir, fname, ext);
/* Rebuild path */ wsprintfW(string, fmt, drive, dir, fd.cFileName); diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c index 41e1f4e929..2d35f8eb1d 100644 --- a/programs/cmd/directory.c +++ b/programs/cmd/directory.c @@ -166,8 +166,8 @@ static int __cdecl WCMD_dir_sort (const void *a, const void *b) WCHAR extB[MAX_PATH];
/* Split into components */ - WCMD_splitpath(filea->cFileName, drive, dir, fname, extA); - WCMD_splitpath(fileb->cFileName, drive, dir, fname, extB); + _wsplitpath(filea->cFileName, drive, dir, fname, extA); + _wsplitpath(fileb->cFileName, drive, dir, fname, extB); result = lstrcmpiW(extA, extB); }
@@ -819,7 +819,7 @@ void WCMD_directory (WCHAR *args) thisEntry->next = NULL;
/* Split into components */ - WCMD_splitpath(path, drive, dir, fname, ext); + _wsplitpath(path, drive, dir, fname, ext); WINE_TRACE("Path Parts: drive: '%s' dir: '%s' name: '%s' ext:'%s'\n", wine_dbgstr_w(drive), wine_dbgstr_w(dir), wine_dbgstr_w(fname), wine_dbgstr_w(ext)); diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 112fc1a1ea..247f3dfdf3 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -117,7 +117,6 @@ WCHAR *WCMD_skip_leading_spaces (WCHAR *string); BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr); void WCMD_HandleTildaModifiers(WCHAR **start, BOOL atExecute);
-void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext); WCHAR *WCMD_strip_quotes(WCHAR *cmd); WCHAR *WCMD_LoadMessage(UINT id); void WCMD_strsubstW(WCHAR *start, const WCHAR* next, const WCHAR* insert, int len);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/cmd/batch.c | 4 ++-- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index 06437ecf1b..3aa40874ae 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -302,7 +302,7 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) }
/**************************************************************************** - * WCMD_HandleTildaModifiers + * WCMD_HandleTildeModifiers * * Handle the ~ modifiers when expanding %0-9 or (%a-z/A-Z in for command) * %~xxxxxV (V=0-9 or A-Z, a-z) @@ -333,7 +333,7 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) * Hence search forwards until find an invalid modifier, and then * backwards until find for variable or 0-9 */ -void WCMD_HandleTildaModifiers(WCHAR **start, BOOL atExecute) +void WCMD_HandleTildeModifiers(WCHAR **start, BOOL atExecute) {
#define NUMMODIFIERS 11 diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 247f3dfdf3..9ae87ea706 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -115,7 +115,7 @@ WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, BOOL raw, BOOL wholecmdline, const WCHAR *delims); WCHAR *WCMD_skip_leading_spaces (WCHAR *string); BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr); -void WCMD_HandleTildaModifiers(WCHAR **start, BOOL atExecute); +void WCMD_HandleTildeModifiers(WCHAR **start, BOOL atExecute);
WCHAR *WCMD_strip_quotes(WCHAR *cmd); WCHAR *WCMD_LoadMessage(UINT id); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 2834986bf9..90df222b16 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -853,7 +853,7 @@ static void handleExpansion(WCHAR *cmd, BOOL atExecute, BOOL delayed) {
/* Replace %~ modifications if in batch program */ } else if (*(p+1) == '~') { - WCMD_HandleTildaModifiers(&p, atExecute); + WCMD_HandleTildeModifiers(&p, atExecute); p++;
/* Replace use of %0...%9 if in batch program*/
This fixes a hang in the WinTV 8.5 installer.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/cmd/tests/test_cmdline.cmd | 19 +++-- programs/cmd/tests/test_cmdline.cmd.exp | 12 ++- programs/cmd/wcmdmain.c | 97 ++++++++++++------------- 3 files changed, 68 insertions(+), 60 deletions(-)
diff --git a/programs/cmd/tests/test_cmdline.cmd b/programs/cmd/tests/test_cmdline.cmd index 32a1ef2e48..7a7f8d7b63 100644 --- a/programs/cmd/tests/test_cmdline.cmd +++ b/programs/cmd/tests/test_cmdline.cmd @@ -183,12 +183,19 @@ echo ------- Testing CMD /C qualifier treatment ------------ rem no need for space after /c cmd /csay one cmd /c"say one" -rem ignore quote before qualifier -rem FIXME the next command in wine starts a sub-CMD -echo THIS FAILS: cmd "/c"say one -rem ignore anything before /c -rem FIXME the next command in wine starts a sub-CMD -echo THIS FAILS: cmd ignoreme/c say one +cmd /c"say one +cmd /c=say one +cmd /c,say one +cmd /c;say one +rem non-options are ignored before /c; quotes are not treated specially +cmd "/c"say one +cmd ignoreme/c say one +cmd abc "def ghi/c say one" +cmd -@$*'"/c say one +echo echo bar > foo.bat +cmd /qq/c foo +cmd /q "xyz /c foo" +del foo.bat
echo --------- Testing special characters -------------- echo @echo amp > "say&.bat" diff --git a/programs/cmd/tests/test_cmdline.cmd.exp b/programs/cmd/tests/test_cmdline.cmd.exp index 980f67411c..7978a249c9 100644 --- a/programs/cmd/tests/test_cmdline.cmd.exp +++ b/programs/cmd/tests/test_cmdline.cmd.exp @@ -90,8 +90,16 @@ Passed ------- Testing CMD /C qualifier treatment ------------ 0@space@ 1@space@ -THIS FAILS: cmd "/c"say one -THIS FAILS: cmd ignoreme/c say one +0@space@ +0@space@ +0@space@ +0@space@ +0@space@ +0@space@ +0@space@ +0@space@ +bar@space@ +bar@space@ --------- Testing special characters -------------- 0@space@ 0@space@ diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 90df222b16..2819f7fa99 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -2421,10 +2421,8 @@ void WCMD_free_commands(CMD_LIST *cmds) {
int __cdecl wmain (int argc, WCHAR *argvW[]) { - int args; WCHAR *cmdLine = NULL; WCHAR *cmd = NULL; - WCHAR *argPos = NULL; WCHAR string[1024]; WCHAR envvar[4]; BOOL promptNewLine = TRUE; @@ -2440,6 +2438,7 @@ int __cdecl wmain (int argc, WCHAR *argvW[]) RTL_OSVERSIONINFOEXW osv; char osver[50]; STARTUPINFOW startupInfo; + const WCHAR *arg;
if (!GetEnvironmentVariableW(comspecW, comspec, ARRAY_SIZE(comspec))) { @@ -2467,57 +2466,55 @@ int __cdecl wmain (int argc, WCHAR *argvW[]) */ cmdLine = GetCommandLineW(); WINE_TRACE("Full commandline '%s'\n", wine_dbgstr_w(cmdLine)); - args = 0; + + while (*cmdLine && *cmdLine != '/') ++cmdLine;
opt_c = opt_k = opt_q = opt_s = FALSE; - WCMD_parameter(cmdLine, args, &argPos, TRUE, TRUE); - while (argPos && argPos[0] != 0x00) - { - WCHAR c; - WINE_TRACE("Command line parm: '%s'\n", wine_dbgstr_w(argPos)); - if (argPos[0]!='/' || argPos[1]=='\0') { - args++; - WCMD_parameter(cmdLine, args, &argPos, TRUE, TRUE); - continue; - }
- c=argPos[1]; - if (towlower(c)=='c') { - opt_c = TRUE; - } else if (towlower(c)=='q') { - opt_q = TRUE; - } else if (towlower(c)=='k') { - opt_k = TRUE; - } else if (towlower(c)=='s') { - opt_s = TRUE; - } else if (towlower(c)=='a') { - unicodeOutput = FALSE; - } else if (towlower(c)=='u') { - unicodeOutput = TRUE; - } else if (towlower(c)=='v' && argPos[2]==':') { - delayedsubst = wcsnicmp(&argPos[3], offW, 3); - if (delayedsubst) WINE_TRACE("Delayed substitution is on\n"); - } else if (towlower(c)=='t' && argPos[2]==':') { - opt_t=wcstoul(&argPos[3], NULL, 16); - } else if (towlower(c)=='x' || towlower(c)=='y') { - /* Ignored for compatibility with Windows */ - } + for (arg = cmdLine; *arg; ++arg) + { + if (arg[0] != '/') + continue;
- if (argPos[2]==0 || argPos[2]==' ' || argPos[2]=='\t' || - towlower(c)=='v') { - args++; - WCMD_parameter(cmdLine, args, &argPos, TRUE, TRUE); - } - else /* handle `cmd /cnotepad.exe` and `cmd /x/c ...` */ - { - /* Do not step to next parameter, instead carry on parsing this one */ - argPos+=2; - } + switch (towlower(arg[1])) + { + case 'a': + unicodeOutput = FALSE; + break; + case 'c': + opt_c = TRUE; + break; + case 'k': + opt_k = TRUE; + break; + case 'q': + opt_q = TRUE; + break; + case 's': + opt_s = TRUE; + break; + case 't': + if (arg[2] == ':') + opt_t = wcstoul(&arg[3], NULL, 16); + break; + case 'u': + unicodeOutput = TRUE; + break; + case 'v': + if (arg[2] == ':') + delayedsubst = wcsnicmp(&arg[3], L"OFF", 3); + break; + }
- if (opt_c || opt_k) /* break out of parsing immediately after c or k */ - break; + if (opt_c || opt_k) + { + arg += 2; + break; + } }
+ while (*arg && wcschr(L" \t,=;", *arg)) arg++; + if (opt_q) { WCMD_echo(offW); } @@ -2531,12 +2528,8 @@ int __cdecl wmain (int argc, WCHAR *argvW[]) int len; WCHAR *q1 = NULL,*q2 = NULL,*p;
- /* Handle very edge case error scenario, "cmd.exe /c" ie when there are no - * parameters after the /C or /K by pretending there was a single space */ - if (argPos == NULL) argPos = (WCHAR *)spaceW; - /* Take a copy */ - cmd = heap_strdupW(argPos); + cmd = heap_strdupW(arg);
/* opt_s left unflagged if the command starts with and contains exactly * one quoted string (exactly two quote characters). The quoted string @@ -2545,7 +2538,7 @@ int __cdecl wmain (int argc, WCHAR *argvW[])
if (!opt_s) { /* 1. Confirm there is at least one quote */ - q1 = wcschr(argPos, '"'); + q1 = wcschr(arg, '"'); if (!q1) opt_s=1; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70549
Your paranoid android.
=== w1064v1809_he (32 bit report) ===
cmd.exe: batch.c:321: Test failed: unexpected char 0x43 position 0 in line 983 (got 'C:\Users\winetest\Documents\foobar\temp.bat', wanted 'Mixed enumeration from provided root') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 984 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\bar."', wanted 'With duplicates enumeration') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 985 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\baz."', wanted 'Strip missing wildcards, keep unwildcarded names') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 986 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\baz\bazbaz"', wanted 'for /R passed') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 987 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\bazbaz"', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 988 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\foo."', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x4d position 0 in line 989 (got 'Mixed enumeration from provided root', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x57 position 0 in line 990 (got 'With duplicates enumeration', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x53 position 0 in line 991 (got 'Strip missing wildcards, keep unwildcarded names', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x66 position 0 in line 992 (got 'for /R passed', wanted '--- Complex wildcards unix and windows slash')
On 4/25/20 11:20 PM, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70549
Your paranoid android.
=== w1064v1809_he (32 bit report) ===
cmd.exe: batch.c:321: Test failed: unexpected char 0x43 position 0 in line 983 (got 'C:\Users\winetest\Documents\foobar\temp.bat', wanted 'Mixed enumeration from provided root') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 984 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\bar."', wanted 'With duplicates enumeration') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 985 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\baz."', wanted 'Strip missing wildcards, keep unwildcarded names') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 986 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\baz\bazbaz"', wanted 'for /R passed') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 987 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\bazbaz"', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x46 position 0 in line 988 (got 'Found missing result: "C:\Users\winetest\Documents\foobar\foo."', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x4d position 0 in line 989 (got 'Mixed enumeration from provided root', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x57 position 0 in line 990 (got 'With duplicates enumeration', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x53 position 0 in line 991 (got 'Strip missing wildcards, keep unwildcarded names', wanted '--- Complex wildcards unix and windows slash') batch.c:321: Test failed: unexpected char 0x66 position 0 in line 992 (got 'for /R passed', wanted '--- Complex wildcards unix and windows slash')
I can't easily find record of this failure occurring before, but it's in test_builtins, so presumably unrelated.
If I get time, I'll try to look into it...