From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 63 +++++++++++++----------- programs/cmd/tests/directory.c | 2 +- programs/cmd/tests/test_builtins.cmd | 2 +- programs/cmd/tests/test_builtins.cmd.exp | 6 +-- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 3 +- 6 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index a509f68382a..d3dede6b9f5 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1733,43 +1733,50 @@ int WCMD_for_nexttoken(int lasttoken, const WCHAR *tokenstr, return nexttoken; }
+static int find_in_array(const WCHAR array[][10], size_t sz, const WCHAR *what) +{ + int i; + + for (i = 0; i < sz; i++) + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + what, -1, array[i], -1) == CSTR_EQUAL) + return i; + return -1; +} + /************************************************************************** * WCMD_give_help * * Simple on-line help. Help text is stored in the resource file. */
-void WCMD_give_help (const WCHAR *args) +RETURN_CODE WCMD_give_help(WCHAR *args) { - size_t i; + WCHAR *help_on = WCMD_parameter(args, 0, NULL, FALSE, FALSE);
- args = WCMD_skip_leading_spaces((WCHAR*) args); - if (!*args) { - WCMD_output_asis (WCMD_LoadMessage(WCMD_ALLHELP)); - } - else { - /* Display help message for builtin commands */ - for (i=0; i<=WCMD_EXIT; i++) { - if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - args, -1, inbuilt[i], -1) == CSTR_EQUAL) { - WCMD_output_asis (WCMD_LoadMessage(i)); - return; - } - } - /* Launch the command with the /? option for external commands shipped with cmd.exe */ - for (i = 0; i <= ARRAY_SIZE(externals); i++) { - if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - args, -1, externals[i], -1) == CSTR_EQUAL) { - WCHAR cmd[128]; - lstrcpyW(cmd, args); - lstrcatW(cmd, L" /?"); - WCMD_run_program(cmd, FALSE); - return; - } + /* yes, return code / errorlevel look inverted, but native does it this way */ + if (!*help_on) + WCMD_output_asis(WCMD_LoadMessage(WCMD_ALLHELP)); + else + { + int i; + /* Display help message for builtin commands */ + if ((i = find_in_array(inbuilt, ARRAY_SIZE(inbuilt), help_on)) >= 0) + WCMD_output_asis(WCMD_LoadMessage(i)); + else if ((i = find_in_array(externals, ARRAY_SIZE(externals), help_on)) >= 0) + { + WCHAR cmd[128]; + lstrcpyW(cmd, help_on); + lstrcatW(cmd, L" /?"); + WCMD_run_program(cmd, FALSE); + } + else + { + WCMD_output(WCMD_LoadMessage(WCMD_NOCMDHELP), help_on); + return errorlevel = NO_ERROR; + } } - WCMD_output (WCMD_LoadMessage(WCMD_NOCMDHELP), args); - } - return; + return errorlevel = ERROR_INVALID_FUNCTION; }
/**************************************************************************** diff --git a/programs/cmd/tests/directory.c b/programs/cmd/tests/directory.c index 1a62ce120ca..11c65f62689 100644 --- a/programs/cmd/tests/directory.c +++ b/programs/cmd/tests/directory.c @@ -138,7 +138,7 @@ static void test_basic(void) ok(stderr_size > 0, "unexpected stderr buffer size %ld.\n", stderr_size);
/* errorlevel for usage is 0. But, cmd.exe's exit code is 1. */ - todo_wine run_dir("/?", 1); + run_dir("/?", 1); ok(stdout_size > 0, "unexpected stdout buffer size %ld.\n", stdout_size); ok(stderr_size == 0, "unexpected stderr buffer size %ld.\n", stderr_size); } diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 2b02888e4b2..2bda4ad68ff 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -664,7 +664,7 @@ goto :eof :afterSuccessFailureShift echo --- success/failure for HELP command call :setError 666 & help >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel! -call :setError 666 & help help >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel! +call :setError 666 & help dir >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel! call :setError 666 & help ACommandThatLikelyDoesntExist >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel! echo --- success/failure for PROMPT command call :setError 666 & prompt >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel! diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 8804bd48c4b..0d0bbb95e15 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -593,9 +593,9 @@ FAILURE 1 SUCCESS 666 SUCCESS 666 --- success/failure for HELP command -@todo_wine@FAILURE 1 -@todo_wine@FAILURE 1 -@todo_wine@SUCCESS 0 +FAILURE 1 +FAILURE 1 +SUCCESS 0 --- success/failure for PROMPT command @todo_wine@SUCCESS 0 --- diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 192680eac42..1eae5701b8b 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -177,7 +177,7 @@ RETURN_CODE WCMD_endlocal(void); void WCMD_enter_paged_mode(const WCHAR *); RETURN_CODE WCMD_exit(void); BOOL WCMD_get_fullpath(const WCHAR *, SIZE_T, WCHAR *, WCHAR **); -void WCMD_give_help (const WCHAR *args); +RETURN_CODE WCMD_give_help(WCHAR *args); RETURN_CODE WCMD_goto(void); RETURN_CODE WCMD_label(void); void WCMD_leave_paged_mode(void); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index a9704a80fb2..d83da05cb30 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1807,7 +1807,6 @@ static RETURN_CODE execute_single_command(const WCHAR *command) cmd_index = WCMD_HELP; memcpy(parms_start, whichcmd, count * sizeof(WCHAR)); parms_start[count] = '\0'; - }
return_code = RETURN_CODE_OLD_CHAINING; @@ -1846,7 +1845,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) return_code = WCMD_goto(); break; case WCMD_HELP: - WCMD_give_help (parms_start); + return_code = WCMD_give_help(parms_start); break; case WCMD_LABEL: return_code = WCMD_label();