From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 24 +++++++++++++----------- programs/cmd/tests/test_builtins.cmd | 1 - programs/cmd/tests/test_builtins.cmd.exp | 12 ++++++------ programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 2 +- 5 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index c4a387dc823..caa76547734 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -291,7 +291,8 @@ void WCMD_change_tty (void) { * */
-void WCMD_choice (const WCHAR * args) { +RETURN_CODE WCMD_choice (const WCHAR * args) +{ WCHAR answer[16]; WCHAR buffer[16]; WCHAR *ptr = NULL; @@ -306,11 +307,12 @@ void WCMD_choice (const WCHAR * args) { BOOL opt_s = FALSE;
have_console = GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &oldmode); - errorlevel = NO_ERROR; - my_command = xstrdupW(WCMD_skip_leading_spaces((WCHAR*)args));
- ptr = WCMD_skip_leading_spaces(my_command); + ptr = my_command; + /* syntax errors are reported with ERRORLEVEL=1, which doesn't allow to + * discriminate from a choosen option! + */ while (*ptr == '/') { switch (towupper(ptr[1])) { case 'C': @@ -322,7 +324,7 @@ void WCMD_choice (const WCHAR * args) { if (!*ptr || iswspace(*ptr)) { WINE_FIXME("bad parameter %s for /C\n", wine_dbgstr_w(ptr)); free(my_command); - return; + return errorlevel = ERROR_INVALID_FUNCTION; }
/* remember the allowed keys (overwrite previous /C option) */ @@ -359,7 +361,7 @@ void WCMD_choice (const WCHAR * args) { if (!opt_default || (*ptr != ',')) { WINE_FIXME("bad option %s for /T\n", opt_default ? wine_dbgstr_w(ptr) : ""); free(my_command); - return; + return errorlevel = ERROR_INVALID_FUNCTION; } ptr++;
@@ -378,7 +380,7 @@ void WCMD_choice (const WCHAR * args) { default: WINE_FIXME("bad parameter: %s\n", wine_dbgstr_w(ptr)); free(my_command); - return; + return errorlevel = ERROR_INVALID_FUNCTION; } }
@@ -422,11 +424,11 @@ void WCMD_choice (const WCHAR * args) {
/* FIXME: Add support for option /T */ answer[1] = 0; /* terminate single character string */ - if (!WCMD_ReadFile(GetStdHandle(STD_INPUT_HANDLE), answer, 1, &count)) + if (!WCMD_ReadFile(GetStdHandle(STD_INPUT_HANDLE), answer, 1, &count) || !count) { free(my_command); - errorlevel = NO_ERROR; - return; + /* FIXME: is this choice 1 or ERROR_INVALID_FUNCTION? */ + return errorlevel = 1; }
if (!opt_s) @@ -442,7 +444,7 @@ void WCMD_choice (const WCHAR * args) { errorlevel = (ptr - opt_c) + 1; TRACE("answer: %d\n", errorlevel); free(my_command); - return; + return errorlevel; } else { diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index d9757751bd1..b43848575fc 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -693,7 +693,6 @@ call :setError 666 & (echo foo | more &&echo SUCCESS !errorlevel!||echo FAILURE echo --- success/failure for PAUSE command call :setError 666 & (pause < NUL > NUL 2>&1 &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) rem TODO: pause is harder to test when fd 1 is a console handle as we don't control output - echo --- setlocal DisableDelayedExpansion echo ------------ Testing 'set' ------------ diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 86e9d22b0ce..a949693025c 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -608,11 +608,11 @@ FAILURE 1 SUCCESS 666 SUCCESS 666 --- success/failure for CHOICE command -@todo_wine@FAILURE 1 -@todo_wine@FAILURE 1 -@todo_wine@FAILURE 2 -@todo_wine@FAILURE 1 -@todo_wine@--- success/failure for MORE command +FAILURE 1 +FAILURE 1 +FAILURE 2 +FAILURE 1 +--- success/failure for MORE command SUCCESS 0 @todo_wine@SUCCESS 0 foo@space@ @@ -659,7 +659,7 @@ I'm here!@space@ I'm here!@space@ ------------ Testing 'choice' ------------ @todo_wine@Example message [A,B,C]?A@or_broken@choice unavailable -@todo_wine@1@or_broken@9009 +1@or_broken@9009 @todo_wine@Example message [A,B,C]?B@or_broken@choice unavailable @todo_wine@2@or_broken@9009 @todo_wine@[D,E,F]?F@or_broken@choice unavailable diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 36de66215bd..ae8f69166c2 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -165,7 +165,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *, BOOL); RETURN_CODE WCMD_batch(const WCHAR *, WCHAR *, const WCHAR *, HANDLE); RETURN_CODE WCMD_call(WCHAR *command); void WCMD_change_tty (void); -void WCMD_choice (const WCHAR *); +RETURN_CODE WCMD_choice(const WCHAR *); RETURN_CODE WCMD_clear_screen(void); RETURN_CODE WCMD_color(void); RETURN_CODE WCMD_copy(WCHAR *); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 72df7f2567c..4aa5a992218 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1928,7 +1928,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) WCMD_more(parms_start); break; case WCMD_CHOICE: - WCMD_choice(parms_start); + return_code = WCMD_choice(parms_start); break; case WCMD_MKLINK: WCMD_mklink(parms_start);