Bug #21111. Reviewed by John Darrington.
authorBen Pfaff <blp@gnu.org>
Sun, 23 Sep 2007 16:47:27 +0000 (16:47 +0000)
committerBen Pfaff <blp@gnu.org>
Sun, 23 Sep 2007 16:47:27 +0000 (16:47 +0000)
* command/input-program.sh: New test.

* command/do-if.sh: New tests.

* data-list.c (data_list_trns_proc): Properly set retval when END
subcommand is in use.

* do-if.c: Fix ELSE and ELSE IF clauses.
(add_clause): Drop TARGET_INDEX argument and figure out the target
of the jump on our own.  The caller couldn't compensate for the
inserted BREAK transformation.  Updated all callers.

doc/data-io.texi
src/language/control/ChangeLog
src/language/control/do-if.c
src/language/data-io/ChangeLog
src/language/data-io/data-list.c
tests/ChangeLog
tests/automake.mk
tests/command/do-if.sh [new file with mode: 0755]
tests/command/input-program.sh [new file with mode: 0755]

index 83d1949cd7de28568b2f3dcdd37800193e34b216..cb11c7cfc1008306f87a408b93201ba1f7f1d8e1 100644 (file)
@@ -541,6 +541,8 @@ structure.
 
 All this is very confusing.  A few examples should help to clarify.
 
+@c If you change this example, change the regression test1 in
+@c tests/command/input-program.sh to match.
 @example
 INPUT PROGRAM.
         DATA LIST NOTABLE FILE='a.data'/X 1-10.
@@ -553,6 +555,8 @@ The example above reads variable X from file @file{a.data} and variable
 Y from file @file{b.data}.  If one file is shorter than the other then
 the extra data in the longer file is ignored.
 
+@c If you change this example, change the regression test2 in
+@c tests/command/input-program.sh to match.
 @example
 INPUT PROGRAM.
         NUMERIC #A #B.
@@ -576,6 +580,8 @@ The above example reads variable X from @file{a.data} and variable Y from
 field is set to the system-missing value alongside the present value for
 the remaining length of the longer file.
 
+@c If you change this example, change the regression test3 in
+@c tests/command/input-program.sh to match.
 @example
 INPUT PROGRAM.
         NUMERIC #A #B.
@@ -600,6 +606,8 @@ LIST.
 The above example reads data from file @file{a.data}, then from
 @file{b.data}, and concatenates them into a single active file.
 
+@c If you change this example, change the regression test4 in
+@c tests/command/input-program.sh to match.
 @example
 INPUT PROGRAM.
         NUMERIC #EOF.
@@ -627,6 +635,8 @@ LIST.
 The above example does the same thing as the previous example, in a
 different way.
 
+@c If you change this example, make similar changes to the regression
+@c test5 in tests/command/input-program.sh.
 @example
 INPUT PROGRAM.
         LOOP #I=1 TO 50.
index f26aba150f6fa19f17b896b1b67dc7703c98fdb0..ecdcc65877d5acd5c0c502440eb1c4938160efef 100644 (file)
@@ -1,3 +1,12 @@
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+
+       * do-if.c: Fix ELSE and ELSE IF clauses.
+       (add_clause): Drop TARGET_INDEX argument and figure out the target
+       of the jump on our own.  The caller couldn't compensate for the
+       inserted BREAK transformation.  Updated all callers.
+
 Fri Feb  2 22:41:43 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * repeat.c (parse_numbers): Fixed bug parseing ranges vs. lists.
index cb4207846c3bdc2b39ce4e6503fead8233fd1810..2e1e0abf5f4deb412db249189cb489b298f72e0d 100644 (file)
@@ -82,8 +82,7 @@ struct do_if_trns
 static const struct ctl_class do_if_class;
 
 static int parse_clause (struct lexer *, struct do_if_trns *, struct dataset *ds);
-static void add_clause (struct do_if_trns *,
-                        struct expression *condition, int target_index);
+static void add_clause (struct do_if_trns *, struct expression *condition);
 static void add_else (struct do_if_trns *);
 
 static bool has_else (struct do_if_trns *);
@@ -165,7 +164,7 @@ static void
 add_else (struct do_if_trns *do_if)
 {
   assert (!has_else (do_if));
-  add_clause (do_if, NULL, next_transformation (do_if->ds));
+  add_clause (do_if, NULL);
 }
 
 /* Returns true if DO_IF does not yet have an ELSE clause.
@@ -203,16 +202,16 @@ parse_clause (struct lexer *lexer, struct do_if_trns *do_if, struct dataset *ds)
   if (condition == NULL)
     return CMD_CASCADING_FAILURE;
 
-  add_clause (do_if, condition, next_transformation (ds));
+  add_clause (do_if, condition);
 
   return lex_end_of_command (lexer);
 }
 
 /* Adds a clause to DO_IF that tests for the given CONDITION and,
-   if true, jumps to TARGET_INDEX. */
+   if true, jumps to the set of transformations produced by
+   following commands. */
 static void
-add_clause (struct do_if_trns *do_if,
-            struct expression *condition, int target_index)
+add_clause (struct do_if_trns *do_if, struct expression *condition)
 {
   struct clause *clause;
 
@@ -223,7 +222,7 @@ add_clause (struct do_if_trns *do_if,
                               do_if->clause_cnt + 1, sizeof *do_if->clauses);
   clause = &do_if->clauses[do_if->clause_cnt++];
   clause->condition = condition;
-  clause->target_index = target_index;
+  clause->target_index = next_transformation (do_if->ds);
 }
 
 /* Finalizes DO IF by clearing the control stack, thus ensuring
index 572aacd5a7700838d5b8a1735e58c3be4ff90185..ec8873acbe7789d5fc19bdb7800e20cfe13c24c4 100644 (file)
@@ -1,3 +1,10 @@
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+
+       * data-list.c (data_list_trns_proc): Properly set retval when END
+       subcommand is in use.
+
 2007-09-12  Ben Pfaff  <blp@gnu.org>
 
        * get.c (get_translate_case): Change input case parameter from
index 9f77ed8d9a135b7751ba408662779e70d1b7b70a..4e2f083bee9077f2f69c990624fc6694b8ed0749 100644 (file)
@@ -807,10 +807,10 @@ data_list_trns_proc (void *dls_, struct ccase *c, casenumber case_num UNUSED)
   if (dls->end != NULL)
     {
       double *end = &case_data_rw (c, dls->end)->f;
-      if (retval == TRNS_DROP_CASE)
+      if (retval == TRNS_END_FILE)
         {
           *end = 1.0;
-          retval = TRNS_END_FILE;
+          retval = TRNS_CONTINUE;
         }
       else
         *end = 0.0;
index e91645ce4c14434d050932a4eb6023362d9603c4..3a912d56157090be5d73a224e6b043edb01848d7 100644 (file)
@@ -1,3 +1,11 @@
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+       
+       * command/input-program.sh: New test.
+
+       * command/do-if.sh: New tests.
+
 2007-09-22  Ben Pfaff  <blp@gnu.org>
 
        Bug #21128.  Reviewed by John Darrington.
index 3ee837dab621d7bbaceb50db9267c657a146f0e6..25eb1ab9ce8c7f3ff31a0ad7b908a2cf891dc7be 100644 (file)
@@ -10,6 +10,7 @@ dist_TESTS = \
        tests/command/count.sh \
        tests/command/datasheet.sh \
        tests/command/data-list.sh \
+       tests/command/do-if.sh \
        tests/command/do-repeat.sh \
        tests/command/erase.sh \
        tests/command/examine.sh \
@@ -20,6 +21,7 @@ dist_TESTS = \
        tests/command/filter.sh \
        tests/command/flip.sh \
        tests/command/import-export.sh \
+       tests/command/input-program.sh \
        tests/command/insert.sh \
        tests/command/lag.sh \
        tests/command/list.sh \
diff --git a/tests/command/do-if.sh b/tests/command/do-if.sh
new file mode 100755 (executable)
index 0000000..185dc4e
--- /dev/null
@@ -0,0 +1,115 @@
+#!/bin/sh
+
+# This program tests the DO IF command.
+
+TEMPDIR=/tmp/pspp-tst-$$
+
+# ensure that top_builddir  are absolute
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+top_builddir=`cd $top_builddir; pwd`
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+# ensure that top_srcdir is absolute
+top_srcdir=`cd $top_srcdir; pwd`
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+LANG=C
+export LANG
+
+cleanup()
+{
+     cd /
+     #rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+activity="generate input and expected output"
+(for a in 0 1 ' '; do
+    for b in 0 1 ' '; do
+       for c in 0 1 ' '; do
+           for d in 0 1 ' '; do
+               abcd=$a$b$c$d
+               echo "$abcd" 1>&3
+               if test "$a" = "1"; then
+                   echo " $abcd A"
+               elif test "$a" = " "; then
+                   :
+               elif test "$b" = "1"; then
+                   echo " $abcd B"
+               elif test "$b" = " "; then
+                   :
+               elif test "$c" = "1"; then
+                   echo " $abcd C"
+               elif test "$c" = " "; then
+                   :
+               elif test "$d" = "1"; then
+                   echo " $abcd D"
+               elif test "$d" = " "; then
+                   :
+               else
+                   echo " $abcd E"
+               fi
+           done
+       done
+    done
+done) >test1.expected 3>test1.data
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="create test1.pspp"
+cat > test1.pspp <<EOF
+DATA LIST FILE="test1.data"/A B C D 1-4 ABCD 1-4 (A).
+DO IF A.
+PRINT OUTFILE="test1.out"/ABCD 'A'.
+ELSE IF B.
+PRINT OUTFILE="test1.out"/ABCD 'B'.
+ELSE IF C.
+PRINT OUTFILE="test1.out"/ABCD 'C'.
+ELSE IF D.
+PRINT OUTFILE="test1.out"/ABCD 'D'.
+ELSE.
+PRINT OUTFILE="test1.out"/ABCD 'E'.
+END IF.
+EXECUTE.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test1"
+$SUPERVISOR $PSPP --testing-mode test1.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test1 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -u $TEMPDIR/test1.out $TEMPDIR/test1.expected
+if [ $? -ne 0 ] ; then fail ; fi
+
+pass
diff --git a/tests/command/input-program.sh b/tests/command/input-program.sh
new file mode 100755 (executable)
index 0000000..0d7d95c
--- /dev/null
@@ -0,0 +1,306 @@
+#!/bin/sh
+
+# This program tests the INPUT PROGRAM command, specifically all of
+# the examples given in the user manual.
+
+TEMPDIR=/tmp/pspp-tst-$$
+
+# ensure that top_builddir  are absolute
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+top_builddir=`cd $top_builddir; pwd`
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+# ensure that top_srcdir is absolute
+top_srcdir=`cd $top_srcdir; pwd`
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+LANG=C
+export LANG
+
+cleanup()
+{
+     cd /
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+activity="create a.data"
+cat > a.data <<EOF
+1
+2
+3
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="create b.data"
+cat > b.data <<EOF
+4
+5
+6
+7
+8
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="create test1.pspp"
+cat > test1.pspp <<EOF
+INPUT PROGRAM.
+        DATA LIST NOTABLE FILE='a.data'/X 1-10.
+        DATA LIST NOTABLE FILE='b.data'/Y 1-10.
+END INPUT PROGRAM.
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test1"
+$SUPERVISOR $PSPP --testing-mode test1.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test1 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  $TEMPDIR/pspp.list - << EOF
+         X          Y
+---------- ----------
+         1          4
+         2          5
+         3          6
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+activity="create test2.pspp"
+cat > test2.pspp <<EOF
+INPUT PROGRAM.
+        NUMERIC #A #B.
+
+        DO IF NOT #A.
+                DATA LIST NOTABLE END=#A FILE='a.data'/X 1-10.
+        END IF.
+        DO IF NOT #B.
+                DATA LIST NOTABLE END=#B FILE='b.data'/Y 1-10.
+        END IF.
+        DO IF #A AND #B.
+                END FILE.
+        END IF.
+        END CASE.
+END INPUT PROGRAM.
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test2"
+$SUPERVISOR $PSPP --testing-mode test2.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test2 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  $TEMPDIR/pspp.list - << EOF
+         X          Y
+---------- ----------
+         1          4
+         2          5
+         3          6
+         .          7
+         .          8
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+activity="create test3.pspp"
+cat > test3.pspp <<EOF
+INPUT PROGRAM.
+        NUMERIC #A #B.
+
+        DO IF #A.
+                DATA LIST NOTABLE END=#B FILE='b.data'/X 1-10.
+                DO IF #B.
+                        END FILE.
+                ELSE.
+                        END CASE.
+                END IF.
+        ELSE.
+                DATA LIST NOTABLE END=#A FILE='a.data'/X 1-10.
+                DO IF NOT #A.
+                        END CASE.
+                END IF.
+        END IF.
+END INPUT PROGRAM.
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test3"
+$SUPERVISOR $PSPP --testing-mode test3.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test3 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  $TEMPDIR/pspp.list - << EOF
+         X
+----------
+         1
+         2
+         3
+         4
+         5
+         6
+         7
+         8
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+activity="create test4.pspp"
+cat > test4.pspp <<EOF
+INPUT PROGRAM.
+        NUMERIC #EOF.
+
+        LOOP IF NOT #EOF.
+                DATA LIST NOTABLE END=#EOF FILE='a.data'/X 1-10.
+                DO IF NOT #EOF.
+                        END CASE.
+                END IF.
+        END LOOP.
+
+        COMPUTE #EOF = 0.
+        LOOP IF NOT #EOF.
+                DATA LIST NOTABLE END=#EOF FILE='b.data'/X 1-10.
+                DO IF NOT #EOF.
+                        END CASE.
+                END IF.
+        END LOOP.
+
+        END FILE.
+END INPUT PROGRAM.
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test4"
+$SUPERVISOR $PSPP --testing-mode test4.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test4 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  $TEMPDIR/pspp.list - << EOF
+         X
+----------
+         1
+         2
+         3
+         4
+         5
+         6
+         7
+         8
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+# This example differs slightly from the one in the manual in that
+# it doesn't generate random variates.  There's already a test that
+# checks that random variates are predictable, so we don't need
+# another.
+activity="create test5.pspp"
+cat > test5.pspp <<EOF
+INPUT PROGRAM.
+        LOOP #I=1 TO 50.
+                COMPUTE X=#I * 3.
+                END CASE.
+        END LOOP.
+        END FILE.
+END INPUT PROGRAM.
+LIST/FORMAT=NUMBERED.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run test5"
+$SUPERVISOR $PSPP --testing-mode test5.pspp
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare test5 results"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  $TEMPDIR/pspp.list - << EOF
+Case#        X
+----- --------
+    1     3.00
+    2     6.00
+    3     9.00
+    4    12.00
+    5    15.00
+    6    18.00
+    7    21.00
+    8    24.00
+    9    27.00
+   10    30.00
+   11    33.00
+   12    36.00
+   13    39.00
+   14    42.00
+   15    45.00
+   16    48.00
+   17    51.00
+   18    54.00
+   19    57.00
+   20    60.00
+   21    63.00
+   22    66.00
+   23    69.00
+   24    72.00
+   25    75.00
+   26    78.00
+   27    81.00
+   28    84.00
+   29    87.00
+   30    90.00
+   31    93.00
+   32    96.00
+   33    99.00
+   34   102.00
+   35   105.00
+   36   108.00
+   37   111.00
+   38   114.00
+   39   117.00
+   40   120.00
+   41   123.00
+   42   126.00
+   43   129.00
+   44   132.00
+   45   135.00
+   46   138.00
+   47   141.00
+   48   144.00
+   49   147.00
+   50   150.00
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass