X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasegrouper.c;h=9e7ab157e1921057ba8aed5a720658df74677067;hb=5c3291dc396b795696e94f47780308fd7ace6fc4;hp=8a392afbab8be62531b68c9f3890818e88df4630;hpb=5da5a98055ad574120c3e3922af097411a0dcf3a;p=pspp-builds.git diff --git a/src/data/casegrouper.c b/src/data/casegrouper.c index 8a392afb..9e7ab157 100644 --- a/src/data/casegrouper.c +++ b/src/data/casegrouper.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. - Copyright (C) 2007 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 2007, 2009 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 the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program. If not, see . */ #include @@ -22,10 +20,10 @@ #include -#include #include #include #include +#include #include #include "xalloc.h" @@ -82,28 +80,27 @@ 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)); + case_ref (group_case); + casewriter_write (writer, 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 (group_case); *reader = casewriter_make_reader (writer); return true; @@ -112,9 +109,18 @@ casegrouper_get_next_group (struct casegrouper *grouper, { if (grouper->reader != NULL) { - *reader = grouper->reader; - grouper->reader = NULL; - return true; + if (!casereader_is_empty (grouper->reader)) + { + *reader = grouper->reader; + grouper->reader = NULL; + return true; + } + else + { + casereader_destroy (grouper->reader); + grouper->reader = NULL; + return false; + } } else { @@ -152,13 +158,6 @@ casegrouper_destroy (struct casegrouper *grouper) /* 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 *); @@ -173,15 +172,12 @@ casegrouper_create_vars (struct casereader *reader, const struct variable *const *vars, size_t var_cnt) { - if (var_cnt > 0) + 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); @@ -203,39 +199,41 @@ casegrouper_create_splits (struct casereader *reader, /* 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 + 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. */ 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); + } } -