[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pspp-cvs] pspp doc/flow-control.texi src/language/control...
From: |
Ben Pfaff |
Subject: |
[Pspp-cvs] pspp doc/flow-control.texi src/language/control... |
Date: |
Wed, 20 Dec 2006 16:09:45 +0000 |
CVSROOT: /cvsroot/pspp
Module name: pspp
Changes by: Ben Pfaff <blp> 06/12/20 16:09:45
Modified files:
doc : flow-control.texi
src/language/control: ChangeLog loop.c
tests : ChangeLog
tests/command : loop.sh
Log message:
Fix bugs in LOOP.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/doc/flow-control.texi?cvsroot=pspp&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/ChangeLog?cvsroot=pspp&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/loop.c?cvsroot=pspp&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pspp/tests/ChangeLog?cvsroot=pspp&r1=1.73&r2=1.74
http://cvs.savannah.gnu.org/viewcvs/pspp/tests/command/loop.sh?cvsroot=pspp&r1=1.16&r2=1.17
Patches:
Index: doc/flow-control.texi
===================================================================
RCS file: /cvsroot/pspp/pspp/doc/flow-control.texi,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- doc/flow-control.texi 8 May 2006 01:14:16 -0000 1.4
+++ doc/flow-control.texi 20 Dec 2006 16:09:44 -0000 1.5
@@ -145,16 +145,19 @@
condition is false or missing before the loop contents are executed the
first time, the loop contents are not executed at all.
-If index and condition clauses are both present on @cmd{LOOP}, the index
-clause is always evaluated first.
+If index and condition clauses are both present on @cmd{LOOP}, the
+index variable is always set before the condition is evaluated. Thus,
+a condition that makes use of the index variable will always see the
+index value to be used in the next execution of the body.
Specify a boolean expression for the condition on @cmd{END LOOP} to cause
-the loop to terminate if the condition is not true after the enclosed
+the loop to terminate if the condition is true after the enclosed
code block is executed. The condition is evaluated at the end of the
-loop, not at the beginning.
+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 the index clause and both condition clauses are not present, then the
-loop is executed MXLOOPS (@pxref{SET}) times.
+If neither the index clause nor either condition clause is
+present, then the loop is executed MXLOOPS (@pxref{SET}) times.
@cmd{BREAK} also terminates @cmd{LOOP} execution (@pxref{BREAK}).
Index: src/language/control/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/control/ChangeLog,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- src/language/control/ChangeLog 10 Dec 2006 04:12:40 -0000 1.7
+++ src/language/control/ChangeLog 20 Dec 2006 16:09:44 -0000 1.8
@@ -1,3 +1,20 @@
+Tue Dec 19 08:12:46 2006 Ben Pfaff <address@hidden>
+
+ Fix LOOP. Thanks to Daniel Williams
+ <address@hidden> for reporting one of the bugs
+ fixed here.
+
+ * loop.c (cmd_loop): Keep track of whether we created the index
+ variable and delete it if parsing fails, instead of creating it
+ after parsing the IF clause. This allows the index variable to be
+ used in the IF clause. This incidentally fixes a segfault when no
+ index variable was used. Also, return CMD_CASCADING_FAILURE if we
+ fail.
+ (parse_if_clause): Don't allow more than one IF clause.
+ (parse_index_clause): Don't allow more than one index clause.
+ Create the index variable if it doesn't exist.
+ (end_loop_trns_proc): Invert the sense of END LOOP's IF clause.
+
Sat Dec 9 20:12:34 2006 Ben Pfaff <address@hidden>
* repeat.c (parse_lines): Issue an error when attempting to nest
Index: src/language/control/loop.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/control/loop.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- src/language/control/loop.c 15 Dec 2006 00:16:02 -0000 1.13
+++ src/language/control/loop.c 20 Dec 2006 16:09:44 -0000 1.14
@@ -86,8 +86,10 @@
static trns_free_func loop_trns_free;
static struct loop_trns *create_loop_trns (struct dataset *);
-static bool parse_if_clause (struct lexer *, struct loop_trns *, struct
expression **);
-static bool parse_index_clause (struct lexer *, struct loop_trns *, char
index_var_name[]);
+static bool parse_if_clause (struct lexer *,
+ struct loop_trns *, struct expression **);
+static bool parse_index_clause (struct dataset *, struct lexer *,
+ struct loop_trns *, bool *created_index_var);
static void close_loop (void *);
/* LOOP. */
@@ -97,7 +99,7 @@
cmd_loop (struct lexer *lexer, struct dataset *ds)
{
struct loop_trns *loop;
- char index_var_name[LONG_NAME_LEN + 1];
+ bool created_index_var = false;
bool ok = true;
loop = create_loop_trns (ds);
@@ -106,21 +108,21 @@
if (lex_match_id (lexer, "IF"))
ok = parse_if_clause (lexer, loop, &loop->loop_condition);
else
- ok = parse_index_clause (lexer, loop, index_var_name);
+ ok = parse_index_clause (ds, lexer, loop, &created_index_var);
}
- /* Find index variable and create if necessary. */
- if (ok && index_var_name[0] != '\0')
+ /* Clean up if necessary. */
+ if (!ok)
+ {
+ loop->max_pass_count = 0;
+ if (loop->index_var != NULL && created_index_var)
{
- loop->index_var = dict_lookup_var (dataset_dict (ds), index_var_name);
- if (loop->index_var == NULL)
- loop->index_var = dict_create_var (dataset_dict (ds),
- index_var_name, 0);
+ dict_delete_var (dataset_dict (ds), loop->index_var);
+ loop->index_var = NULL;
+ }
}
- if (!ok)
- loop->max_pass_count = 0;
- return ok ? CMD_SUCCESS : CMD_FAILURE;
+ return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
}
/* Parses END LOOP. */
@@ -189,22 +191,45 @@
parse_if_clause (struct lexer *lexer,
struct loop_trns *loop, struct expression **condition)
{
+ if (*condition != NULL)
+ {
+ lex_sbc_only_once ("IF");
+ return false;
+ }
+
*condition = expr_parse_pool (lexer, loop->pool, loop->ds, EXPR_BOOLEAN);
return *condition != NULL;
}
/* Parses an indexing clause into LOOP.
- Stores the index variable's name in INDEX_VAR_NAME[].
+ Stores true in *CREATED_INDEX_VAR if the index clause created
+ a new variable, false otherwise.
Returns true if successful, false on failure. */
static bool
-parse_index_clause (struct lexer *lexer, struct loop_trns *loop, char
index_var_name[])
+parse_index_clause (struct dataset *ds, struct lexer *lexer,
+ struct loop_trns *loop, bool *created_index_var)
{
+ if (loop->index_var != NULL)
+ {
+ msg (SE, _("Only one index clause may be specified."));
+ return false;
+ }
+
if (lex_token (lexer) != T_ID)
{
lex_error (lexer, NULL);
return false;
}
- strcpy (index_var_name, lex_tokid (lexer));
+
+ loop->index_var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
+ if (loop->index_var != NULL)
+ *created_index_var = false;
+ else
+ {
+ loop->index_var = dict_create_var_assert (dataset_dict (ds),
+ lex_tokid (lexer), 0);
+ *created_index_var = true;
+ }
lex_get (lexer);
if (!lex_force_match (lexer, '='))
@@ -336,7 +361,7 @@
struct loop_trns *loop = loop_;
if (loop->end_loop_condition != NULL
- && expr_evaluate_num (loop->end_loop_condition, c, case_num) != 1.0)
+ && expr_evaluate_num (loop->end_loop_condition, c, case_num) != 0.0)
goto break_out;
/* MXLOOPS limiter. */
Index: tests/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/ChangeLog,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -b -r1.73 -r1.74
--- tests/ChangeLog 16 Dec 2006 22:01:19 -0000 1.73
+++ tests/ChangeLog 20 Dec 2006 16:09:45 -0000 1.74
@@ -1,3 +1,7 @@
+Tue Dec 19 08:17:28 2006 Ben Pfaff <address@hidden>
+
+ * command/loop.sh: Test all the possible combinations of clauses.
+
Sat Dec 16 14:00:48 2006 Ben Pfaff <address@hidden>
* command/rank.sh: Fix test to allow string grouping variables.
Index: tests/command/loop.sh
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/command/loop.sh,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- tests/command/loop.sh 7 Nov 2006 13:00:00 -0000 1.16
+++ tests/command/loop.sh 20 Dec 2006 16:09:45 -0000 1.17
@@ -57,17 +57,71 @@
activity="create prog"
cat > $TEMPDIR/loop.stat <<EOF
-data list /X 1 Y 2 ZOOLOGICAL 3.
+data list notable /x 1 y 2 z 3.
begin data.
-125
-256
-397
-401
+121
+252
+393
+404
end data.
-loop iterative_Variable=y to zoological by abs(zoological-y)/(zoological-y).
-print /x iterative_Variable.
-break. /* Generates warning.
+
+echo 'Loop with index'.
+loop #i=x to y by z.
+print /#i.
+end loop.
+print/'--------'.
+execute.
+
+echo 'Loop with IF condition'.
+compute #j=x.
+loop if #j <= y.
+print /#j.
+compute #j = #j + z.
+end loop.
+print/'--------'.
+execute.
+
+echo 'Loop with END IF condition'.
+compute #k=x.
+loop.
+print /#k.
+compute #k = #k + z.
+end loop if #k > y.
+print/'--------'.
+execute.
+
+echo 'Loop with index and IF condition based on index'.
+loop #m=x to y by z if #m < 4.
+print /#m.
+end loop.
+print/'--------'.
+execute.
+
+echo 'Loop with index and END IF condition based on index'.
+loop #n=x to y by z.
+print /#n.
+end loop if #n >= 4.
+print/'--------'.
+execute.
+
+echo 'Loop with index and IF and END IF condition based on index'.
+loop #o=x to y by z if mod(#o,2) = 0.
+print /#o.
+end loop if #o >= 4.
+print/'--------'.
+execute.
+
+echo 'Loop with no conditions'.
+set mxloops = 2.
+compute #p = x.
+loop.
+print /#p.
+compute #p = #p + z.
+do if #p >= y.
+break.
+end if.
end loop.
+print/'--------'.
execute.
EOF
if [ $? -ne 0 ] ; then no_result ; fi
@@ -85,18 +139,81 @@
activity="compare results"
perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
diff -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST. Reading 1 record from INLINE.
-+----------+------+-------+------+
-| Variable |Record|Columns|Format|
-#==========#======#=======#======#
-|X | 1| 1- 1|F1.0 |
-|Y | 1| 2- 2|F1.0 |
-|ZOOLOGICAL| 1| 3- 3|F1.0 |
-+----------+------+-------+------+
-1 2.00
-2 5.00
-3 9.00
-4 .00
+Loop with index
+ 1.00
+ 2.00
+--------
+ 2.00
+ 4.00
+--------
+ 3.00
+ 6.00
+ 9.00
+--------
+--------
+Loop with IF condition
+ 1.00
+ 2.00
+--------
+ 2.00
+ 4.00
+--------
+ 3.00
+ 6.00
+ 9.00
+--------
+--------
+Loop with END IF condition
+ 1.00
+ 2.00
+--------
+ 2.00
+ 4.00
+--------
+ 3.00
+ 6.00
+ 9.00
+--------
+ 4.00
+--------
+Loop with index and IF condition based on index
+ 1.00
+ 2.00
+--------
+ 2.00
+--------
+ 3.00
+--------
+--------
+Loop with index and END IF condition based on index
+ 1.00
+ 2.00
+--------
+ 2.00
+ 4.00
+--------
+ 3.00
+ 6.00
+--------
+--------
+Loop with index and IF and END IF condition based on index
+--------
+ 2.00
+ 4.00
+--------
+--------
+--------
+Loop with no conditions
+ 1.00
+--------
+ 2.00
+ 4.00
+--------
+ 3.00
+ 6.00
+--------
+ 4.00
+--------
EOF
if [ $? -ne 0 ] ; then fail ; fi
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pspp-cvs] pspp doc/flow-control.texi src/language/control...,
Ben Pfaff <=