[v2] cmd/tests: chaining rules of pipe and else

Flávio J. Saraiva flaviojs2005 at gmail.com
Mon Nov 28 04:25:34 CST 2016


'|' has the highest bottom-up precedence

'else' has the lowest bottom-up precedence and matches the closest
unmatched 'if' in the same bracket depth

'if 1==1 if 2==2 if 3==3 a|b&&c||d&e else f|g&&h||i&j else k'
is interpreted as
'if 1==1 (if 2==2 (if 3==3 ((((a|b)&&c)||d)&e) else ((((f|g)&&h)||i)&j)) else k)'

The tests results of section 'chain pipe input' contain @or_broken@
alternatives for all broken results that showed up in 1000 runs.

FIXME 3 pipe tests are disabled for causing "unexpected end of output"

Signed-off-by: Flávio J. Saraiva <flaviojs2005 at gmail.com>
---

Notes:
    v2 - fix 2 missmatches in test results

 programs/cmd/tests/test_builtins.cmd     | 118 +++++++++++++++++++++++++++++--
 programs/cmd/tests/test_builtins.cmd.exp |  84 ++++++++++++++++++++++
 2 files changed, 197 insertions(+), 5 deletions(-)

diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index cf32481..052f77a 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -252,10 +252,15 @@ echo %ErrorLevel%
 set WINE_FOO=
 
 echo ------------ Testing chains ------------
-rem brackets precede '&&', '||' and '&'
-rem '&&' precedes '||' and '&'
-rem '||' precedes '&'
-rem 'a && b || c & d' is equivalent to '(((a && b) || c) & d)'
+rem The chain operators have the following bottom-up precedence:
+rem 'else' precedes nothing and matches the closest unmatched 'if' in the same bracket depth
+rem '&' precedes 'else'
+rem '||' precedes '&' and 'else'
+rem '&&' precedes '||', '&' and 'else'
+rem '|' precedes '&&', '||', '&' and 'else'
+rem
+rem Example: 'if 1==1 if 2==2 if 3==3 a | b && c || d & e else f else g' is interpreted as
+rem          'if 1==1 (if 2==2 (if 3==3 ((((a | b) && c) || d) & e) else f) else g)'
 goto :cfailend
 :cfail
 echo %1
@@ -301,6 +306,8 @@ call :cfail k1||call :cfail k2&&call :cfail k3
 echo ---
 call :cfail l1||call :cfail l2||call :cfail l3
 echo --- chain brackets
+rem Brackets are like regular commands, they support redirections
+rem and have the same precedence as regular commands.
 echo a1&(echo a2&echo a3)
 echo b1&(echo b2&&echo b3)
 echo c1&(echo c2||echo c3)
@@ -329,7 +336,108 @@ call :cfail p1||(call :cfail p2&call :cfail p3)
 call :cfail q1||(call :cfail q2&&call :cfail q3)
 echo ---
 call :cfail r1||(call :cfail r2||call :cfail r3)
-
+echo --- chain pipe
+rem Piped commands run at the same time, so the print order varies.
+rem Additionally, they don't run in the batch script context, as shown by
+rem 'call :existing_label|echo read the error message'.
+(echo a 1>&2|echo a 1>&2) 2>&1
+echo ---
+echo b1|echo b2
+echo c1&&echo c2|echo c3
+echo d1||echo d2|echo d3
+echo ---
+echo e1&echo e2|echo e3
+echo f1|echo f2&&echo f3
+echo g1|echo g2||echo g3
+echo ---
+echo h1|echo h2&echo h3
+echo i1|echo i2|echo i3
+echo --- chain pipe input
+rem The output data of the left side of a pipe can dissapear, probably
+rem because it finished too fast and closed the pipe before it could be read,
+rem which means we can get broken results for the tests of this section.
+echo @echo off> tmp.cmd
+echo set IN=X>> tmp.cmd
+echo set /p IN=%%1:>> tmp.cmd
+echo setlocal EnableDelayedExpansion>> tmp.cmd
+echo echo [!IN!,%%1]>> tmp.cmd
+echo endlocal>> tmp.cmd
+echo set IN=>> tmp.cmd
+echo a1|cmd /ctmp.cmd a2
+echo b1|cmd /ctmp.cmd b2|cmd /ctmp.cmd b3
+echo c1|cmd /ctmp.cmd c2|cmd /ctmp.cmd c3|cmd /ctmp.cmd c4
+echo d1|call tmp.cmd d2
+echo e1|call tmp.cmd e2|call tmp.cmd e3
+echo f1|call tmp.cmd f2|call tmp.cmd f3|call tmp.cmd f4
+rem FIXME these 3 tests cause "unexpected end of output"
+rem echo g1|tmp.cmd g2
+echo ---
+rem echo h1|tmp.cmd h2|tmp.cmd h3
+echo ---
+rem echo i1|tmp.cmd i2|tmp.cmd i3|tmp.cmd i4
+echo ---
+del tmp.cmd
+echo --- chain else
+rem Command arguments are gready and eat up the 'else' unless terminated by
+rem brackets, which means the 'else' can only be recognized when the
+rem 'if true' command chain ends with brackets.
+if 1==1 if 2==2 if 3==3 (echo a1) else (echo a2) else echo a3
+if 1==1 if 2==2 if 3==0 (echo b1) else (echo b2) else echo b3
+echo ---
+if 1==1 if 2==0 if 3==3 (echo c1) else (echo c2) else echo c3
+echo ---
+if 1==1 if 2==0 if 3==0 (echo d1) else (echo d2) else echo d3
+echo ---
+if 1==0 if 2==2 if 3==3 (echo e1) else (echo e2) else echo e3
+echo ---
+if 1==0 if 2==2 if 3==0 (echo f1) else (echo f2) else echo f3
+echo ---
+if 1==0 if 2==0 if 3==3 (echo g1) else (echo g2) else echo g3
+echo ---
+if 1==0 if 2==0 if 3==0 (echo h1) else (echo h2) else echo h3
+echo ---
+echo --- chain else (if true)
+if 1==1 echo a1 else echo a2
+if 1==1 echo b1|echo b2 else echo b3
+if 1==1 echo c1&&echo c2 else echo c3
+if 1==1 echo d1||echo d2 else echo d3
+echo ---
+if 1==1 echo e1&echo e2 else echo e3
+if 1==1 echo f1 else echo f2|echo f3
+if 1==1 echo g1 else echo g2&&echo g3
+if 1==1 echo h1 else echo h2||echo h3
+echo ---
+if 1==1 echo i1 else echo i2&echo i3
+if 1==1 echo j1|(echo j2) else echo j3
+echo ---
+if 1==1 echo k1&&(echo k2) else echo k3
+if 1==1 echo l1||(echo l2) else echo l3
+echo ---
+if 1==1 echo m1&(echo m2) else echo m3
+if 1==1 (echo n1) else echo n2|echo n3
+if 1==1 (echo o1) else echo o2&&echo o3
+if 1==1 (echo p1) else echo p2||echo p3
+if 1==1 (echo q1) else echo q2&echo q3
+echo --- chain else (if false)
+if 1==0 echo a1 else echo a2
+if 1==0 echo b1|echo b2 else echo b3
+if 1==0 echo c1&&echo c2 else echo c3
+if 1==0 echo d1||echo d2 else echo d3
+if 1==0 echo e1&echo e2 else echo e3
+if 1==0 echo f1 else echo f2|echo f3
+if 1==0 echo g1 else echo g2&&echo g3
+if 1==0 echo h1 else echo h2||echo h3
+if 1==0 echo i1 else echo i2&echo i3
+if 1==0 echo j1|(echo j2) else echo j3
+echo ---
+if 1==0 echo k1&&(echo k2) else echo k3
+if 1==0 echo l1||(echo l2) else echo l3
+if 1==0 echo m1&(echo m2) else echo m3
+if 1==0 (echo n1) else echo n2|echo n3
+if 1==0 (echo o1) else echo o2&&echo o3
+if 1==0 (echo p1) else echo p2||echo p3
+echo ---
+if 1==0 (echo q1) else echo q2&echo q3
 echo ------------ Testing 'set' ------------
 call :setError 0
 rem Remove any WINE_FOO* WINE_BA* environment variables from shell before proceeding
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 58f6fae..91167d6 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -363,6 +363,90 @@ q2
 r1
 r2
 r3
+--- chain pipe
+ at todo_wine@a at space@
+ at todo_wine@a at space@
+---
+b2
+c1
+c3
+d1
+ at todo_wine@---
+e1
+e3
+f2
+f3
+g2
+ at todo_wine@---
+h2
+h3
+i3
+--- chain pipe input
+a2:[a1,a2]
+b3:[b2:[b1,b2],b3]@or_broken at b3:[b2:,b3]
+c4:[c3:[c2:[c1,c2],c3],c4]@or_broken at c4:[c3:[c2:,c3],c4]@or_broken at c4:[c3:,c4]
+d2:[d1,d2]
+e3:[e2:[e1,e2],e3]@or_broken at e3:[e2:,e3]
+f4:[f3:[f2:[f1,f2],f3],f4]@or_broken at f4:[f3:[f2:,f3],f4]@or_broken at f4:[f3:,f4]
+ at todo_wine@g2:[g1,g2]
+---
+ at todo_wine@h3:[h2:[h1,h2],h3]@or_broken at h3:[h2:,h3]
+---
+ at todo_wine@i4:[i3:[i2:[i1,i2],i3],i4]@or_broken at i4:[i3:[i2:,i3],i4]@or_broken at i4:[i3:,i4]
+---
+--- chain else
+a1
+b2
+ at todo_wine@---
+ at todo_wine@c3
+ at todo_wine@---
+ at todo_wine@d3
+ at todo_wine@---
+ at todo_wine@---
+ at todo_wine@---
+ at todo_wine@---
+ at todo_wine@---
+--- chain else (if true)
+a1 else echo a2
+b2 else echo b3
+c1
+c2 else echo c3
+d1
+ at todo_wine@---
+e1
+e2 else echo e3
+f3
+g1 else echo g2
+g3
+h1 else echo h2
+ at todo_wine@---
+i1 else echo i2
+i3
+ at todo_wine@j2 at space@
+ at todo_wine@---
+k1
+k2
+l1
+ at todo_wine@---
+m1
+m2
+n1
+o1
+p1
+q1
+--- chain else (if false)
+ at todo_wine@j3
+---
+k3
+l3
+m3
+n3
+o2
+o3
+p2
+ at todo_wine@---
+q2
+q3
 ------------ Testing 'set' ------------
 1
 0
-- 
2.7.4




More information about the wine-patches mailing list