Actually implement the new procedure code and adapt all of its clients
[pspp-builds.git] / src / language / stats / npar.q
index 2881ff9c814dcf2173428fe6ebf0eac55279b571..74e8364f1b14bd7ae33a0b97507bbe4fb9129d75 100644 (file)
@@ -20,23 +20,25 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 #include <config.h>
 
-#include <language/lexer/lexer.h>
-#include <language/lexer/variable-parser.h>
-#include <language/command.h>
-#include <data/procedure.h>
-#include <libpspp/pool.h>
-#include <libpspp/hash.h>
+#include <language/stats/npar.h>
+
+#include <math.h>
 
-#include <data/casefilter.h>
 #include <data/case.h>
-#include <data/casefile.h>
-#include <math/moments.h>
+#include <data/casegrouper.h>
+#include <data/casereader.h>
 #include <data/dictionary.h>
-#include <language/stats/chisquare.h>
+#include <data/procedure.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <language/lexer/variable-parser.h>
 #include <language/stats/binomial.h>
-#include <math.h>
+#include <language/stats/chisquare.h>
+#include <libpspp/hash.h>
+#include <libpspp/pool.h>
+#include <libpspp/taint.h>
+#include <math/moments.h>
 
-#include "npar.h"
 #include "npar-summary.h"
 
 #include "gettext.h"
@@ -75,22 +77,21 @@ struct npar_specs
                                       (those mentioned on ANY subcommand */
   int n_vars; /* Number of variables in vv */
 
-  struct casefilter *filter; /* The missing value filter */
+  enum mv_class filter;    /* Missing values to filter. */
 
   bool descriptives;       /* Descriptive statistics should be calculated */
   bool quartiles;          /* Quartiles should be calculated */
 };
 
 void one_sample_insert_variables (const struct npar_test *test,
-                                 struct hsh_table *variables);
+                                 struct const_hsh_table *variables);
 
-static bool 
-npar_execute(const struct ccase *first UNUSED,
-            const struct casefile *cf, void *aux, 
+static void
+npar_execute(struct casereader *input,
+             const struct npar_specs *specs,
             const struct dataset *ds)
 {
   int t;
-  const struct npar_specs *specs = aux;
   struct descriptives *summary_descriptives = NULL;
 
   for ( t = 0 ; t < specs->n_tests; ++t ) 
@@ -101,7 +102,7 @@ npar_execute(const struct ccase *first UNUSED,
          msg (SW, _("NPAR subcommand not currently implemented."));
          continue;
        }
-      test->execute (ds, cf, specs->filter, test);
+      test->execute (ds, casereader_clone (input), specs->filter, test);
     }
 
   if ( specs->descriptives )
@@ -109,31 +110,34 @@ npar_execute(const struct ccase *first UNUSED,
       summary_descriptives = xnmalloc (sizeof (*summary_descriptives), 
                                       specs->n_vars);
 
-      npar_summary_calc_descriptives (summary_descriptives, cf, 
-                                     specs->filter,
+      npar_summary_calc_descriptives (summary_descriptives,
+                                      casereader_clone (input), 
                                      dataset_dict (ds),
-                                     specs->vv, specs->n_vars);
+                                     specs->vv, specs->n_vars,
+                                      specs->filter);
     }
 
-  if ( specs->descriptives || specs->quartiles ) 
+  if ( (specs->descriptives || specs->quartiles)
+       && !taint_has_tainted_successor (casereader_get_taint (input)) ) 
     do_summary_box (summary_descriptives, specs->vv, specs->n_vars );
 
   free (summary_descriptives);
-  
-  return true;
+  casereader_destroy (input);
 }
 
-
 int
 cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
   int i;
   struct npar_specs npar_specs = {0, 0, 0, 0, 0, 0, 0, 0};
-  struct hsh_table *var_hash;
+  struct const_hsh_table *var_hash;
+  struct casegrouper *grouper;
+  struct casereader *input, *group;
+  
   npar_specs.pool = pool_create ();
 
-  var_hash = hsh_create_pool (npar_specs.pool, 0, 
+  var_hash = const_hsh_create_pool (npar_specs.pool, 0, 
                              compare_vars_by_name, hash_var_by_name, 
                              NULL, NULL);
 
@@ -143,24 +147,24 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
       return CMD_FAILURE;
     }
 
-  for (i = 0; i < npar_specs.n_tests; ++i ) 
+  for (i = 0; i < npar_specs.n_tests; ++i )
     {
       const struct npar_test *test = npar_specs.test[i];
       test->insert_variables (test, var_hash);
     }
 
-  npar_specs.vv =  (const struct variable *const *) hsh_data (var_hash);
-  npar_specs.n_vars = hsh_count (var_hash);
-  
-  if ( cmd.sbc_statistics ) 
+  npar_specs.vv =  (const struct variable *const *) const_hsh_data (var_hash);
+  npar_specs.n_vars = const_hsh_count (var_hash);
+
+  if ( cmd.sbc_statistics )
     {
       int i;
 
-      for ( i = 0 ; i < NPAR_ST_count; ++i ) 
+      for ( i = 0 ; i < NPAR_ST_count; ++i )
        {
-         if ( cmd.a_statistics[i] ) 
+         if ( cmd.a_statistics[i] )
            {
-             switch ( i ) 
+             switch ( i )
                {
                case NPAR_ST_DESCRIPTIVES:
                  npar_specs.descriptives = true;
@@ -179,19 +183,22 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
        }
     }
 
-  npar_specs.filter = 
-    casefilter_create (cmd.incl == NPAR_EXCLUDE, 0, 0);
-
-  if ( cmd.miss == NPAR_LISTWISE ) 
-    casefilter_add_variables (npar_specs.filter, 
-                             npar_specs.vv, 
-                             npar_specs.n_vars);
+  npar_specs.filter = cmd.incl == NPAR_EXCLUDE ? MV_ANY : MV_SYSTEM;
 
-  ok = multipass_procedure_with_splits (ds, npar_execute, &npar_specs);
+  input = proc_open (ds);
+  if ( cmd.miss == NPAR_LISTWISE )
+    input = casereader_create_filter_missing (input,
+                                              (struct variable **) npar_specs.vv,
+                                              npar_specs.n_vars,
+                                              npar_specs.filter, NULL);
 
-  casefilter_destroy (npar_specs.filter);
+  grouper = casegrouper_create_splits (input, dataset_dict (ds));
+  while (casegrouper_get_next_group (grouper, &group))
+    npar_execute (group, &npar_specs, ds);
+  ok = casegrouper_destroy (grouper);
+  ok = proc_commit (ds) && ok;
 
-  hsh_destroy (var_hash);
+  const_hsh_destroy (var_hash);
 
   pool_destroy (npar_specs.pool);
 
@@ -209,7 +216,7 @@ npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_t
   ((struct npar_test *)tp)->execute = chisquare_execute;
   ((struct npar_test *)tp)->insert_variables = one_sample_insert_variables;
 
-  if (!parse_variables_pool (lexer, specs->pool, dataset_dict (ds), 
+  if (!parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), 
                             &tp->vars, &tp->n_vars,
                             PV_NO_SCRATCH | PV_NO_DUPLICATE))
     {
@@ -329,7 +336,7 @@ npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_te
 
   if ( lex_match (lexer, '=') ) 
     {
-      if (parse_variables_pool (lexer, specs->pool, dataset_dict (ds), 
+      if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds), 
                                &tp->vars, &tp->n_vars,
                                PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
        {
@@ -389,13 +396,13 @@ parse_two_sample_related_test (struct lexer *lexer,
   int n = 0;
   bool paired = false;
   bool with = false;
-  struct variable **vlist1;
+  const struct variable **vlist1;
   size_t n_vlist1;
 
-  struct variable **vlist2;
+  const struct variable **vlist2;
   size_t n_vlist2;
 
-  if (!parse_variables_pool (lexer, pool, 
+  if (!parse_variables_const_pool (lexer, pool, 
                             dict, 
                             &vlist1, &n_vlist1,
                             PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
@@ -404,7 +411,7 @@ parse_two_sample_related_test (struct lexer *lexer,
   if ( lex_match(lexer, T_WITH))
     {
       with = true;
-      if ( !parse_variables_pool (lexer, pool, dict,
+      if ( !parse_variables_const_pool (lexer, pool, dict,
                                  &vlist2, &n_vlist2,
                                  PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
        return false;
@@ -421,7 +428,7 @@ parse_two_sample_related_test (struct lexer *lexer,
          if ( n_vlist1 != n_vlist2) 
            msg (SE, _("PAIRED was specified but the number of variables "
                       "preceding WITH (%d) did not match the number "
-                      "following (%d)."), n_vlist1, n_vlist2);
+                      "following (%d)."), (int) n_vlist1, (int) n_vlist2);
 
          test_parameters->n_pairs = n_vlist1 ;
        }
@@ -558,12 +565,12 @@ npar_custom_sign (struct lexer *lexer, struct dataset *ds,
 /* Insert the variables for TEST into VAR_HASH */
 void
 one_sample_insert_variables (const struct npar_test *test,
-                           struct hsh_table *var_hash)
+                           struct const_hsh_table *var_hash)
 {
   int i;
   struct one_sample_test *ost = (struct one_sample_test *) test;
 
-  for ( i = 0 ; i < ost->n_vars ; ++i ) 
-    hsh_insert (var_hash, ost->vars[i]);
+  for ( i = 0 ; i < ost->n_vars ; ++i )
+    const_hsh_insert (var_hash, ost->vars[i]);
 }