From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd.exp | 6 +++--- programs/cmd/wcmdmain.c | 26 +++++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 137404c5a52..ae4f674f1ca 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1822,9 +1822,9 @@ bar cp1 echo bar cp2 echo @todo_wine@cp3 bar b1 echo -@todo_wine@bar b2 echo -@todo_wine@bar b3 echo -@todo_wine@bar cb1 echo +bar b2 echo +bar b3 echo +bar cb1 echo --- mixing batch and builtins bar@space@ foo diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 4c30094cc76..0c74011a029 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -743,15 +743,10 @@ static void handleExpansion(WCHAR *cmd, BOOL atExecute) { wine_dbgstr_w(cmd), atExecute, wine_dbgstr_w(p)); i = *(p+1) - '0';
- /* Don't touch %% unless it's in Batch */ - if (!atExecute && *(p+1) == startchar) { - if (context) { - WCMD_strsubstW(p, p+1, NULL, 0); - p++; - } - else p+=2; - } else if (*(p+1) == startchar && startchar == L'!') { - p++; + /* handle consecutive % or ! */ + if ((!atExecute || startchar == L'!') && p[1] == startchar) { + if (context) WCMD_strsubstW(p, p + 1, NULL, 0); + if (!context || startchar == L'%') p++; /* Replace %~ modifications if in batch program */ } else if (*(p+1) == '~') { WCMD_HandleTildeModifiers(&p, atExecute); @@ -776,12 +771,19 @@ static void handleExpansion(WCHAR *cmd, BOOL atExecute) {
} else { int forvaridx = for_var_char_to_index(*(p+1)); - if (startchar == '%' && forvaridx != -1 && forloopcontext->variable[forvaridx]) { + if (startchar == L'%' && forvaridx != -1 && forloopcontext->variable[forvaridx]) { /* Replace the 2 characters, % and for variable character */ p = WCMD_strsubstW(p, p + 2, forloopcontext->variable[forvaridx], -1); - } else if (!atExecute || startchar == '!') { + } else if (!atExecute || startchar == L'!') { + BOOL first = p == cmd; p = WCMD_expand_envvar(p); - + /* FIXME: maybe this more likely calls for a specific handling of first arg? */ + if (context && startchar == L'!' && first) + { + WCHAR *last; + for (last = p; *last == startchar; last++) {} + p = WCMD_strsubstW(p, last, NULL, 0); + } /* In a FOR loop, see if this is the variable to replace */ } else { /* Ignore %'s on second pass of batch program */ p++;