subcase: Rename subcase_destroy() to subcase_uninit().
[pspp] / src / data / casegrouper.c
index 75925650f277ad8fbdf0f83b548eebb217b9138f..d4993b4952ff9e874a0388a478aa4c941b9b9231 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2011, 2013 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include <config.h>
 
-#include <data/casegrouper.h>
+#include "data/casegrouper.h"
 
 #include <stdlib.h>
 
-#include <data/casereader.h>
-#include <data/casewriter.h>
-#include <data/dictionary.h>
-#include <data/subcase.h>
-#include <libpspp/taint.h>
+#include "data/casereader.h"
+#include "data/casewriter.h"
+#include "data/dictionary.h"
+#include "data/subcase.h"
+#include "libpspp/taint.h"
 
-#include "xalloc.h"
+#include "gl/xalloc.h"
 
 /* A casegrouper. */
 struct casegrouper
@@ -47,6 +47,8 @@ struct casegrouper
    the casegrouper is destroyed and should free any storage
    needed by SAME_GROUP.
 
+   Takes ownerhip of READER.
+
    SAME_GROUP may be a null pointer.  If so, READER's entire
    contents is considered to be a single group. */
 struct casegrouper *
@@ -80,28 +82,28 @@ casegrouper_get_next_group (struct casegrouper *grouper,
   if (grouper->same_group != NULL)
     {
       struct casewriter *writer;
-      struct ccase group_case, tmp;
+      struct ccase *group_case, *tmp;
 
-      if (!casereader_read (grouper->reader, &group_case))
+      group_case = casereader_read (grouper->reader);
+      if (group_case == NULL)
         {
           *reader = NULL;
           return false;
         }
 
-      writer = autopaging_writer_create (casereader_get_value_cnt (grouper->reader));
-      case_clone (&tmp, &group_case);
-      casewriter_write (writer, &tmp);
+      writer = autopaging_writer_create (
+        casereader_get_proto (grouper->reader));
+
+      casewriter_write (writer, case_ref (group_case));
 
-      while (casereader_peek (grouper->reader, 0, &tmp)
-             && grouper->same_group (&group_case, &tmp, grouper->aux))
+      while ((tmp = casereader_peek (grouper->reader, 0)) != NULL
+             && grouper->same_group (group_case, tmp, grouper->aux))
         {
-          struct ccase discard;
-          casereader_read (grouper->reader, &discard);
-          case_destroy (&discard);
-          casewriter_write (writer, &tmp);
+          case_unref (casereader_read (grouper->reader));
+          casewriter_write (writer, tmp);
         }
-      case_destroy (&tmp);
-      case_destroy (&group_case);
+      case_unref (tmp);
+      case_unref (group_case);
 
       *reader = casewriter_make_reader (writer);
       return true;
@@ -166,19 +168,21 @@ static void casegrouper_vars_destroy (void *);
 
 /* Creates and returns a casegrouper that reads data from READER
    and breaks it into contiguous groups of cases that have equal
-   values for the VAR_CNT variables in VARS.  If VAR_CNT is 0,
-   then all the cases will be put in a single group. */
+   values for the N_VARS variables in VARS.  If N_VARS is 0,
+   then all the cases will be put in a single group.
+
+   Takes ownerhip of READER. */
 struct casegrouper *
 casegrouper_create_vars (struct casereader *reader,
                          const struct variable *const *vars,
-                         size_t var_cnt)
+                         size_t n_vars)
 {
-  if (var_cnt > 0) 
+  if (n_vars > 0)
     {
       struct subcase *sc = xmalloc (sizeof *sc);
-      subcase_init_vars (sc, vars, var_cnt);
+      subcase_init_vars (sc, vars, n_vars);
       return casegrouper_create_func (reader, casegrouper_vars_same_group,
-                                      casegrouper_vars_destroy, sc); 
+                                      casegrouper_vars_destroy, sc);
     }
   else
     return casegrouper_create_func (reader, NULL, NULL, NULL);
@@ -188,31 +192,35 @@ casegrouper_create_vars (struct casereader *reader,
    and breaks it into contiguous groups of cases that have equal
    values for the SPLIT FILE variables in DICT.  If DICT has no
    SPLIT FILE variables, then all the cases will be put into a
-   single group. */
+   single group.
+
+   Takes ownerhip of READER. */
 struct casegrouper *
 casegrouper_create_splits (struct casereader *reader,
                            const struct dictionary *dict)
 {
   return casegrouper_create_vars (reader,
                                   dict_get_split_vars (dict),
-                                  dict_get_split_cnt (dict));
+                                  dict_get_n_splits (dict));
 }
 
 /* Creates and returns a casegrouper that reads data from READER
    and breaks it into contiguous groups of cases that have equal
    values for the variables used for sorting in SC.  If SC is
    empty (contains no fields), then all the cases will be put
-   into a single group. */
+   into a single group.
+
+   Takes ownerhip of READER. */
 struct casegrouper *
 casegrouper_create_subcase (struct casereader *reader,
                             const struct subcase *sc)
 {
-  if (subcase_get_n_fields (sc) > 0) 
+  if (subcase_get_n_fields (sc) > 0)
     {
       struct subcase *sc_copy = xmalloc (sizeof *sc);
       subcase_clone (sc_copy, sc);
       return casegrouper_create_func (reader, casegrouper_vars_same_group,
-                                      casegrouper_vars_destroy, sc_copy); 
+                                      casegrouper_vars_destroy, sc_copy);
     }
   else
     return casegrouper_create_func (reader, NULL, NULL, NULL);
@@ -232,9 +240,9 @@ static void
 casegrouper_vars_destroy (void *sc_)
 {
   struct subcase *sc = sc_;
-  if (sc != NULL) 
+  if (sc != NULL)
     {
-      subcase_destroy (sc);
-      free (sc); 
+      subcase_uninit (sc);
+      free (sc);
     }
 }