X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasegrouper.c;h=8a4f05b318faa2874dab7d1e695a9d9901ab94c6;hb=9f4661992f4b481c6dafa6fd53c94ecfe7b3af8c;hp=f2815106ea6330bac01609c40ae310be8cc808da;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp-builds.git diff --git a/src/data/casegrouper.c b/src/data/casegrouper.c index f2815106..8a4f05b3 100644 --- a/src/data/casegrouper.c +++ b/src/data/casegrouper.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. +/* PSPP - a program for statistical analysis. Copyright (C) 2007 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 @@ -30,16 +28,27 @@ #include "xalloc.h" +/* A casegrouper. */ struct casegrouper { - struct casereader *reader; - struct taint *taint; + struct casereader *reader; /* Source of input cases. */ + struct taint *taint; /* Error status for casegrouper. */ + /* Functions for grouping cases. */ bool (*same_group) (const struct ccase *, const struct ccase *, void *aux); void (*destroy) (void *aux); void *aux; }; +/* Creates and returns a new casegrouper that takes its input + from READER. SAME_GROUP is used to decide which cases are in + a group: it returns true if the pair of cases provided are in + the same group, false otherwise. DESTROY will be called when + the casegrouper is destroyed and should free any storage + needed by SAME_GROUP. + + SAME_GROUP may be a null pointer. If so, READER's entire + contents is considered to be a single group. */ struct casegrouper * casegrouper_create_func (struct casereader *reader, bool (*same_group) (const struct ccase *, @@ -57,13 +66,17 @@ casegrouper_create_func (struct casereader *reader, return grouper; } -/* FIXME: we really shouldn't need a temporary casewriter for the - common case where we read an entire group's data before going - on to the next. */ +/* Obtains the next group of cases from GROUPER. Returns true if + successful, false if no groups remain. If successful, *READER + is set to the casereader for the new group; otherwise, it is + set to NULL. */ bool casegrouper_get_next_group (struct casegrouper *grouper, struct casereader **reader) { + /* FIXME: we really shouldn't need a temporary casewriter for + the common case where we read an entire group's data before + going on to the next. */ if (grouper->same_group != NULL) { struct casewriter *writer; @@ -102,10 +115,17 @@ casegrouper_get_next_group (struct casegrouper *grouper, return true; } else - return false; + { + *reader = NULL; + return false; + } } } +/* Destroys GROUPER. Returns false if GROUPER's input casereader + or any state derived from it had become tainted, which means + that an I/O error or other serious error occurred in + processing data derived from GROUPER; otherwise, return true. */ bool casegrouper_destroy (struct casegrouper *grouper) { @@ -126,29 +146,26 @@ casegrouper_destroy (struct casegrouper *grouper) else 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; - size_t var_cnt; + const struct variable **vars; /* Variables to compare. */ + size_t var_cnt; /* Number of variables. */ }; -static bool -casegrouper_vars_same_group (const struct ccase *a, const struct ccase *b, - void *cv_) -{ - struct casegrouper_vars *cv = cv_; - return case_compare (a, b, cv->vars, cv->var_cnt) == 0; -} - -static void -casegrouper_vars_destroy (void *cv_) -{ - struct casegrouper_vars *cv = cv_; - free (cv->vars); - free (cv); -} +static bool casegrouper_vars_same_group (const struct ccase *, + const struct ccase *, + void *); +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. */ struct casegrouper * casegrouper_create_vars (struct casereader *reader, const struct variable *const *vars, @@ -168,6 +185,11 @@ casegrouper_create_vars (struct casereader *reader, return casegrouper_create_func (reader, NULL, NULL, NULL); } +/* Creates and returns a casegrouper that reads data from 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. */ struct casegrouper * casegrouper_create_splits (struct casereader *reader, const struct dictionary *dict) @@ -177,6 +199,11 @@ casegrouper_create_splits (struct casereader *reader, dict_get_split_cnt (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. */ struct casegrouper * casegrouper_create_case_ordering (struct casereader *reader, const struct case_ordering *co) @@ -191,3 +218,22 @@ casegrouper_create_case_ordering (struct casereader *reader, return grouper; } + +/* "same_group" function for an equal-variables casegrouper. */ +static bool +casegrouper_vars_same_group (const struct ccase *a, const struct ccase *b, + void *cv_) +{ + struct casegrouper_vars *cv = cv_; + return case_compare (a, b, cv->vars, cv->var_cnt) == 0; +} + +/* "destroy" for an equal-variables casegrouper. */ +static void +casegrouper_vars_destroy (void *cv_) +{ + struct casegrouper_vars *cv = cv_; + free (cv->vars); + free (cv); +} +