projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Eliminate temp_case, and a few other cleanups.
[pspp]
/
src
/
aggregate.c
diff --git
a/src/aggregate.c
b/src/aggregate.c
index dbfad40f6d4b2b79b938b6a83ed3c771bfa49b8d..4d00a34ad2cbb7404548762a0096f94b22f9e409 100644
(file)
--- a/
src/aggregate.c
+++ b/
src/aggregate.c
@@
-26,6
+26,7
@@
#include "file-handle.h"
#include "lexer.h"
#include "misc.h"
#include "file-handle.h"
#include "lexer.h"
#include "misc.h"
+#include "pool.h"
#include "settings.h"
#include "sfm.h"
#include "sort.h"
#include "settings.h"
#include "sfm.h"
#include "sort.h"
@@
-76,7
+77,7
@@
struct agr_func
};
/* Attributes of aggregation functions. */
};
/* 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}},
{
{"<NONE>", 0, -1, {0, 0, 0}},
{"SUM", 0, -1, {FMT_F, 8, 2}},
@@
-116,6
+117,9
@@
enum
/* ITEMWISE or COLUMNWISE. */
static int missing;
/* ITEMWISE or COLUMNWISE. */
static int missing;
+/* Sort program. */
+static struct sort_cases_pgm *sort;
+
/* Aggregate variables. */
static struct agr_var *agr_first, *agr_next;
/* Aggregate variables. */
static struct agr_var *agr_first, *agr_next;
@@
-137,15
+141,16
@@
static void initialize_aggregate_info (void);
/* Prototypes. */
static int parse_aggregate_functions (void);
static void free_aggregate_functions (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 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 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 void agr_10x_end_func (void *);
-static int agr_11x_func (write_case_data);
+static read_sort_output_func agr_11x_read;
+static void agr_11x_finish (void);
#if DEBUGGING
static void debug_print (int flags);
#if DEBUGGING
static void debug_print (int flags);
@@
-157,15
+162,12
@@
static void debug_print (int flags);
int
cmd_aggregate (void)
{
int
cmd_aggregate (void)
{
- /* From sort.c. */
- int parse_sort_variables (void);
-
/* Have we seen these subcommands? */
unsigned seen = 0;
outfile = NULL;
missing = ITEMWISE;
/* Have we seen these subcommands? */
unsigned seen = 0;
outfile = NULL;
missing = ITEMWISE;
-
v_
sort = NULL;
+ sort = NULL;
prev_case = NULL;
agr_dict = dict_create ();
prev_case = NULL;
agr_dict = dict_create ();
@@
-183,7
+185,7
@@
cmd_aggregate (void)
{
if (seen & 1)
{
{
if (seen & 1)
{
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
dict_destroy (agr_dict);
msg (SE, _("%s subcommand given multiple times."),"OUTFILE");
return CMD_FAILURE;
dict_destroy (agr_dict);
msg (SE, _("%s subcommand given multiple times."),"OUTFILE");
return CMD_FAILURE;
@@
-198,7
+200,7
@@
cmd_aggregate (void)
outfile = fh_parse_file_handle ();
if (outfile == NULL)
{
outfile = fh_parse_file_handle ();
if (outfile == NULL)
{
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
dict_destroy (agr_dict);
return CMD_FAILURE;
}
dict_destroy (agr_dict);
return CMD_FAILURE;
}
@@
-209,7
+211,7
@@
cmd_aggregate (void)
lex_match ('=');
if (!lex_match_id ("COLUMNWISE"))
{
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;
dict_destroy (agr_dict);
lex_error (_("while expecting COLUMNWISE"));
return CMD_FAILURE;
@@
-224,7
+226,7
@@
cmd_aggregate (void)
{
if (seen & 8)
{
{
if (seen & 8)
{
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
dict_destroy (agr_dict);
msg (SE, _("%s subcommand given multiple times."),"BREAK");
return CMD_FAILURE;
dict_destroy (agr_dict);
msg (SE, _("%s subcommand given multiple times."),"BREAK");
return CMD_FAILURE;
@@
-232,7
+234,8
@@
cmd_aggregate (void)
seen |= 8;
lex_match ('=');
seen |= 8;
lex_match ('=');
- if (!parse_sort_variables ())
+ sort = parse_sort ();
+ if (sort == NULL)
{
dict_destroy (agr_dict);
return CMD_FAILURE;
{
dict_destroy (agr_dict);
return CMD_FAILURE;
@@
-241,11
+244,11
@@
cmd_aggregate (void)
{
int i;
{
int i;
- for (i = 0; i <
nv_sor
t; i++)
+ for (i = 0; i <
sort->var_cn
t; i++)
{
struct variable *v;
{
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);
}
}
assert (v != NULL);
}
}
@@
-261,7
+264,7
@@
cmd_aggregate (void)
if (!parse_aggregate_functions ())
{
free_aggregate_functions ();
if (!parse_aggregate_functions ())
{
free_aggregate_functions ();
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
return CMD_FAILURE;
}
return CMD_FAILURE;
}
@@
-312,7
+315,7
@@
cmd_aggregate (void)
if (outfile != NULL)
type |= 4;
if (outfile != NULL)
type |= 4;
- if (
nv_sort != 0
&& (seen & 4) == 0)
+ if (
sort != NULL
&& (seen & 4) == 0)
type |= 2;
if (temporary)
type |= 1;
type |= 2;
if (temporary)
type |= 1;
@@
-323,7
+326,7
@@
cmd_aggregate (void)
cancel_temporary ();
/* fall through */
case 2:
cancel_temporary ();
/* fall through */
case 2:
- sort_cases (0);
+ sort_cases (
sort,
0);
goto case0;
case 1:
goto case0;
case 1:
@@
-366,20
+369,14
@@
cmd_aggregate (void)
}
case 6:
}
case 6:
- case 7:
- sort_cases (1);
+ case 7:
+ sort_cases (
sort,
1);
if (!create_sysfile ())
goto lossage;
if (!create_sysfile ())
goto lossage;
- read_sort_output (agr_11x_func, NULL);
-
- {
- struct ccase *save_temp_case = temp_case;
- temp_case = NULL;
- agr_11x_func (NULL);
- temp_case = save_temp_case;
- }
-
+ read_sort_output (sort, agr_11x_read, NULL);
+ agr_11x_finish ();
+
break;
default:
break;
default:
@@
-391,7
+388,7
@@
cmd_aggregate (void)
free (buf_1xx);
/* Clean up. */
free (buf_1xx);
/* Clean up. */
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
free_aggregate_functions ();
free (prev_case);
free_aggregate_functions ();
free (prev_case);
@@
-399,7
+396,7
@@
cmd_aggregate (void)
lossage:
/* Clean up. */
lossage:
/* Clean up. */
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
free_aggregate_functions ();
free (prev_case);
free_aggregate_functions ();
free (prev_case);
@@
-418,7
+415,7
@@
create_sysfile (void)
if (!sfm_write_dictionary (&w))
{
free_aggregate_functions ();
if (!sfm_write_dictionary (&w))
{
free_aggregate_functions ();
-
free (v_
sort);
+
destroy_sort_cases_pgm (
sort);
dict_destroy (agr_dict);
return 0;
}
dict_destroy (agr_dict);
return 0;
}
@@
-443,7
+440,7
@@
parse_aggregate_functions (void)
int n_dest;
int include_missing;
int n_dest;
int include_missing;
- struct agr_func *function;
+
const
struct agr_func *function;
int func_index;
union value arg[2];
int func_index;
union value arg[2];
@@
-457,6
+454,7
@@
parse_aggregate_functions (void)
dest_label = NULL;
n_dest = 0;
src = NULL;
dest_label = NULL;
n_dest = 0;
src = NULL;
+ function = NULL;
n_src = 0;
arg[0].c = NULL;
arg[1].c = NULL;
n_src = 0;
arg[0].c = NULL;
arg[1].c = NULL;
@@
-760,7
+758,7
@@
free_aggregate_functions (void)
\f
/* Execution. */
\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
static void dump_aggregate_info (struct ccase *output);
/* Processes a single case INPUT for aggregation. If output is
@@
-770,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
/* 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. */
{
/* The first case always begins a new break group. We also need to
preserve the values of the case for later comparison. */
@@
-781,8
+779,8
@@
aggregate_single_case (struct ccase *input, struct ccase *output)
{
int i;
{
int i;
- for (i = 0; i <
nv_sor
t; i++)
- n_elem +=
v_sort
[i]->nv;
+ for (i = 0; i <
sort->var_cn
t; i++)
+ n_elem +=
sort->vars
[i]->nv;
}
prev_case = xmalloc (sizeof *prev_case * n_elem);
}
prev_case = xmalloc (sizeof *prev_case * n_elem);
@@
-792,9
+790,9
@@
aggregate_single_case (struct ccase *input, struct ccase *output)
union value *iter = prev_case;
int i;
union value *iter = prev_case;
int i;
- for (i = 0; i <
nv_sor
t; i++)
+ for (i = 0; i <
sort->var_cn
t; i++)
{
{
- struct variable *v =
v_sort
[i];
+ struct variable *v =
sort->vars
[i];
if (v->type == NUMERIC)
(iter++)->f = input->data[v->fv].f;
if (v->type == NUMERIC)
(iter++)->f = input->data[v->fv].f;
@@
-817,9
+815,9
@@
aggregate_single_case (struct ccase *input, struct ccase *output)
union value *iter = prev_case;
int i;
union value *iter = prev_case;
int i;
- for (i = 0; i <
nv_sor
t; i++)
+ for (i = 0; i <
sort->var_cn
t; i++)
{
{
- struct variable *v =
v_sort
[i];
+ struct variable *v =
sort->vars
[i];
switch (v->type)
{
switch (v->type)
{
@@
-856,9
+854,9
@@
not_equal:
union value *iter = prev_case;
int i;
union value *iter = prev_case;
int i;
- for (i = 0; i <
nv_sor
t; i++)
+ for (i = 0; i <
sort->var_cn
t; i++)
{
{
- struct variable *v =
v_sort
[i];
+ struct variable *v =
sort->vars
[i];
if (v->type == NUMERIC)
(iter++)->f = input->data[v->fv].f;
if (v->type == NUMERIC)
(iter++)->f = input->data[v->fv].f;
@@
-875,7
+873,7
@@
not_equal:
/* Accumulates aggregation data from the case INPUT. */
static void
/* 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;
{
struct agr_var *iter;
double weight;
@@
-885,7
+883,7
@@
accumulate_aggregate_info (struct ccase *input)
for (iter = agr_first; iter; iter = iter->next)
if (iter->src)
{
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
if ((!iter->include_missing && is_missing (v, iter->src))
|| (iter->include_missing && iter->src->type == NUMERIC
@@
-1050,8
+1048,8
@@
dump_aggregate_info (struct ccase *output)
{
int i;
{
int i;
- for (i = 0; i <
nv_sor
t; i++)
- n_elem +=
v_sort
[i]->nv;
+ for (i = 0; i <
sort->var_cn
t; i++)
+ n_elem +=
sort->vars
[i]->nv;
}
debug_printf (("n_elem=%d:", n_elem));
memcpy (output->data, prev_case, sizeof (union value) * n_elem);
}
debug_printf (("n_elem=%d:", n_elem));
memcpy (output->data, prev_case, sizeof (union value) * n_elem);
@@
-1194,7
+1192,8
@@
initialize_aggregate_info (void)
/* Aggregate each case as it comes through. Cases which aren't needed
are dropped. */
static int
/* 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));
{
int code = aggregate_single_case (c, compaction_case);
debug_printf (("%d ", code));
@@
-1211,8
+1210,7
@@
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);
/* 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
}
/* Transform the aggregate case buf_1xx, in internal format, to system
@@
-1251,7
+1249,8
@@
write_case_to_sfm (void)
/* Aggregate the current case and output it if we passed a
breakpoint. */
static int
/* 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);
{
int code = aggregate_single_case (c, buf_1xx);
@@
-1277,31
+1276,30
@@
agr_10x_end_func (void *aux UNUSED)
write_case_to_sfm ();
}
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
static int
-agr_11x_
func (write_case_data wc_data
UNUSED)
+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. */
}
\f
/* Debugging. */
@@
-1325,9
+1323,9
@@
debug_print (int flags)
int i;
printf (" /BREAK=");
int i;
printf (" /BREAK=");
- for (i = 0; i <
nv_sor
t; i++)
- printf ("%s(%c) ",
v_sort
[i]->name,
-
v_sort
[i]->p.srt.order == SRT_ASCEND ? 'A' : 'D');
+ for (i = 0; i <
sort->var_cn
t; i++)
+ printf ("%s(%c) ",
sort->vars
[i]->name,
+
sort->vars
[i]->p.srt.order == SRT_ASCEND ? 'A' : 'D');
putc ('\n', stdout);
}
putc ('\n', stdout);
}