This MR fixes two bugzilla entries against cmd.exe.
From: Eric Pouech epouech@codeweavers.com
Mainly shows that upon batch invocation return from another batch file, i echo mode is kept; whereas, from command line, the echo mode is always reset to ON.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 50 ++++++++++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 7 ++++ 2 files changed, 57 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 8552d51930a..01eef4fd7de 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -84,6 +84,56 @@ type mixedEchoModes.cmd cmd /c mixedEchoModes.cmd del mixedEchoModes.cmd
+echo ------------ Testing call and echo modes ------------ +rem echo on/off is propagated back to caller (except in interactive mode) +@echo off +@FOR /F "tokens=* usebackq" %%F IN (`echo`) DO SET "wine_echo_on=%%F" +goto :hopCallEchoModes + +rem ensure comparison isn't locale dependant +:showEchoMode +@FOR /F "tokens=*" %%F IN (%1) DO @IF "%%F"=="%wine_echo_on%" (@echo ECHO_IS_ON) else (@echo ECHO_IS_OFF) +@del %1 +@exit /b 0 +:hopCallEchoModes + +echo %%*> callme.cmd +rem ensure that :showEchoMode works as expected +@echo on +@echo>foo.tmp +@call :showEchoMode foo.tmp +@echo off +@echo>foo.tmp +@call :showEchoMode foo.tmp +rem test inside a batch file, that caller keeps callee echo on/off status +@echo off +@call callme.cmd @echo on +@echo>foo.tmp +@call :showEchoMode foo.tmp +@echo on +@call callme.cmd @echo off +@echo>foo.tmp +@call :showEchoMode foo.tmp +@echo off + +rem test in interactive mode... echo is always preserved after a call +@echo echo on>foo.txt +@echo call callme.cmd @echo off>>foo.txt +@echo echo^>foo.tmp>>foo.txt +type foo.txt | cmd.exe > NULL +@call :showEchoMode foo.tmp + +@echo echo off>foo.txt +@echo call callme.cmd @echo on>>foo.txt +@echo echo^>foo.tmp>>foo.txt +type foo.txt | cmd.exe > NULL +@call :showEchoMode foo.tmp + +rem cleanup +del foo.txt +del callme.cmd +set wine_echo_on= +@echo off echo ------------ Testing parameterization ------------ call :TestParm a b c call :TestParm "a b c" diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 292c24985e8..0acdca096e3 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -142,6 +142,13 @@ foo bar foo2 bar2 +------------ Testing call and echo modes ------------ +ECHO_IS_ON +ECHO_IS_OFF +ECHO_IS_ON +ECHO_IS_OFF +@todo_wine@ECHO_IS_ON +@todo_wine@ECHO_IS_OFF ------------ Testing parameterization ------------ 'a', 'b', 'c' '"a b c"', '', ''
From: Eric Pouech epouech@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57804
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd.exp | 4 ++-- programs/cmd/wcmdmain.c | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 0acdca096e3..c58567bf241 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -147,8 +147,8 @@ ECHO_IS_ON ECHO_IS_OFF ECHO_IS_ON ECHO_IS_OFF -@todo_wine@ECHO_IS_ON -@todo_wine@ECHO_IS_OFF +ECHO_IS_ON +ECHO_IS_OFF ------------ Testing parameterization ------------ 'a', 'b', 'c' '"a b c"', '', '' diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index b19f8453438..48589a2245d 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1903,8 +1903,11 @@ RETURN_CODE WCMD_call_command(WCHAR *command) return_code = search_command(command, &sc, FALSE); if (return_code == NO_ERROR) { + unsigned old_echo_mode = echo_mode; if (!*sc.path) return NO_ERROR; - return run_full_path(sc.path, command, TRUE); + return_code = run_full_path(sc.path, command, TRUE); + if (interactive) echo_mode = old_echo_mode; + return return_code; }
if (sc.cmd_index <= WCMD_EXIT)
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 13 +++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 12 ++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 01eef4fd7de..4dadeaeb9c0 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1030,6 +1030,19 @@ echo %WINE_VAR:~2,-3% echo '%WINE_VAR:~-2,-4%' echo %WINE_VAR:~-3,-2% echo %WINE_VAR:~4,4% +echo '%WINE_VAR:~5%' +echo '%WINE_VAR:~6%' +echo '%WINE_VAR:~7%' +echo '%WINE_VAR:~-0%' +echo '%WINE_VAR:~,%' +echo '%WINE_VAR:~,2%' +echo '%WINE_VAR:~2a%' +echo '%WINE_VAR:~2a,2%' +echo '%WINE_VAR:~a,2%' +echo '%WINE_VAR:~2,2a%' +echo '%WINE_VAR:~-%' + +echo ------------ Testing variable partial replacement ------------ set WINE_VAR=qwertyQWERTY echo %WINE_VAR:qw=az% echo %WINE_VAR:qw=% diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index c58567bf241..63487a098a5 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -777,6 +777,18 @@ e@or_broken@qwerty ''@or_broken@'qwerty' r@or_broken@qwerty ty +'y' +@todo_wine@'' +@todo_wine@'' +'qwerty' +'' +'qw' +@todo_wine@'WINE_VAR:~2a' +@todo_wine@'WINE_VAR:~2a,2' +@todo_wine@'WINE_VAR:~a,2' +@todo_wine@'WINE_VAR:~2,2a' +@todo_wine@'WINE_VAR:~-' +------------ Testing variable partial replacement ------------ azertyazERTY ertyERTY =_QWERTY
From: Eric Pouech epouech@codeweavers.com
Also fix returned string in case of incorrect range for substring.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57809
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd.exp | 14 +++---- programs/cmd/wcmdmain.c | 48 +++++++++++------------- 2 files changed, 28 insertions(+), 34 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 63487a098a5..5b0a93bd22d 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -778,16 +778,16 @@ e@or_broken@qwerty r@or_broken@qwerty ty 'y' -@todo_wine@'' -@todo_wine@'' +'' +'' 'qwerty' '' 'qw' -@todo_wine@'WINE_VAR:~2a' -@todo_wine@'WINE_VAR:~2a,2' -@todo_wine@'WINE_VAR:~a,2' -@todo_wine@'WINE_VAR:~2,2a' -@todo_wine@'WINE_VAR:~-' +'WINE_VAR:~2a' +'WINE_VAR:~2a,2' +'WINE_VAR:~a,2' +'WINE_VAR:~2,2a' +'WINE_VAR:~-' ------------ Testing variable partial replacement ------------ azertyazERTY ertyERTY diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 48589a2245d..9c7377e3258 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -514,6 +514,13 @@ WCHAR *WCMD_strip_quotes(WCHAR *cmd) { return lastquote; }
+static inline int read_int_in_range(const WCHAR *from, WCHAR **after, int low, int high) +{ + int val = wcstol(from, after, 10); + val += (val < 0) ? high : low; + return val <= low ? low : (val >= high ? high : val); +} + /************************************************************************* * WCMD_expand_envvar * @@ -598,34 +605,21 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start) */
/* ~ is substring manipulation */ - if (colonpos[1] == L'~') { - - int substrposition, substrlength = 0; - WCHAR *commapos = wcschr(colonpos+2, L','); - WCHAR *startCopy; - - substrposition = wcstol(colonpos+2, NULL, 10); - if (commapos) substrlength = wcstol(commapos+1, NULL, 10); - - /* Check bounds */ - if (substrposition >= 0) { - startCopy = &thisVarContents[min(substrposition, len - 1)]; - } else { - startCopy = &thisVarContents[max(0, len + substrposition)]; - } - - if (commapos == NULL) - /* Copy the lot */ - return WCMD_strsubstW(start, endOfVar + 1, startCopy, -1); - if (substrlength < 0) { + if (colonpos[1] == L'~') + { + int substr_beg, substr_end; + WCHAR *ptr;
- int copybytes = len + substrlength - (startCopy - thisVarContents); - if (copybytes >= len) copybytes = len - 1; - else if (copybytes < 0) copybytes = 0; - return WCMD_strsubstW(start, endOfVar + 1, startCopy, copybytes); - } - substrlength = min(substrlength, len - (startCopy - thisVarContents)); - return WCMD_strsubstW(start, endOfVar + 1, startCopy, substrlength); + substr_beg = read_int_in_range(colonpos + 2, &ptr, 0, len); + if (*ptr == L',') + substr_end = read_int_in_range(ptr + 1, &ptr, substr_beg, len); + else + substr_end = len; + if (*ptr == L'\0') + return WCMD_strsubstW(start, endOfVar + 1, &thisVarContents[substr_beg], substr_end - substr_beg); + /* error, remove enclosing % pair (in place) */ + memmove(start, start + 1, (endOfVar - start - 1) * sizeof(WCHAR)); + return WCMD_strsubstW(endOfVar - 1, endOfVar + 1, NULL, 0); /* search and replace manipulation */ } else { WCHAR *equalspos = wcschr(colonpos, L'=');