From 65c0ae1b10b813ae602a29d16773ed30213cfaee Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 10 Nov 2019 18:29:17 +0000 Subject: [PATCH] LOOP: Limit number of iterations when IF clauses present. The LOOP command is limited by the MXLOOPS setting in some cirumstances. Until now, if an IF clause was present, MXLOOPS was disregarded. However, this behavior does not match SPSS behavior. This commit makes LOOP honor MXLOOPS even when IF is present, for compatibility. With this commit, only the presence of an index clause makes LOOP disregard MXLOOPS. Thanks to Frans Houweling for reporting this bug. --- doc/flow-control.texi | 6 ++++-- src/language/control/loop.c | 5 +---- tests/language/control/loop.at | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/doc/flow-control.texi b/doc/flow-control.texi index 04fd6c3c8f..9f4d413457 100644 --- a/doc/flow-control.texi +++ b/doc/flow-control.texi @@ -182,8 +182,10 @@ code block is executed. The condition is evaluated at the end of the loop, not at the beginning, so that the body of a loop with only a condition on @cmd{END LOOP} will always execute at least once. -If neither the index clause nor either condition clause is -present, then the loop is executed @var{max_loops} (@pxref{SET}) times. +If the index clause is not +present, then the loop is executed at most @var{max_loops} (@pxref{SET}) times +(but possibly fewer, if a condition clause evaluates to false or if +@cmd{BREAK} executes). The default value of @var{max_loops} is 40. @cmd{BREAK} also terminates @cmd{LOOP} execution (@pxref{BREAK}). diff --git a/src/language/control/loop.c b/src/language/control/loop.c index 10d57105cc..bfd364ccd1 100644 --- a/src/language/control/loop.c +++ b/src/language/control/loop.c @@ -177,10 +177,7 @@ close_loop (void *loop_) /* If there's nothing else limiting the number of loops, use MXLOOPS as a limit. */ - if (loop->max_pass_count == -1 - && loop->index_var == NULL - && loop->loop_condition == NULL - && loop->end_loop_condition == NULL) + if (loop->max_pass_count == -1 && loop->index_var == NULL) loop->max_pass_count = settings_get_mxloops (); } diff --git a/tests/language/control/loop.at b/tests/language/control/loop.at index d506a4d37f..babab1c825 100644 --- a/tests/language/control/loop.at +++ b/tests/language/control/loop.at @@ -229,3 +229,34 @@ AT_CHECK([cat pspp.csv], [0], [dnl ]) AT_CLEANUP +AT_SETUP([LOOP with IF condition that ends due to MXLOOPS]) +AT_DATA([loop.sps], [dnl +LOOP_DATA +set mxloops=3. +compute #p = x. +loop. +print /x #p. +compute #p = #p + 1. +end loop if #p >= 6. +print/'--------'. +execute. +]) +AT_CHECK([pspp -o pspp.csv loop.sps]) +AT_CHECK([cat pspp.csv], [0], [dnl +1 1.00 @&t@ +1 2.00 @&t@ +1 3.00 @&t@ +-------- +2 2.00 @&t@ +2 3.00 @&t@ +2 4.00 @&t@ +-------- +3 3.00 @&t@ +3 4.00 @&t@ +3 5.00 @&t@ +-------- +4 4.00 @&t@ +4 5.00 @&t@ +-------- +]) +AT_CLEANUP -- 2.30.2