/* 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/case-ordering.h>
-#include <data/casereader.h>
-#include <data/casewriter.h>
-#include <data/dictionary.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
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 *
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;
/* Casegrouper based on equal values of variables from case to
case. */
-/* Casegrouper based on equal variables. */
-struct casegrouper_vars
- {
- const struct variable **vars; /* Variables to compare. */
- size_t var_cnt; /* Number of variables. */
- };
-
static bool casegrouper_vars_same_group (const struct ccase *,
const struct ccase *,
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. */
+ 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,
{
if (var_cnt > 0)
{
- struct casegrouper_vars *cv = xmalloc (sizeof *cv);
- cv->vars = xmemdup (vars, sizeof *vars * var_cnt);
- cv->var_cnt = var_cnt;
- return casegrouper_create_func (reader,
- casegrouper_vars_same_group,
- casegrouper_vars_destroy,
- cv);
+ struct subcase *sc = xmalloc (sizeof *sc);
+ subcase_init_vars (sc, vars, var_cnt);
+ return casegrouper_create_func (reader, casegrouper_vars_same_group,
+ casegrouper_vars_destroy, sc);
}
else
return casegrouper_create_func (reader, NULL, NULL, NULL);
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)
/* 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 CO. If CO is
- empty (contains no sort keys), then all the cases will be put
- into a single group. */
+ 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.
+
+ Takes ownerhip of READER. */
struct casegrouper *
-casegrouper_create_case_ordering (struct casereader *reader,
- const struct case_ordering *co)
+casegrouper_create_subcase (struct casereader *reader,
+ const struct subcase *sc)
{
- const struct variable **vars;
- size_t var_cnt;
- struct casegrouper *grouper;
-
- case_ordering_get_vars (co, &vars, &var_cnt);
- grouper = casegrouper_create_vars (reader, vars, var_cnt);
- free (vars);
-
- return grouper;
+ 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);
+ }
+ else
+ return casegrouper_create_func (reader, NULL, NULL, NULL);
}
/* "same_group" function for an equal-variables casegrouper. */
static bool
casegrouper_vars_same_group (const struct ccase *a, const struct ccase *b,
- void *cv_)
+ void *sc_)
{
- struct casegrouper_vars *cv = cv_;
- return case_compare (a, b, cv->vars, cv->var_cnt) == 0;
+ struct subcase *sc = sc_;
+ return subcase_equal (sc, a, sc, b);
}
/* "destroy" for an equal-variables casegrouper. */
static void
-casegrouper_vars_destroy (void *cv_)
+casegrouper_vars_destroy (void *sc_)
{
- struct casegrouper_vars *cv = cv_;
- free (cv->vars);
- free (cv);
+ struct subcase *sc = sc_;
+ if (sc != NULL)
+ {
+ subcase_destroy (sc);
+ free (sc);
+ }
}
-