X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Faggregate.c;h=4d00a34ad2cbb7404548762a0096f94b22f9e409;hb=77cbf2d7d1e5712d4ef952f265ed5c2917fc3f68;hp=d49ebf9e520a51c86c13eee2fb73d95fb7b79c2f;hpb=4944c86a9318bc5b5578ab145a95c116ffd2c9fd;p=pspp diff --git a/src/aggregate.c b/src/aggregate.c index d49ebf9e52..4d00a34ad2 100644 --- a/src/aggregate.c +++ b/src/aggregate.c @@ -21,12 +21,12 @@ #include #include #include "alloc.h" -#include "approx.h" #include "command.h" #include "error.h" #include "file-handle.h" #include "lexer.h" #include "misc.h" +#include "pool.h" #include "settings.h" #include "sfm.h" #include "sort.h" @@ -36,8 +36,6 @@ #include "vfm.h" #include "vfmP.h" -#undef DEBUGGING -/*#define DEBUGGING 1*/ #include "debug-print.h" /* Specifies how to make an aggregate variable. */ @@ -67,8 +65,6 @@ enum N_AGR_FUNCS, N_NO_VARS, NU_NO_VARS, FUNC = 0x1f, /* Function mask. */ FSTRING = 1<<5, /* String function bit. */ - FWEIGHT = 1<<6, /* Weighted function bit. */ - FOPTIONS = FSTRING | FWEIGHT /* Function options mask. */ }; /* Attributes of an aggregation function. */ @@ -81,7 +77,7 @@ struct agr_func }; /* Attributes of aggregation functions. */ -static struct agr_func agr_func_tab[] = +static const struct agr_func agr_func_tab[] = { {"", 0, -1, {0, 0, 0}}, {"SUM", 0, -1, {FMT_F, 8, 2}}, @@ -121,6 +117,9 @@ enum /* ITEMWISE or COLUMNWISE. */ static int missing; +/* Sort program. */ +static struct sort_cases_pgm *sort; + /* Aggregate variables. */ static struct agr_var *agr_first, *agr_next; @@ -142,15 +141,16 @@ static void initialize_aggregate_info (void); /* Prototypes. */ static int parse_aggregate_functions (void); static void free_aggregate_functions (void); -static int aggregate_single_case (struct ccase *input, struct ccase *output); +static int aggregate_single_case (const struct ccase *input, + struct ccase *output); static int create_sysfile (void); -static int agr_00x_trns_proc (struct trns_header *, struct ccase *); -static void agr_00x_end_func (void); -static int agr_10x_trns_proc (struct trns_header *, struct ccase *); -static void agr_10x_trns_free (struct trns_header *); -static void agr_10x_end_func (void); -static int agr_11x_func (void); +static trns_proc_func agr_00x_trns_proc, agr_10x_trns_proc; +static trns_free_func agr_10x_trns_free; +static void agr_00x_end_func (void *aux); +static void agr_10x_end_func (void *); +static read_sort_output_func agr_11x_read; +static void agr_11x_finish (void); #if DEBUGGING static void debug_print (int flags); @@ -162,18 +162,17 @@ static void debug_print (int flags); int cmd_aggregate (void) { - /* From sort.c. */ - int parse_sort_variables (void); - /* Have we seen these subcommands? */ unsigned seen = 0; outfile = NULL; missing = ITEMWISE; - v_sort = NULL; + sort = NULL; prev_case = NULL; - agr_dict = new_dictionary (1); + agr_dict = dict_create (); + dict_set_label (agr_dict, dict_get_label (default_dict)); + dict_set_documents (agr_dict, dict_get_documents (default_dict)); lex_match_id ("AGGREGATE"); @@ -186,9 +185,9 @@ cmd_aggregate (void) { if (seen & 1) { - free (v_sort); - free_dictionary (agr_dict); - msg (SE, _("OUTFILE specified multiple times.")); + destroy_sort_cases_pgm (sort); + dict_destroy (agr_dict); + msg (SE, _("%s subcommand given multiple times."),"OUTFILE"); return CMD_FAILURE; } seen |= 1; @@ -201,8 +200,8 @@ cmd_aggregate (void) outfile = fh_parse_file_handle (); if (outfile == NULL) { - free (v_sort); - free_dictionary (agr_dict); + destroy_sort_cases_pgm (sort); + dict_destroy (agr_dict); return CMD_FAILURE; } } @@ -212,8 +211,8 @@ cmd_aggregate (void) lex_match ('='); if (!lex_match_id ("COLUMNWISE")) { - free (v_sort); - free_dictionary (agr_dict); + destroy_sort_cases_pgm (sort); + dict_destroy (agr_dict); lex_error (_("while expecting COLUMNWISE")); return CMD_FAILURE; } @@ -227,28 +226,29 @@ cmd_aggregate (void) { if (seen & 8) { - free (v_sort); - free_dictionary (agr_dict); - msg (SE, _("BREAK specified multiple times.")); + destroy_sort_cases_pgm (sort); + dict_destroy (agr_dict); + msg (SE, _("%s subcommand given multiple times."),"BREAK"); return CMD_FAILURE; } seen |= 8; lex_match ('='); - if (!parse_sort_variables ()) + sort = parse_sort (); + if (sort == NULL) { - free_dictionary (agr_dict); + dict_destroy (agr_dict); return CMD_FAILURE; } { int i; - for (i = 0; i < nv_sort; i++) + for (i = 0; i < sort->var_cnt; i++) { struct variable *v; - v = dup_variable (agr_dict, v_sort[i], v_sort[i]->name); + v = dict_clone_var (agr_dict, sort->vars[i], sort->vars[i]->name); assert (v != NULL); } } @@ -264,22 +264,16 @@ cmd_aggregate (void) if (!parse_aggregate_functions ()) { free_aggregate_functions (); - free (v_sort); + destroy_sort_cases_pgm (sort); return CMD_FAILURE; } /* Delete documents. */ if (!(seen & 2)) - { - free (agr_dict->documents); - agr_dict->documents = NULL; - agr_dict->n_documents = 0; - } + dict_set_documents (agr_dict, NULL); /* Cancel SPLIT FILE. */ - default_dict.n_splits = 0; - free (default_dict.splits); - default_dict.splits = NULL; + dict_set_split_vars (agr_dict, NULL, 0); #if DEBUGGING debug_print (seen); @@ -321,7 +315,7 @@ cmd_aggregate (void) if (outfile != NULL) type |= 4; - if (nv_sort != 0 && (seen & 4) == 0) + if (sort != NULL && (seen & 4) == 0) type |= 2; if (temporary) type |= 1; @@ -332,7 +326,7 @@ cmd_aggregate (void) cancel_temporary (); /* fall through */ case 2: - sort_cases (0); + sort_cases (sort, 0); goto case0; case 1: @@ -352,7 +346,7 @@ cmd_aggregate (void) agr_dict = NULL; - procedure (NULL, NULL, agr_00x_end_func); + procedure (NULL, NULL, agr_00x_end_func, NULL); break; } @@ -368,27 +362,21 @@ cmd_aggregate (void) t->free = agr_10x_trns_free; add_transformation (t); - procedure (NULL, NULL, agr_10x_end_func); + procedure (NULL, NULL, agr_10x_end_func, NULL); } break; } case 6: - case 7: - sort_cases (1); + case 7: + sort_cases (sort, 1); if (!create_sysfile ()) goto lossage; - read_sort_output (agr_11x_func); - - { - struct ccase *save_temp_case = temp_case; - temp_case = NULL; - agr_11x_func (); - temp_case = save_temp_case; - } - + read_sort_output (sort, agr_11x_read, NULL); + agr_11x_finish (); + break; default: @@ -400,7 +388,7 @@ cmd_aggregate (void) free (buf_1xx); /* Clean up. */ - free (v_sort); + destroy_sort_cases_pgm (sort); free_aggregate_functions (); free (prev_case); @@ -408,7 +396,7 @@ cmd_aggregate (void) lossage: /* Clean up. */ - free (v_sort); + destroy_sort_cases_pgm (sort); free_aggregate_functions (); free (prev_case); @@ -427,13 +415,13 @@ create_sysfile (void) if (!sfm_write_dictionary (&w)) { free_aggregate_functions (); - free (v_sort); - free_dictionary (agr_dict); + destroy_sort_cases_pgm (sort); + dict_destroy (agr_dict); return 0; } buf64_1xx = xmalloc (sizeof *buf64_1xx * w.case_size); - buf_1xx = xmalloc (sizeof (struct ccase) + sizeof (union value) * (agr_dict->nval - 1)); + buf_1xx = xmalloc (dict_get_case_size (agr_dict)); return 1; } @@ -444,9 +432,6 @@ parse_aggregate_functions (void) { agr_first = agr_next = NULL; - /* Anticipate weighting for optimization later. */ - update_weighting (&default_dict); - /* Parse everything. */ for (;;) { @@ -455,7 +440,7 @@ parse_aggregate_functions (void) int n_dest; int include_missing; - struct agr_func *function; + const struct agr_func *function; int func_index; union value arg[2]; @@ -469,6 +454,7 @@ parse_aggregate_functions (void) dest_label = NULL; n_dest = 0; src = NULL; + function = NULL; n_src = 0; arg[0].c = NULL; arg[1].c = NULL; @@ -545,7 +531,7 @@ parse_aggregate_functions (void) else if (function->n_args) pv_opts |= PV_SAME_TYPE; - if (!parse_variables (&default_dict, &src, &n_src, pv_opts)) + if (!parse_variables (default_dict, &src, &n_src, pv_opts)) goto lossage; } @@ -626,7 +612,7 @@ parse_aggregate_functions (void) if (src) { - int output_type; + int output_width; agr_next->src = src[i]; @@ -636,23 +622,19 @@ parse_aggregate_functions (void) agr_next->string = xmalloc (src[i]->width); } - if (default_dict.weight_index != -1) - agr_next->function |= FWEIGHT; - - if (agr_next->src->type == NUMERIC) - output_type = NUMERIC; + if (agr_next->src->type == NUMERIC || function->alpha_type == NUMERIC) + output_width = 0; else - output_type = function->alpha_type; + output_width = agr_next->src->width; if (function->alpha_type == ALPHA) - destvar = dup_variable (agr_dict, agr_next->src, dest[i]); + destvar = dict_clone_var (agr_dict, agr_next->src, dest[i]); else { - destvar = create_variable (agr_dict, dest[i], output_type, - agr_next->src->width); - if (output_type == NUMERIC) + destvar = dict_create_var (agr_dict, dest[i], output_width); + if (output_width == 0) destvar->print = destvar->write = function->format; - if (output_type == NUMERIC && default_dict.weight_index != -1 + if (output_width == 0 && dict_get_weight (default_dict) != NULL && (func_index == N || func_index == N_NO_VARS || func_index == NU || func_index == NU_NO_VARS)) { @@ -663,7 +645,7 @@ parse_aggregate_functions (void) } } else { agr_next->src = NULL; - destvar = create_variable (agr_dict, dest[i], NUMERIC, 0); + destvar = dict_create_var (agr_dict, dest[i], 0); } if (!destvar) @@ -678,6 +660,7 @@ parse_aggregate_functions (void) } free (dest[i]); + destvar->init = 0; if (dest_label[i]) { destvar->label = dest_label[i]; @@ -754,7 +737,7 @@ free_aggregate_functions (void) struct agr_var *iter, *next; if (agr_dict) - free_dictionary (agr_dict); + dict_destroy (agr_dict); for (iter = agr_first; iter; iter = next) { next = iter->next; @@ -775,7 +758,7 @@ free_aggregate_functions (void) /* Execution. */ -static void accumulate_aggregate_info (struct ccase *input); +static void accumulate_aggregate_info (const struct ccase *input); static void dump_aggregate_info (struct ccase *output); /* Processes a single case INPUT for aggregation. If output is @@ -785,7 +768,7 @@ static void dump_aggregate_info (struct ccase *output); /* The code in this function has an eerie similarity to vfm.c:SPLIT_FILE_procfunc()... */ static int -aggregate_single_case (struct ccase *input, struct ccase *output) +aggregate_single_case (const struct ccase *input, struct ccase *output) { /* The first case always begins a new break group. We also need to preserve the values of the case for later comparison. */ @@ -796,8 +779,8 @@ aggregate_single_case (struct ccase *input, struct ccase *output) { int i; - for (i = 0; i < nv_sort; i++) - n_elem += v_sort[i]->nv; + for (i = 0; i < sort->var_cnt; i++) + n_elem += sort->vars[i]->nv; } prev_case = xmalloc (sizeof *prev_case * n_elem); @@ -807,9 +790,9 @@ aggregate_single_case (struct ccase *input, struct ccase *output) union value *iter = prev_case; int i; - for (i = 0; i < nv_sort; i++) + for (i = 0; i < sort->var_cnt; i++) { - struct variable *v = v_sort[i]; + struct variable *v = sort->vars[i]; if (v->type == NUMERIC) (iter++)->f = input->data[v->fv].f; @@ -832,14 +815,14 @@ aggregate_single_case (struct ccase *input, struct ccase *output) union value *iter = prev_case; int i; - for (i = 0; i < nv_sort; i++) + for (i = 0; i < sort->var_cnt; i++) { - struct variable *v = v_sort[i]; + struct variable *v = sort->vars[i]; switch (v->type) { case NUMERIC: - if (approx_ne (input->data[v->fv].f, iter->f)) + if (input->data[v->fv].f != iter->f) goto not_equal; iter++; break; @@ -871,9 +854,9 @@ not_equal: union value *iter = prev_case; int i; - for (i = 0; i < nv_sort; i++) + for (i = 0; i < sort->var_cnt; i++) { - struct variable *v = v_sort[i]; + struct variable *v = sort->vars[i]; if (v->type == NUMERIC) (iter++)->f = input->data[v->fv].f; @@ -890,16 +873,17 @@ not_equal: /* Accumulates aggregation data from the case INPUT. */ static void -accumulate_aggregate_info (struct ccase *input) +accumulate_aggregate_info (const struct ccase *input) { struct agr_var *iter; + double weight; -#define WEIGHT (input->data[default_dict.weight_index].f) + weight = dict_get_case_weight (default_dict, input); for (iter = agr_first; iter; iter = iter->next) if (iter->src) { - union value *v = &input->data[iter->src->fv]; + const union value *v = &input->data[iter->src->fv]; if ((!iter->include_missing && is_missing (v, iter->src)) || (iter->include_missing && iter->src->type == NUMERIC @@ -907,12 +891,10 @@ accumulate_aggregate_info (struct ccase *input) { switch (iter->function) { - case NMISS | FWEIGHT: - iter->dbl[0] += WEIGHT; - break; case NMISS: + iter->dbl[0] += weight; + break; case NUMISS: - case NUMISS | FWEIGHT: iter->int1++; break; } @@ -924,190 +906,95 @@ accumulate_aggregate_info (struct ccase *input) switch (iter->function) { case SUM: - case SUM | FWEIGHT: iter->dbl[0] += v->f; break; case MEAN: - iter->dbl[0] += v->f; - iter->int1++; - break; - case MEAN | FWEIGHT: - { - double w = WEIGHT; - iter->dbl[0] += v->f * w; - iter->dbl[1] += w; - break; - } - case SD: - iter->dbl[0] += v->f; - iter->dbl[1] += v->f * v->f; - iter->int1++; - break; - case SD | FWEIGHT: - { - double w = WEIGHT; - double product = v->f * w; - iter->dbl[0] += product; - iter->dbl[1] += product * v->f; - iter->dbl[2] += w; - break; - } + iter->dbl[0] += v->f * weight; + iter->dbl[1] += weight; + break; + case SD: + { + double product = v->f * weight; + iter->dbl[0] += product; + iter->dbl[1] += product * v->f; + iter->dbl[2] += weight; + break; + } case MAX: - case MAX | FWEIGHT: iter->dbl[0] = max (iter->dbl[0], v->f); iter->int1 = 1; break; case MAX | FSTRING: - case MAX | FSTRING | FWEIGHT: if (memcmp (iter->string, v->s, iter->src->width) < 0) memcpy (iter->string, v->s, iter->src->width); iter->int1 = 1; break; case MIN: - case MIN | FWEIGHT: iter->dbl[0] = min (iter->dbl[0], v->f); iter->int1 = 1; break; case MIN | FSTRING: - case MIN | FSTRING | FWEIGHT: if (memcmp (iter->string, v->s, iter->src->width) > 0) memcpy (iter->string, v->s, iter->src->width); iter->int1 = 1; break; case FGT: case PGT: - if (approx_gt (v->f, iter->arg[0].f)) - iter->int1++; - iter->int2++; - break; - case FGT | FWEIGHT: - case PGT | FWEIGHT: - { - double w = WEIGHT; - if (approx_gt (v->f, iter->arg[0].f)) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (v->f > iter->arg[0].f) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FGT | FSTRING: case PGT | FSTRING: - if (memcmp (iter->arg[0].c, v->s, iter->src->width) < 0) - iter->int1++; - iter->int2++; - break; - case FGT | FSTRING | FWEIGHT: - case PGT | FSTRING | FWEIGHT: - { - double w = WEIGHT; - if (memcmp (iter->arg[0].c, v->s, iter->src->width) < 0) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (memcmp (iter->arg[0].c, v->s, iter->src->width) < 0) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FLT: case PLT: - if (approx_lt (v->f, iter->arg[0].f)) - iter->int1++; - iter->int2++; - break; - case FLT | FWEIGHT: - case PLT | FWEIGHT: - { - double w = WEIGHT; - if (approx_lt (v->f, iter->arg[0].f)) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (v->f < iter->arg[0].f) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FLT | FSTRING: case PLT | FSTRING: - if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0) - iter->int1++; - iter->int2++; - break; - case FLT | FSTRING | FWEIGHT: - case PLT | FSTRING | FWEIGHT: - { - double w = WEIGHT; - if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FIN: case PIN: - if (approx_in_range (v->f, iter->arg[0].f, iter->arg[1].f)) - iter->int1++; - iter->int2++; - break; - case FIN | FWEIGHT: - case PIN | FWEIGHT: - { - double w = WEIGHT; - if (approx_in_range (v->f, iter->arg[0].f, iter->arg[1].f)) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (iter->arg[0].f <= v->f && v->f <= iter->arg[1].f) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FIN | FSTRING: case PIN | FSTRING: - if (memcmp (iter->arg[0].c, v->s, iter->src->width) <= 0 - && memcmp (iter->arg[1].c, v->s, iter->src->width) >= 0) - iter->int1++; - iter->int2++; - break; - case FIN | FSTRING | FWEIGHT: - case PIN | FSTRING | FWEIGHT: - { - double w = WEIGHT; - if (memcmp (iter->arg[0].c, v->s, iter->src->width) <= 0 - && memcmp (iter->arg[1].c, v->s, iter->src->width) >= 0) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (memcmp (iter->arg[0].c, v->s, iter->src->width) <= 0 + && memcmp (iter->arg[1].c, v->s, iter->src->width) >= 0) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FOUT: case POUT: - if (!approx_in_range (v->f, iter->arg[0].f, iter->arg[1].f)) - iter->int1++; - iter->int2++; - break; - case FOUT | FWEIGHT: - case POUT | FWEIGHT: - { - double w = WEIGHT; - if (!approx_in_range (v->f, iter->arg[0].f, iter->arg[1].f)) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } + if (iter->arg[0].f > v->f || v->f > iter->arg[1].f) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case FOUT | FSTRING: case POUT | FSTRING: - if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0 - && memcmp (iter->arg[1].c, v->s, iter->src->width) < 0) - iter->int1++; - iter->int2++; - break; - case FOUT | FSTRING | FWEIGHT: - case POUT | FSTRING | FWEIGHT: - { - double w = WEIGHT; - if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0 - && memcmp (iter->arg[1].c, v->s, iter->src->width) < 0) - iter->dbl[0] += w; - iter->dbl[1] += w; - break; - } - case N | FWEIGHT: - iter->dbl[0] += WEIGHT; - break; + if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0 + && memcmp (iter->arg[1].c, v->s, iter->src->width) < 0) + iter->dbl[0] += weight; + iter->dbl[1] += weight; + break; case N: + iter->dbl[0] += weight; + break; case NU: - case NU | FWEIGHT: iter->int1++; break; case FIRST: - case FIRST | FWEIGHT: if (iter->int1 == 0) { iter->dbl[0] = v->f; @@ -1115,7 +1002,6 @@ accumulate_aggregate_info (struct ccase *input) } break; case FIRST | FSTRING: - case FIRST | FSTRING | FWEIGHT: if (iter->int1 == 0) { memcpy (iter->string, v->s, iter->src->width); @@ -1123,12 +1009,10 @@ accumulate_aggregate_info (struct ccase *input) } break; case LAST: - case LAST | FWEIGHT: iter->dbl[0] = v->f; iter->int1 = 1; break; case LAST | FSTRING: - case LAST | FSTRING | FWEIGHT: memcpy (iter->string, v->s, iter->src->width); iter->int1 = 1; break; @@ -1138,12 +1022,10 @@ accumulate_aggregate_info (struct ccase *input) } else { switch (iter->function) { - case N_NO_VARS | FWEIGHT: - iter->dbl[0] += WEIGHT; - break; case N_NO_VARS: + iter->dbl[0] += weight; + break; case NU_NO_VARS: - case NU_NO_VARS | FWEIGHT: iter->int1++; break; default: @@ -1166,8 +1048,8 @@ dump_aggregate_info (struct ccase *output) { int i; - for (i = 0; i < nv_sort; i++) - n_elem += v_sort[i]->nv; + for (i = 0; i < sort->var_cnt; i++) + n_elem += sort->vars[i]->nv; } debug_printf (("n_elem=%d:", n_elem)); memcpy (output->data, prev_case, sizeof (union value) * n_elem); @@ -1196,58 +1078,37 @@ dump_aggregate_info (struct ccase *output) switch (i->function) { case SUM: - case SUM | FWEIGHT: v->f = i->dbl[0]; break; case MEAN: - v->f = i->int1 ? i->dbl[0] / i->int1 : SYSMIS; - break; - case MEAN | FWEIGHT: v->f = i->dbl[1] != 0.0 ? i->dbl[0] / i->dbl[1] : SYSMIS; break; case SD: - v->f = ((i->int1 > 1) - ? calc_stddev (calc_variance (i->dbl, i->int1)) - : SYSMIS); - break; - case SD | FWEIGHT: v->f = ((i->dbl[2] > 1.0) ? calc_stddev (calc_variance (i->dbl, i->dbl[2])) : SYSMIS); break; case MAX: - case MAX | FWEIGHT: case MIN: - case MIN | FWEIGHT: v->f = i->int1 ? i->dbl[0] : SYSMIS; break; case MAX | FSTRING: - case MAX | FSTRING | FWEIGHT: case MIN | FSTRING: - case MIN | FSTRING | FWEIGHT: if (i->int1) memcpy (v->s, i->string, i->dest->width); else memset (v->s, ' ', i->dest->width); break; - case FGT: case FGT | FSTRING: - case FLT: case FLT | FSTRING: - case FIN: case FIN | FSTRING: - case FOUT: case FOUT | FSTRING: v->f = i->int2 ? (double) i->int1 / (double) i->int2 : SYSMIS; break; - case FGT | FWEIGHT: - case FGT | FSTRING | FWEIGHT: - case FLT | FWEIGHT: - case FLT | FSTRING | FWEIGHT: - case FIN | FWEIGHT: - case FIN | FSTRING | FWEIGHT: - case FOUT | FWEIGHT: - case FOUT | FSTRING | FWEIGHT: + case FGT: + case FLT: + case FIN: + case FOUT: v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] : SYSMIS; break; case PGT: @@ -1258,56 +1119,35 @@ dump_aggregate_info (struct ccase *output) case PIN | FSTRING: case POUT: case POUT | FSTRING: - v->f = (i->int2 - ? (double) i->int1 / (double) i->int2 * 100.0 - : SYSMIS); - break; - case PGT | FWEIGHT: - case PGT | FSTRING | FWEIGHT: - case PLT | FWEIGHT: - case PLT | FSTRING | FWEIGHT: - case PIN | FWEIGHT: - case PIN | FSTRING | FWEIGHT: - case POUT | FWEIGHT: - case POUT | FSTRING | FWEIGHT: v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] * 100.0 : SYSMIS; break; - case N | FWEIGHT: - v->f = i->dbl[0]; case N: + v->f = i->dbl[0]; + break; case NU: - case NU | FWEIGHT: v->f = i->int1; break; case FIRST: - case FIRST | FWEIGHT: case LAST: - case LAST | FWEIGHT: v->f = i->int1 ? i->dbl[0] : SYSMIS; break; case FIRST | FSTRING: - case FIRST | FSTRING | FWEIGHT: case LAST | FSTRING: - case LAST | FSTRING | FWEIGHT: if (i->int1) memcpy (v->s, i->string, i->dest->width); else memset (v->s, ' ', i->dest->width); break; - case N_NO_VARS | FWEIGHT: + case N_NO_VARS: v->f = i->dbl[0]; break; - case N_NO_VARS: case NU_NO_VARS: - case NU_NO_VARS | FWEIGHT: v->f = i->int1; break; - case NMISS | FWEIGHT: + case NMISS: v->f = i->dbl[0]; break; - case NMISS: case NUMISS: - case NUMISS | FWEIGHT: v->f = i->int1; break; default: @@ -1326,10 +1166,8 @@ initialize_aggregate_info (void) for (iter = agr_first; iter; iter = iter->next) { - int plain_function = iter->function & ~FWEIGHT; - iter->missing = 0; - switch (plain_function) + switch (iter->function) { case MIN: iter->dbl[0] = DBL_MAX; @@ -1354,7 +1192,8 @@ initialize_aggregate_info (void) /* Aggregate each case as it comes through. Cases which aren't needed are dropped. */ static int -agr_00x_trns_proc (struct trns_header *h unused, struct ccase *c) +agr_00x_trns_proc (struct trns_header *h UNUSED, struct ccase *c, + int case_num UNUSED) { int code = aggregate_single_case (c, compaction_case); debug_printf (("%d ", code)); @@ -1366,13 +1205,12 @@ agr_00x_trns_proc (struct trns_header *h unused, struct ccase *c) the cases have been output; very little has been cleaned up at this point. */ static void -agr_00x_end_func (void) +agr_00x_end_func (void *aux UNUSED) { /* Ensure that info for the last break group gets written to the active file. */ dump_aggregate_info (compaction_case); - vfm_sink_info.ncases++; - vfm_sink->write (); + vfm_sink->class->write (vfm_sink, compaction_case); } /* Transform the aggregate case buf_1xx, in internal format, to system @@ -1384,9 +1222,9 @@ write_case_to_sfm (void) flt64 *p = buf64_1xx; int i; - for (i = 0; i < agr_dict->nvar; i++) + for (i = 0; i < dict_get_var_cnt (agr_dict); i++) { - struct variable *v = agr_dict->var[i]; + struct variable *v = dict_get_var (agr_dict, i); if (v->type == NUMERIC) { @@ -1411,7 +1249,8 @@ write_case_to_sfm (void) /* Aggregate the current case and output it if we passed a breakpoint. */ static int -agr_10x_trns_proc (struct trns_header *h unused, struct ccase *c) +agr_10x_trns_proc (struct trns_header *h UNUSED, struct ccase *c, + int case_num UNUSED) { int code = aggregate_single_case (c, buf_1xx); @@ -1423,7 +1262,7 @@ agr_10x_trns_proc (struct trns_header *h unused, struct ccase *c) /* Close the system file now that we're done with it. */ static void -agr_10x_trns_free (struct trns_header *h unused) +agr_10x_trns_free (struct trns_header *h UNUSED) { fh_close_handle (outfile); } @@ -1431,37 +1270,36 @@ agr_10x_trns_free (struct trns_header *h unused) /* Ensure that info for the last break group gets written to the system file. */ static void -agr_10x_end_func (void) +agr_10x_end_func (void *aux UNUSED) { dump_aggregate_info (buf_1xx); write_case_to_sfm (); } -/* When called with temp_case non-NULL (the normal case), runs the - case through the aggregater and outputs it to the system file if - appropriate. If temp_case is NULL, finishes up writing the last - case if necessary. */ +/* Runs case C through the aggregater and outputs it to the + system file if appropriate. */ static int -agr_11x_func (void) +agr_11x_read (const struct ccase *c, void *aux UNUSED) { - if (temp_case != NULL) - { - int code = aggregate_single_case (temp_case, buf_1xx); + int code = aggregate_single_case (c, buf_1xx); - assert (code == -2 || code == -1); - if (code == -1) - write_case_to_sfm (); - } - else + assert (code == -2 || code == -1); + if (code == -1) + write_case_to_sfm (); + + return 1; +} + +/* Finishes up writing the last case if necessary. */ +static void +agr_11x_finish (void) +{ + if (case_count) { - if (case_count) - { - dump_aggregate_info (buf_1xx); - write_case_to_sfm (); - } - fh_close_handle (outfile); + dump_aggregate_info (buf_1xx); + write_case_to_sfm (); } - return 1; + fh_close_handle (outfile); } /* Debugging. */ @@ -1485,9 +1323,9 @@ debug_print (int flags) int i; printf (" /BREAK="); - for (i = 0; i < nv_sort; i++) - printf ("%s(%c) ", v_sort[i]->name, - v_sort[i]->p.srt.order == SRT_ASCEND ? 'A' : 'D'); + for (i = 0; i < sort->var_cnt; i++) + printf ("%s(%c) ", sort->vars[i]->name, + sort->vars[i]->p.srt.order == SRT_ASCEND ? 'A' : 'D'); putc ('\n', stdout); }