[PATCH v11 0/2] MR8200: cmd: COPY should output file names as they are copied.
In native Windows, the COPY command will display the names of the files as they are copied. Wine should do the same. This change enables that. -- v11: cmd: COPY should output file names as they are copied. cmd/tests: Add tests to verify COPY command output. https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/tests/test_builtins.cmd | 79 ++++++++++++++++++------ programs/cmd/tests/test_builtins.cmd.exp | 42 +++++++++++++ 2 files changed, 102 insertions(+), 19 deletions(-) diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 58d78194380..8ae733681eb 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -3416,6 +3416,30 @@ shift if not "%1"=="" goto :CheckNotExist goto :eof +:CheckOutputExist +find /i "%1" test1.txt >nul 2>&1 +if errorlevel 0 ( + echo Passed: Found expected %1 in COPY output +) else ( + echo Failed: Did not find expected %1 in COPY output +) +shift +if not "%1"=="" goto :CheckOutputExist +del /q test1.txt >nul 2>&1 +goto :eof + +:CheckOutputNotExist +find /i "%1" test1.txt >nul 2>&1 +if errorlevel 1 ( + echo Passed: Did not find %1 in COPY output +) else ( + echo Failed: Unexpectedly found %1 in COPY output +) +shift +if not "%1"=="" goto :CheckOutputNotExist +del /q test1.txt >nul 2>&1 +goto :eof + rem Note: No way to check file size on NT4 so skip the test :CheckFileSize if not exist "%1" ( @@ -3444,28 +3468,33 @@ rem ----------------------- rem Simple single file copy rem ----------------------- rem Simple single file copy, normally used syntax -copy file1 dummy.file >nul 2>&1 +copy file1 dummy.file >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputNotExist file1 call :CheckExist dummy.file rem Simple single file copy, destination supplied as two forms of directory -copy file1 dir1 >nul 2>&1 +copy file1 dir1 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputNotExist file1 call :CheckExist dir1\file1 -copy file1 dir1\ >nul 2>&1 +copy file1 dir1\ >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputNotExist file1 call :CheckExist dir1\file1 rem Simple single file copy, destination supplied as fully qualified destination -copy file1 dir1\file99 >nul 2>&1 +copy file1 dir1\file99 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputNotExist file1 call :CheckExist dir1\file99 rem Simple single file copy, destination not supplied cd dir1 -copy ..\file1 >nul 2>&1 +copy ..\file1 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputNotExist file1 call :CheckExist file1 cd .. @@ -3477,19 +3506,22 @@ call :CheckNotExist dir2 dir2\file1 rem ----------------------- rem Wildcarded copy rem ----------------------- -rem Simple single file copy, destination supplied as two forms of directory -copy file? dir1 >nul 2>&1 +rem Simple wildcarded file copy, destination supplied as two forms of directory +copy file? dir1 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 file3 call :CheckExist dir1\file1 dir1\file2 dir1\file3 -copy file* dir1\ >nul 2>&1 +copy file* dir1\ >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 file3 call :CheckExist dir1\file1 dir1\file2 dir1\file3 -rem Simple single file copy, destination not supplied +rem Simple wildcarded file copy, destination not supplied cd dir1 -copy ..\file*.* >nul 2>&1 +copy ..\file*.* >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 file3 call :CheckExist file1 file2 file3 cd .. @@ -3502,51 +3534,60 @@ rem ------------------------------------------------ rem Confirm overwrite works (cannot test prompting!) rem ------------------------------------------------ copy file1 testfile >nul 2>&1 -copy /y file2 testfile >nul 2>&1 +copy /y file2 testfile >test1.txt 2>&1 +call :CheckOutputNotExist file2 call :CheckExist testfile rem ------------------------------------------------ rem Test concatenation rem ------------------------------------------------ rem simple case, no wildcards -copy file1+file2 testfile >nul 2>&1 +copy file1+file2 testfile >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 call :CheckExist testfile rem simple case, wildcards, no concatenation -copy file* testfile >nul 2>&1 +copy file* testfile >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 file3 call :CheckExist testfile rem simple case, wildcards, and concatenation echo ddddd > fred -copy file*+fred testfile >nul 2>&1 +copy file*+fred testfile >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist file1 file2 file3 fred call :CheckExist testfile rem simple case, wildcards, and concatenation -copy fred+file* testfile >nul 2>&1 +copy fred+file* testfile >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist fred file1 file2 file3 call :CheckExist testfile rem Calculate destination name -copy fred+file* dir1 >nul 2>&1 +copy fred+file* dir1 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist fred file1 file2 file3 call :CheckExist dir1\fred rem Calculate destination name -copy fred+file* dir1\ >nul 2>&1 +copy fred+file* dir1\ >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist fred file1 file2 file3 call :CheckExist dir1\fred rem Calculate destination name (none supplied) cd dir1 -copy ..\fred+..\file* >nul 2>&1 +copy ..\fred+..\file* >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist fred file1 file2 file3 call :CheckExist fred -copy ..\fr*+..\file1 >nul 2>&1 +copy ..\fr*+..\file1 >test1.txt 2>&1 if errorlevel 1 echo Incorrect errorlevel +call :CheckOutputExist fred file1 call :CheckExist fred cd .. diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index ff6f944cffb..95feb67602b 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1936,19 +1936,33 @@ file correctly deleted --- a batch file can alter itself bar ---------- Testing copy +Passed: Did not find file1 in COPY output Passed: Found expected dummy.file +Passed: Did not find file1 in COPY output Passed: Found expected dir1\file1 +Passed: Did not find file1 in COPY output Passed: Found expected dir1\file1 +Passed: Did not find file1 in COPY output Passed: Found expected dir1\file99 +Passed: Did not find file1 in COPY output Passed: Found expected file1 Passed: Did not find dir2 Passed: Did not find dir2\file1 +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected dir1\file1 Passed: Found expected dir1\file2 Passed: Found expected dir1\file3 +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected dir1\file1 Passed: Found expected dir1\file2 Passed: Found expected dir1\file3 +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected file1 Passed: Found expected file2 Passed: Found expected file3 @@ -1956,14 +1970,42 @@ Passed: Did not find dir2 Passed: Did not find dir2\file1 Passed: Did not find dir2\file2 Passed: Did not find dir2\file3 +Passed: Did not find file2 in COPY output Passed: Found expected testfile +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output Passed: Found expected testfile +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected testfile +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output +Passed: Found expected fred in COPY output Passed: Found expected testfile +Passed: Found expected fred in COPY output +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected testfile +Passed: Found expected fred in COPY output +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected dir1\fred +Passed: Found expected fred in COPY output +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected dir1\fred +Passed: Found expected fred in COPY output +Passed: Found expected file1 in COPY output +Passed: Found expected file2 in COPY output +Passed: Found expected file3 in COPY output Passed: Found expected fred +Passed: Found expected fred in COPY output +Passed: Found expected file1 in COPY output Passed: Found expected fred Passed: file size check on file1 [5]@or_broken(a)Skipping file size check on NT4 Passed: file size check on file2 [8]@or_broken(a)Skipping file size check on NT4 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/builtins.c | 32 ++++++++++++++++++++++++++++++-- programs/cmd/cmd.rc | 1 + programs/cmd/wcmd.h | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index b78ae9d293b..ced71de4b58 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -656,6 +656,7 @@ RETURN_CODE WCMD_copy(WCHAR * args) WCHAR copycmd[4]; DWORD len; BOOL dstisdevice = FALSE; + unsigned numcopied = 0; typedef struct _COPY_FILES { @@ -954,6 +955,8 @@ RETURN_CODE WCMD_copy(WCHAR * args) WCHAR *filenamepart; DWORD attributes; BOOL srcisdevice = FALSE; + BOOL havewildcards = FALSE; + BOOL displaynames = anyconcats; /* Display names if we are concatenating. */ /* If it was not explicit, we now know whether we are concatenating or not and hence whether to copy as binary or ascii */ @@ -965,6 +968,13 @@ RETURN_CODE WCMD_copy(WCHAR * args) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Full src name is '%s'\n", wine_dbgstr_w(srcpath)); + havewildcards = wcspbrk(srcpath, L"*?") ? TRUE : FALSE; + /* If we are not already displaying file names due to concatenation, then display them + if using wildards. */ + if (!displaynames) { + displaynames = havewildcards; + } + /* If parameter is a directory, ensure it ends in \* */ attributes = GetFileAttributesW(srcpath); if (ends_with_backslash( srcpath )) { @@ -972,17 +982,19 @@ RETURN_CODE WCMD_copy(WCHAR * args) /* We need to know where the filename part starts, so append * and recalculate the full resulting path */ lstrcatW(thiscopy->name, L"*"); + displaynames = TRUE; if (!WCMD_get_fullpath(thiscopy->name, ARRAY_SIZE(srcpath), srcpath, &filenamepart)) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Directory, so full name is now '%s'\n", wine_dbgstr_w(srcpath)); - } else if ((wcspbrk(srcpath, L"*?") == NULL) && + } else if (!havewildcards && (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { /* We need to know where the filename part starts, so append \* and recalculate the full resulting path */ lstrcatW(thiscopy->name, L"\\*"); + displaynames = TRUE; if (!WCMD_get_fullpath(thiscopy->name, ARRAY_SIZE(srcpath), srcpath, &filenamepart)) return errorlevel = ERROR_INVALID_FUNCTION; WINE_TRACE("Directory, so full name is now '%s'\n", wine_dbgstr_w(srcpath)); @@ -1064,6 +1076,10 @@ RETURN_CODE WCMD_copy(WCHAR * args) /* Do the copy as appropriate */ if (overwrite) { + if (displaynames) { + WCMD_output_asis(srcpath); + WCMD_output_asis(L"\r\n"); + } if (anyconcats && WCMD_IsSameFile(srcpath, outname)) { /* behavior is as Unix 'touch' (change last-written time only) */ HANDLE file = CreateFileW(srcpath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, @@ -1097,7 +1113,12 @@ RETURN_CODE WCMD_copy(WCHAR * args) return_code = ERROR_INVALID_FUNCTION; } else { WINE_TRACE("Copied successfully\n"); - if (anyconcats) writtenoneconcat = TRUE; + if (anyconcats) { + writtenoneconcat = TRUE; + numcopied = 1; + } else { + numcopied++; + } /* Append EOF if ascii destination and we are not going to add more onto the end Note: Testing shows windows has an optimization whereas if you have a binary @@ -1135,6 +1156,13 @@ RETURN_CODE WCMD_copy(WCHAR * args) } } + if (numcopied) { + WCHAR* string; + string = WCMD_format_string(WCMD_LoadMessage(WCMD_NUMCOPIED), numcopied); + WCMD_output_asis(string); + LocalFree(string); + } + /* Exit out of the routine, freeing any remaining allocated memory */ exitreturn: diff --git a/programs/cmd/cmd.rc b/programs/cmd/cmd.rc index 90091090e11..29d105fa7a2 100644 --- a/programs/cmd/cmd.rc +++ b/programs/cmd/cmd.rc @@ -406,4 +406,5 @@ Enter HELP <command> for further information on any of the above commands.\n" WCMD_BADTOKEN, "Syntax error: unexpected %1\n" WCMD_ENDOFLINE, "End of line" WCMD_ENDOFFILE, "End of file" + WCMD_NUMCOPIED, "%t%1!u! file(s) copied\n" } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 4c85d7ad8cb..2731743c27a 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -454,3 +454,4 @@ extern WCHAR version_string[]; #define WCMD_BADTOKEN 1047 #define WCMD_ENDOFLINE 1048 #define WCMD_ENDOFFILE 1049 +#define WCMD_NUMCOPIED 1050 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8200
participants (2)
-
Joe Souza -
Joe Souza (@JoeS209)