From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd.exp | 106 +++++++++++------------ programs/cmd/wcmd.h | 2 + programs/cmd/wcmdmain.c | 42 ++++++++- 3 files changed, 93 insertions(+), 57 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 1799bc795fc..c2dba03b740 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -262,7 +262,7 @@ a2 b1 b2 c1 -@todo_wine@--- +--- d1 d2 d3 @@ -271,7 +271,7 @@ e2 e3 f1 f2 -@todo_wine@--- +--- g1 g2 g3 @@ -280,19 +280,19 @@ h2 h3 i1 i2 -@todo_wine@--- +--- j1 -@todo_wine@j3 -@todo_wine@--- +j3 +--- k1 -@todo_wine@--- +--- l1 -@todo_wine@--- +--- --- chain failure a1 a2 b1 -@todo_wine@--- +--- c1 c2 d1 @@ -300,24 +300,24 @@ d2 d3 e1 e2 -@todo_wine@--- +--- f1 f2 f3 g1 -@todo_wine@g3 -@todo_wine@--- +g3 +--- h1 -@todo_wine@--- +--- i1 -@todo_wine@i3 -@todo_wine@--- +i3 +--- j1 j2 j3 k1 k2 -@todo_wine@--- +--- l1 l2 l3 @@ -330,7 +330,7 @@ b2 b3 c1 c2 -@todo_wine@--- +--- d1 d2 d3 @@ -339,34 +339,34 @@ e2 e3 f1 f2 -@todo_wine@--- +--- g1 -@todo_wine@--- +--- h1 -@todo_wine@--- +--- i1 -@todo_wine@--- +--- j1 j2 j3 k1 k2 -@todo_wine@--- +--- l1 l2 l3 m1 -@todo_wine@--- +--- n1 -@todo_wine@--- +--- o1 -@todo_wine@--- +--- p1 p2 p3 q1 q2 -@todo_wine@--- +--- r1 r2 r3 @@ -378,13 +378,13 @@ b2 c1 c3 d1 -@todo_wine@--- +--- e1 e3 f2 f3 g2 -@todo_wine@--- +--- h2 h3 i3 @@ -398,44 +398,44 @@ f4:[f3:[f2:[f1,f2],f3],f4]@or_broken@f4:[f3:[f2:,f3],f4]@or_broken@f4:[f3:,f4] --- chain else a1 b2 -@todo_wine@--- +--- c3 -@todo_wine@--- +--- d3 -@todo_wine@--- -@todo_wine@--- -@todo_wine@--- -@todo_wine@--- -@todo_wine@--- +--- +--- +--- +--- +--- --- chain else (if true) a1 else echo a2 b2 else echo b3 c1 c2 else echo c3 d1 -@todo_wine@--- +--- e1 e2 else echo e3 f3 g1 else echo g2 g3 h1 else echo h2 -@todo_wine@--- +--- i1 else echo i2 i3 @todo_wine@j2@space@ -@todo_wine@--- +--- k1 k2 l1 -@todo_wine@--- +--- m1 m2 n1 o1 p1 q1 -@todo_wine@--- +--- --- chain else (if false) j3 --- @@ -446,25 +446,25 @@ n3 o2 o3 p2 -@todo_wine@--- +--- q2 q3 ------------- Testing internal commands return codes --- call and IF/FOR blocks SUCCESS 0 -@todo_wine@FAILURE 33 -@todo_wine@foo@space@ -@todo_wine@SUCCESS 666 -@todo_wine@FAILURE 1 +FAILURE 33 +foo@space@ SUCCESS 666 -@todo_wine@SUCCESS 666 -@todo_wine@FAILURE 33 -@todo_wine@FAILURE 34 +FAILURE 1 SUCCESS 666 -@todo_wine@SUCCESS 666 -@todo_wine@SUCCESS 0 -@todo_wine@FAILURE 33 -@todo_wine@--- +SUCCESS 666 +FAILURE 33 +FAILURE 34 +SUCCESS 666 +SUCCESS 666 +SUCCESS 0 +FAILURE 33 +--- ------------ Testing 'set' ------------ 1 0 @@ -654,13 +654,13 @@ bar2@space@ foo2 foobar deleted --- on success conditional and -@todo_wine@foo3 not created +foo3 not created bar4@space@ foo4 --- on failure conditional or foo5 foo6@space@ -@todo_wine@------------ Testing cd ------------ +------------ Testing cd ------------ singleFile Current dir: @drive@@path@foobar@or_broken@Current dir:@space@ @drive@@path@foobar diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 8dfc89534d6..9f8bdd46044 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -156,6 +156,8 @@ typedef int RETURN_CODE; #define RETURN_CODE_SYNTAX_ERROR 255 #define RETURN_CODE_CANT_LAUNCH 9009 #define RETURN_CODE_ABORTED (-999999) +/* temporary to detect builtin commands not migrated to handle return code */ +#define RETURN_CODE_OLD_CHAINING (-999998)
void WCMD_assoc (const WCHAR *, BOOL); void WCMD_batch(WCHAR *, WCHAR *, WCHAR *, HANDLE); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 860ca872ffc..17702f4f277 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1734,7 +1734,7 @@ static BOOL set_std_redirections(CMD_REDIRECTION *redir) */ static RETURN_CODE execute_single_command(const WCHAR *command) { - RETURN_CODE return_code = NO_ERROR; + RETURN_CODE return_code; WCHAR *cmd, *parms_start; int status, cmd_index, count; WCHAR *whichcmd; @@ -1791,6 +1791,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) WINE_TRACE("Got directory %s as %s\n", wine_dbgstr_w(envvar), wine_dbgstr_w(cmd)); status = SetCurrentDirectoryW(cmd); if (!status) WCMD_print_error (); + return_code = ERROR_INVALID_FUNCTION; goto cleanup; }
@@ -1805,6 +1806,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command)
}
+ return_code = RETURN_CODE_OLD_CHAINING; switch (cmd_index) {
case WCMD_CALL: @@ -1936,6 +1938,7 @@ static RETURN_CODE execute_single_command(const WCHAR *command) default: prev_echo_mode = echo_mode; WCMD_run_program (whichcmd, FALSE); + return_code = errorlevel; echo_mode = prev_echo_mode; }
@@ -3659,6 +3662,16 @@ static RETURN_CODE for_control_execute(CMD_FOR_CONTROL *for_ctrl, CMD_NODE *node return return_code; }
+static RETURN_CODE temp_fixup_return_code(CMD_NODE *node, RETURN_CODE return_code, RETURN_CODE fallback_return_code) +{ + if (return_code == RETURN_CODE_OLD_CHAINING) + { + FIXME("Not migrated (%ls) used in chaining\n", node->op == CMD_SINGLE ? node->command->command : L"Too complex"); + return_code = fallback_return_code; + } + return return_code; +} + RETURN_CODE node_execute(CMD_NODE *node) { HANDLE old_stdhandles[3] = {GetStdHandle (STD_INPUT_HANDLE), @@ -3674,7 +3687,7 @@ RETURN_CODE node_execute(CMD_NODE *node) { WCMD_print_error(); /* FIXME potentially leaking here (if first redir created ok, and second failed */ - return ERROR_INVALID_FUNCTION; + return errorlevel = ERROR_INVALID_FUNCTION; } switch (node->op) { @@ -3684,11 +3697,27 @@ RETURN_CODE node_execute(CMD_NODE *node) else return_code = NO_ERROR; break; case CMD_CONCAT: + return_code = node_execute(node->left); + if (return_code != RETURN_CODE_ABORTED) + return_code = node_execute(node->right); + break; case CMD_ONSUCCESS: + return_code = node_execute(node->left); + return_code = temp_fixup_return_code(node->left, return_code, NO_ERROR); + if (return_code == NO_ERROR) + { + return_code = node_execute(node->right); + temp_fixup_return_code(node->right, return_code, 0 /* not used */); + } + break; case CMD_ONFAILURE: return_code = node_execute(node->left); - if (return_code != RETURN_CODE_ABORTED) + return_code = temp_fixup_return_code(node->left, return_code, ERROR_INVALID_FUNCTION); + if (return_code != NO_ERROR) + { return_code = node_execute(node->right); + temp_fixup_return_code(node->right, return_code, 0 /* not used */); + } break; case CMD_PIPE: { @@ -3714,11 +3743,13 @@ RETURN_CODE node_execute(CMD_NODE *node) output = redirection_create_file(REDIR_WRITE_TO, 1, filename); if (set_std_redirections(output)) { - return_code = node_execute(node->left); + RETURN_CODE return_code_left = node_execute(node->left); + return_code = NO_ERROR;
CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)); SetStdHandle(STD_OUTPUT_HANDLE, old_stdhandles[1]);
+ return_code = temp_fixup_return_code(node->left, return_code, NO_ERROR); if (return_code == NO_ERROR) { HANDLE h = CreateFileW(filename, GENERIC_READ, @@ -3728,10 +3759,13 @@ RETURN_CODE node_execute(CMD_NODE *node) { SetStdHandle(STD_INPUT_HANDLE, h); return_code = node_execute(node->right); + temp_fixup_return_code(node->right, return_code, 0 /* not used */); } else return_code = ERROR_INVALID_FUNCTION; } DeleteFileW(filename); + if (return_code_left != NO_ERROR || return_code != NO_ERROR) + errorlevel = ERROR_INVALID_FUNCTION; } else return_code = ERROR_INVALID_FUNCTION; redirection_dispose_list(output);