From: Dmitry Sokolov <mr.dmitry.sokolov(a)gmail.com> Fixed the following code: echo 1. && echo ok || echo failed echo 2. || echo failed && echo --- & echo 3. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55489 --- programs/cmd/wcmdmain.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index d00c6e07566..f6123fb2173 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -58,6 +58,8 @@ static int max_width; static int numChars; #define MAX_WRITECONSOLE_SIZE 65535 +#define CMD_SUCCEEDED(res) ((res)==0) +#define CMD_FAILED(res) ((res)!=0) /* * Returns a buffer for reading from/writing to file @@ -2360,6 +2362,7 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket, BOOL retrycall) { int bdepth = -1; + CMD_LIST *prevCmd = NULL; if (thisCmd && oneBracket) bdepth = thisCmd->bracketDepth; @@ -2381,12 +2384,41 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket, about them and it will be handled in there) Also, skip over any batch labels (eg. :fred) */ if (thisCmd->command && thisCmd->command[0] != ':') { - WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command)); - WCMD_execute (thisCmd->command, thisCmd->redirects, &thisCmd, retrycall); + /* Process the command chaining */ + if ( (thisCmd->prevDelim == CMD_ONSUCCESS && CMD_FAILED(errorlevel)) || + (thisCmd->prevDelim == CMD_ONFAILURE && CMD_SUCCEEDED(errorlevel)) ) { + if (prevCmd && prevCmd->bracketDepth < thisCmd->bracketDepth) { + /* Skipping the chain of commands in brackets */ + int bd = thisCmd->bracketDepth; + do { + WINE_TRACE("Skipping command '%s'\n", wine_dbgstr_w(thisCmd->command)); + prevCmd = thisCmd; + thisCmd = thisCmd->nextcommand; + } while (thisCmd && bd <= thisCmd->bracketDepth); + continue; + } else if (thisCmd->prevDelim == CMD_ONFAILURE && CMD_SUCCEEDED(errorlevel)) { + /* Skipping all chaining commands after '||', i.e. '|| cmd2 && cmd3 || cmd4'*/ + do { + WINE_TRACE("Skipping command '%s'\n", wine_dbgstr_w(thisCmd->command)); + prevCmd = thisCmd; + thisCmd = thisCmd->nextcommand; + } while (thisCmd && (thisCmd->prevDelim == CMD_ONSUCCESS || thisCmd->prevDelim == CMD_ONFAILURE)); + continue; + } else { + /* Skipping the next command */ + WINE_TRACE("Skipping command '%s'\n", wine_dbgstr_w(thisCmd->command)); + } + } else { + WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command)); + WCMD_execute (thisCmd->command, thisCmd->redirects, &thisCmd, retrycall); + } } /* Step on unless the command itself already stepped on */ - if (thisCmd == origCmd) thisCmd = thisCmd->nextcommand; + if (thisCmd == origCmd) { + prevCmd = thisCmd; + thisCmd = thisCmd->nextcommand; + } } return NULL; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3668