#include <assert.h>
#include <stdlib.h>
#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"
#include "vfm.h"
#include "vfmP.h"
-#undef DEBUGGING
-/*#define DEBUGGING 1*/
#include "debug-print.h"
/* Specifies how to make an aggregate variable. */
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. */
};
/* Attributes of aggregation functions. */
-static struct agr_func agr_func_tab[] =
+static const struct agr_func agr_func_tab[] =
{
{"<NONE>", 0, -1, {0, 0, 0}},
{"SUM", 0, -1, {FMT_F, 8, 2}},
/* ITEMWISE or COLUMNWISE. */
static int missing;
+/* Sort program. */
+static struct sort_cases_pgm *sort;
+
/* Aggregate variables. */
static struct agr_var *agr_first, *agr_next;
/* 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);
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");
{
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;
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;
}
}
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;
}
{
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);
}
}
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);
if (outfile != NULL)
type |= 4;
- if (nv_sort != 0 && (seen & 4) == 0)
+ if (sort != NULL && (seen & 4) == 0)
type |= 2;
if (temporary)
type |= 1;
cancel_temporary ();
/* fall through */
case 2:
- sort_cases (0);
+ sort_cases (sort, 0);
goto case0;
case 1:
agr_dict = NULL;
- procedure (NULL, NULL, agr_00x_end_func);
+ procedure (NULL, NULL, agr_00x_end_func, NULL);
break;
}
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:
free (buf_1xx);
/* Clean up. */
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
free_aggregate_functions ();
free (prev_case);
lossage:
/* Clean up. */
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
free_aggregate_functions ();
free (prev_case);
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;
}
{
agr_first = agr_next = NULL;
- /* Anticipate weighting for optimization later. */
- update_weighting (&default_dict);
-
/* Parse everything. */
for (;;)
{
int n_dest;
int include_missing;
- struct agr_func *function;
+ const struct agr_func *function;
int func_index;
union value arg[2];
dest_label = NULL;
n_dest = 0;
src = NULL;
+ function = NULL;
n_src = 0;
arg[0].c = NULL;
arg[1].c = NULL;
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;
}
if (src)
{
- int output_type;
+ int output_width;
agr_next->src = src[i];
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))
{
}
} 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)
}
free (dest[i]);
+ destvar->init = 0;
if (dest_label[i])
{
destvar->label = dest_label[i];
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;
\f
/* 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
/* 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. */
{
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);
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;
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;
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;
/* 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
{
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;
}
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;
}
break;
case FIRST | FSTRING:
- case FIRST | FSTRING | FWEIGHT:
if (iter->int1 == 0)
{
memcpy (iter->string, v->s, iter->src->width);
}
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;
} 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:
{
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);
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:
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:
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;
/* 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));
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
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)
{
/* 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);
/* 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);
}
/* 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);
}
\f
/* Debugging. */
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);
}