#include "file-handle.h"
#include "lexer.h"
#include "misc.h"
+#include "pool.h"
#include "settings.h"
#include "sfm.h"
#include "sort.h"
};
/* 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;
static int create_sysfile (void);
static int agr_00x_trns_proc (struct trns_header *, struct ccase *);
-static void agr_00x_end_func (void);
+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 void agr_10x_end_func (void *);
+static int agr_11x_func (write_case_data);
#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 = dict_create ();
{
if (seen & 1)
{
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
dict_destroy (agr_dict);
- msg (SE, _("OUTFILE specified multiple times."));
+ msg (SE, _("%s subcommand given multiple times."),"OUTFILE");
return CMD_FAILURE;
}
seen |= 1;
outfile = fh_parse_file_handle ();
if (outfile == NULL)
{
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
dict_destroy (agr_dict);
return CMD_FAILURE;
}
lex_match ('=');
if (!lex_match_id ("COLUMNWISE"))
{
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
dict_destroy (agr_dict);
lex_error (_("while expecting COLUMNWISE"));
return CMD_FAILURE;
{
if (seen & 8)
{
- free (v_sort);
+ destroy_sort_cases_pgm (sort);
dict_destroy (agr_dict);
- msg (SE, _("BREAK specified multiple times."));
+ 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)
{
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 = dict_clone_var (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;
}
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);
+ sort_cases (sort, 1);
if (!create_sysfile ())
goto lossage;
- read_sort_output (agr_11x_func);
+ read_sort_output (sort, agr_11x_func, NULL);
{
struct ccase *save_temp_case = temp_case;
temp_case = NULL;
- agr_11x_func ();
+ agr_11x_func (NULL);
temp_case = save_temp_case;
}
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);
+ 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)
- * (dict_get_value_cnt (agr_dict) - 1)));
+ buf_1xx = xmalloc (dict_get_case_size (agr_dict));
return 1;
}
int n_dest;
int include_missing;
- struct agr_func *function;
+ const struct agr_func *function;
int func_index;
union value arg[2];
}
free (dest[i]);
+ destvar->init = 0;
if (dest_label[i])
{
destvar->label = dest_label[i];
{
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)
{
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;
{
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);
/* 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 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, temp_case);
}
/* Transform the aggregate case buf_1xx, in internal format, to system
/* 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 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 ();
appropriate. If temp_case is NULL, finishes up writing the last
case if necessary. */
static int
-agr_11x_func (void)
+agr_11x_func (write_case_data wc_data UNUSED)
{
if (temp_case != NULL)
{
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);
}