X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasereader-translator.c;h=0557b65e8d6336452b4b88c4881d901fc289c7f2;hb=c400888ac9d64228138f69b473afb0083c6ca37c;hp=b857b5b880e2d4b9cd71c1a5c49e008cf93a5e9f;hpb=cc6a060446e71cace2d828a864c85702e04aba7c;p=pspp diff --git a/src/data/casereader-translator.c b/src/data/casereader-translator.c index b857b5b880..0557b65e8d 100644 --- a/src/data/casereader-translator.c +++ b/src/data/casereader-translator.c @@ -110,3 +110,104 @@ static const struct casereader_class casereader_translator_class = NULL, NULL, }; + + + +struct casereader_append_numeric +{ + int value_ofs; + casenumber n; + new_value_func *func; + void *aux; + void (*destroy) (void *aux); +}; + +static bool can_destroy (void *can_); + +static void can_translate (struct ccase *input, struct ccase *output, + void *can_); + +/* Creates and returns a new casereader whose cases are produced + by reading from SUBREADER and appending an additional value, + generated by FUNC. AUX is an optional parameter which + gets passed to FUNC. FUNC will also receive N as it, which is + the ordinal number of the case in the reader. DESTROY is an + optional parameter used to destroy AUX. + + After this function is called, SUBREADER must not ever again + be referenced directly. It will be destroyed automatically + when the translating casereader is destroyed. */ +struct casereader * +casereader_create_append_numeric (struct casereader *subreader, + new_value_func func, void *aux, + void (*destroy) (void *aux)) +{ + struct casereader_append_numeric *can = xmalloc (sizeof *can); + can->value_ofs = casereader_get_value_cnt (subreader); + can->n = 0; + can->aux = aux; + can->func = func; + can->destroy = destroy; + return casereader_create_translator (subreader, can->value_ofs + 1, + can_translate, can_destroy, can); +} + + +static void +can_translate (struct ccase *input, struct ccase *output, void *can_) +{ + struct casereader_append_numeric *can = can_; + double new_value = can->func (input, can->n++, can->aux); + case_nullify (output); + case_move (output, input); + case_resize (output, can->value_ofs + 1); + case_data_rw_idx (output, can->value_ofs)->f = new_value; +} + +static bool +can_destroy (void *can_) +{ + struct casereader_append_numeric *can = can_; + if (can->destroy) + can->destroy (can->aux); + free (can); + return true; +} + + + +struct arithmetic_sequence +{ + double first; + double increment; +}; + +static double +next_arithmetic (const struct ccase *c UNUSED, + casenumber n, + void *aux) +{ + struct arithmetic_sequence *as = aux; + return n * as->increment + as->first; +} + +/* Creates and returns a new casereader whose cases are produced + by reading from SUBREADER and appending an additional value, + which takes the value FIRST in the first case, FIRST + + INCREMENT in the second case, FIRST + INCREMENT * 2 in the + third case, and so on. + + After this function is called, SUBREADER must not ever again + be referenced directly. It will be destroyed automatically + when the translating casereader is destroyed. */ +struct casereader * +casereader_create_arithmetic_sequence (struct casereader *subreader, + double first, double increment) +{ + struct arithmetic_sequence *as = xzalloc (sizeof *as); + as->first = first; + as->increment = increment; + return casereader_create_append_numeric (subreader, next_arithmetic, + as, free); +} +