X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Ftransformations.c;h=2a73cade41bbcf6e4c55622c5d00b9d8b18505b6;hb=b5c82cc9aabe7e641011130240ae1b2e84348e23;hp=b5a6c9d8140cdb59a97d70d336e398d7fef975e8;hpb=480a0746507ce73d26f528b56dc3ed80195096e0;p=pspp-builds.git diff --git a/src/data/transformations.c b/src/data/transformations.c index b5a6c9d8..2a73cade 100644 --- a/src/data/transformations.c +++ b/src/data/transformations.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 1997-9, 2000, 2006, 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 @@ -33,7 +31,7 @@ struct transformation /* Offset to add to EXECUTE's return value, if it returns a transformation index. Normally 0 but set to the starting index of a spliced chain after splicing. */ - int idx_ofs; + int idx_ofs; trns_finalize_func *finalize; /* Finalize proc. */ trns_proc_func *execute; /* Executes the transformation. */ trns_free_func *free; /* Garbage collector proc. */ @@ -41,7 +39,7 @@ struct transformation }; /* A chain of transformations. */ -struct trns_chain +struct trns_chain { struct transformation *trns; /* Array of transformations. */ size_t trns_cnt; /* Number of transformations. */ @@ -51,7 +49,7 @@ struct trns_chain /* Allocates and returns a new transformation chain. */ struct trns_chain * -trns_chain_create (void) +trns_chain_create (void) { struct trns_chain *chain = xmalloc (sizeof *chain); chain->trns = NULL; @@ -68,17 +66,17 @@ trns_chain_create (void) finalization the chain's contents are fixed, so that no more transformations may be added afterward. */ void -trns_chain_finalize (struct trns_chain *chain) +trns_chain_finalize (struct trns_chain *chain) { - if (!chain->finalized) + if (!chain->finalized) { size_t i; - for (i = 0; i < chain->trns_cnt; i++) + for (i = 0; i < chain->trns_cnt; i++) { struct transformation *trns = &chain->trns[i]; if (trns->finalize != NULL) - trns->finalize (trns->aux); + trns->finalize (trns->aux); } chain->finalized = true; } @@ -87,34 +85,34 @@ trns_chain_finalize (struct trns_chain *chain) /* Destroys CHAIN, finalizing it in the process if it has not already been finalized. */ bool -trns_chain_destroy (struct trns_chain *chain) +trns_chain_destroy (struct trns_chain *chain) { bool ok = true; - if (chain != NULL) + if (chain != NULL) { size_t i; - + /* Needed to ensure that the control stack gets cleared. */ trns_chain_finalize (chain); - - for (i = 0; i < chain->trns_cnt; i++) + + for (i = 0; i < chain->trns_cnt; i++) { struct transformation *trns = &chain->trns[i]; - if (trns->free != NULL) + if (trns->free != NULL) ok = trns->free (trns->aux) && ok; } free (chain->trns); free (chain); } - + return ok; } /* Returns true if CHAIN contains any transformations, false otherwise. */ bool -trns_chain_is_empty (const struct trns_chain *chain) +trns_chain_is_empty (const struct trns_chain *chain) { return chain->trns_cnt == 0; } @@ -125,7 +123,7 @@ trns_chain_is_empty (const struct trns_chain *chain) void trns_chain_append (struct trns_chain *chain, trns_finalize_func *finalize, trns_proc_func *execute, trns_free_func *free, - void *aux) + void *aux) { struct transformation *trns; @@ -147,25 +145,25 @@ trns_chain_append (struct trns_chain *chain, trns_finalize_func *finalize, and destroys SRC. Both DST and SRC must already be finalized. */ void -trns_chain_splice (struct trns_chain *dst, struct trns_chain *src) +trns_chain_splice (struct trns_chain *dst, struct trns_chain *src) { size_t i; - + assert (dst->finalized); assert (src->finalized); - if (dst->trns_cnt + src->trns_cnt > dst->trns_cap) + if (dst->trns_cnt + src->trns_cnt > dst->trns_cap) { dst->trns_cap = dst->trns_cnt + src->trns_cnt; dst->trns = xnrealloc (dst->trns, dst->trns_cap, sizeof *dst->trns); } - for (i = 0; i < src->trns_cnt; i++) + for (i = 0; i < src->trns_cnt; i++) { struct transformation *d = &dst->trns[i + dst->trns_cnt]; const struct transformation *s = &src->trns[i]; *d = *s; - d->idx_ofs += src->trns_cnt; + d->idx_ofs += src->trns_cnt; } dst->trns_cnt += src->trns_cnt; @@ -175,35 +173,34 @@ trns_chain_splice (struct trns_chain *dst, struct trns_chain *src) /* Returns the index that a transformation execution function may return to "jump" to the next transformation to be added. */ size_t -trns_chain_next (struct trns_chain *chain) +trns_chain_next (struct trns_chain *chain) { return chain->trns_cnt; } -/* Executes the given CHAIN of transformations on C, - passing *CASE_NR as the case number. - If a transformation modifies *CASE_NR, it will affect the case - number passed to following transformations. +/* Executes the given CHAIN of transformations on *C, + passing CASE_NR as the case number. + *C may be replaced by a new case. Returns the result code that caused the transformations to terminate, or TRNS_CONTINUE if the transformations finished due to "falling off the end" of the set of transformations. */ enum trns_result -trns_chain_execute (struct trns_chain *chain, struct ccase *c, - const size_t *case_nr) +trns_chain_execute (const struct trns_chain *chain, enum trns_result start, + struct ccase **c, casenumber case_nr) { size_t i; assert (chain->finalized); - for (i = 0; i < chain->trns_cnt; ) + for (i = start < 0 ? 0 : start; i < chain->trns_cnt; ) { struct transformation *trns = &chain->trns[i]; - int retval = trns->execute (trns->aux, c, *case_nr); + int retval = trns->execute (trns->aux, c, case_nr); if (retval == TRNS_CONTINUE) i++; else if (retval >= 0) i = retval + trns->idx_ofs; else - return retval; + return retval == TRNS_END_CASE ? i + 1 : retval; } return TRNS_CONTINUE;