mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:08:30 +00:00
cmd: Implement semantic for chaining in ||, | and && operators.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
9c717825dc
commit
bf9a465e95
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,12 +3697,28 @@ RETURN_CODE node_execute(CMD_NODE *node)
|
|||
else return_code = NO_ERROR;
|
||||
break;
|
||||
case CMD_CONCAT:
|
||||
case CMD_ONSUCCESS:
|
||||
case CMD_ONFAILURE:
|
||||
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);
|
||||
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:
|
||||
{
|
||||
static SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa), .lpSecurityDescriptor = NULL, .bInheritHandle = TRUE};
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue