Module: wine Branch: stable Commit: 5d6c525dc4d4390f468ffafaf1e6cdeb29f410d6 URL: https://source.winehq.org/git/wine.git/?a=commit;h=5d6c525dc4d4390f468ffafaf...
Author: Jason Edmeades us@edmeades.me.uk Date: Mon Sep 10 23:30:19 2018 +0100
cmd: Handle "for" loop handling of tokens, where * does not follow a number.
With the 'for' loop /f syntax, if tokens are requested the the normal syntax is something like tokens=1,2* but there is valid syntax like 1,2,* (which effectively means the same). Make this other syntax work.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45722 Signed-off-by: Jason Edmeades us@edmeades.me.uk Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 1a7333bec627a31a43d380ecc63e5792e302373e) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
programs/cmd/builtins.c | 48 +++++++++++++++++++------------- programs/cmd/tests/test_builtins.cmd | 3 +- programs/cmd/tests/test_builtins.cmd.exp | 1 + 3 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 9cd86b3..48cfc13 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1836,8 +1836,8 @@ static int WCMD_for_nexttoken(int lasttoken, WCHAR *tokenstr, if (doall) *doall = FALSE; if (duplicates) *duplicates = FALSE;
- WINE_TRACE("Find next token after %d in %s was %d\n", lasttoken, - wine_dbgstr_w(tokenstr), nexttoken); + WINE_TRACE("Find next token after %d in %s\n", lasttoken, + wine_dbgstr_w(tokenstr));
/* Loop through the token string, parsing it. Valid syntax is: token=m or x-y with comma delimiter and optionally * to finish*/ @@ -1845,11 +1845,21 @@ static int WCMD_for_nexttoken(int lasttoken, WCHAR *tokenstr, int nextnumber1, nextnumber2 = -1; WCHAR *nextchar;
- /* It is valid syntax tokens=* which just means get whole line */ + /* Remember if the next character is a star, it indicates a need to + show all remaining tokens and should be the last character */ if (*pos == '*') { if (doall) *doall = TRUE; if (totalfound) (*totalfound)++; - nexttoken = 0; + /* If we have not found a next token to return, then indicate + time to process the star */ + if (nexttoken == -1) { + if (lasttoken == -1) { + /* Special case the syntax of tokens=* which just means get whole line */ + nexttoken = 0; + } else { + nexttoken = lasttoken; + } + } break; }
@@ -1882,8 +1892,9 @@ static int WCMD_for_nexttoken(int lasttoken, WCHAR *tokenstr, if (nextnumber2 >= nextnumber1 && totalfound) { *totalfound = *totalfound + 1 + (nextnumber2 - nextnumber1); } + pos = nextchar;
- } else { + } else if (pos != nextchar) { if (totalfound) (*totalfound)++;
/* See if the number found is one we have already seen */ @@ -1894,26 +1905,25 @@ static int WCMD_for_nexttoken(int lasttoken, WCHAR *tokenstr, ((nexttoken == -1) || (nextnumber1 < nexttoken))) { nexttoken = nextnumber1; } + pos = nextchar;
+ } else { + /* Step on to the next character, usually over comma */ + if (*pos) pos++; }
- /* Remember if it is followed by a star, and if it is indicate a need to - show all tokens, unless a duplicate has been found */ - if (*nextchar == '*') { - if (doall) *doall = TRUE; - if (totalfound) (*totalfound)++; - } - - /* Step on to the next character */ - pos = nextchar; - if (*pos) pos++; }
/* Return result */ - if (nexttoken == -1) nexttoken = lasttoken; - WINE_TRACE("Found next token after %d was %d\n", lasttoken, nexttoken); - if (totalfound) WINE_TRACE("Found total tokens in total %d\n", *totalfound); - if (doall && *doall) WINE_TRACE("Request for all tokens found\n"); + if (nexttoken == -1) { + WINE_TRACE("No next token found, previous was %d\n", lasttoken); + nexttoken = lasttoken; + } else if (nexttoken==lasttoken && doall && *doall) { + WINE_TRACE("Request for all remaining tokens now\n"); + } else { + WINE_TRACE("Found next token after %d was %d\n", lasttoken, nexttoken); + } + if (totalfound) WINE_TRACE("Found total tokens to be %d\n", *totalfound); if (duplicates && *duplicates) WINE_TRACE("Duplicate numbers found\n"); return nexttoken; } diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 08b9d9d..1874b0c 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1774,11 +1774,12 @@ for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k for /f "tokens=1,1,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o for /f "tokens=2,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o for /f "tokens=3,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o -rem Special case tokens=* +rem Special case tokens=* or tokens=n,* echo 3.14>testfile FOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%B FOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%B FOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%B +FOR /F "tokens=1,* delims=." %%A IN (testfile) DO @echo 4:%%A,%%B del testfile cd .. rd /s/q foobar diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index e105576..ebb3161 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1255,6 +1255,7 @@ h=%h i=b j=c k= l= m=%m n=%n o=%o@or_broken@h=%h i=b j=c k= l= m= n=%n o=%o h=%h i=b j=c k= l= m=%m n=%n o=%o@or_broken@h=%h i=b j=c k= l= m= n=%n o=%o 1:3.14,%B 2:3.14, +4:3,14 ------ parameter splitting :forFParameterSplittingFunc myparam1=myvalue1 myparam2=myparam2 mytest@space@@space@@space@ :forFParameterSplittingFunc myparam1=myvalue1 myparam2=myparam2 mytest@space@@space@@space@