DO REPEAT: Accept duplicate names as substitution variables.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 21 Mar 2024 13:32:56 +0000 (06:32 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 21 Mar 2024 13:32:56 +0000 (06:32 -0700)
Thanks to Frans Houweling for reporting the bug.

src/language/commands/repeat.c
src/language/lexer/variable-parser.c
tests/language/commands/do-repeat.at

index af0d89d59edee3104b43a96bf4d93d8ac7da902e..665b97aa7b4121bf3aebd95e53a7857e121fbe13 100644 (file)
@@ -326,7 +326,8 @@ static bool
 parse_ids (struct lexer *lexer, const struct dictionary *dict,
            struct dummy_var *dv)
 {
-  return parse_mixed_vars (lexer, dict, &dv->values, &dv->n_values, PV_NONE);
+  return parse_mixed_vars (lexer, dict, &dv->values, &dv->n_values,
+                           PV_DUPLICATE);
 }
 
 /* Adds REPLACEMENT to MACRO's list of replacements, which has
index 3b3b46e6739ca2c76e852ce35f4a8d7e40fa6f3b..2977c2fb7616106cdc5664239506317c3403105a 100644 (file)
@@ -525,7 +525,7 @@ parse_DATA_LIST_vars (struct lexer *lexer, const struct dictionary *dict,
 
   bool ok = false;
 
-  assert ((pv_opts & ~(PV_APPEND | PV_SINGLE
+  assert ((pv_opts & ~(PV_APPEND | PV_SINGLE | PV_DUPLICATE
                        | PV_NO_SCRATCH | PV_NO_DUPLICATE)) == 0);
   stringi_set_init (&set);
 
index 81bc952bc8ac3d9cab991ab1cc773d8bbf4e0c4f..32c9a0531eeacbb996951698a929738ce4d2057a 100644 (file)
@@ -251,4 +251,29 @@ do-repeat.sps:16: error: DO REPEAT: Each dummy variable must have the same numbe
 
 error: DO REPEAT: At end of input: Syntax error expecting END REPEAT.
 ])
+AT_CLEANUP
+
+AT_SETUP([DO REPEAT -- duplicate substitutions])
+AT_DATA([do-repeat.sps], [dnl
+DATA LIST LIST NOTABLE / numer1 numer2 denom1.
+BEGIN DATA
+30 25 100
+20 15 100
+10 40 100
+20 10 100
+END DATA.
+
+* Check that duplicates are OK for both existing (denom1)
+  and nonexistent (perc1) variables.
+DO REPEAT n=numer1 numer2
+     /d = denom1 denom1
+     /p = perc1 perc1.
+   COMPUTE p = n / d * 100.
+END REPEAT PRINT.
+])
+AT_CHECK([pspp do-repeat.sps], [0], [dnl
+   COMPUTE perc1 = numer1 / denom1 * 100.
+
+   COMPUTE perc1 = numer2 / denom1 * 100.
+])
 AT_CLEANUP
\ No newline at end of file