projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Encapsulated lexer and updated calling functions accordingly.
[pspp]
/
src
/
language
/
stats
/
aggregate.c
diff --git
a/src/language/stats/aggregate.c
b/src/language/stats/aggregate.c
index 788b19b01097df7adbf117998320294deacf95e8..031a84f8657d59cd4ba2b16143f4ff2e1e92d399 100644
(file)
--- a/
src/language/stats/aggregate.c
+++ b/
src/language/stats/aggregate.c
@@
-1,5
+1,5
@@
/* PSPP - computes sample statistics.
/* PSPP - computes sample statistics.
- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000
, 2006
Free Software Foundation, Inc.
Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
@@
-146,6
+146,7
@@
struct agr_proc
enum missing_treatment missing; /* How to treat missing values. */
struct agr_var *agr_vars; /* First aggregate variable. */
struct dictionary *dict; /* Aggregate dictionary. */
enum missing_treatment missing; /* How to treat missing values. */
struct agr_var *agr_vars; /* First aggregate variable. */
struct dictionary *dict; /* Aggregate dictionary. */
+ const struct dictionary *src_dict; /* Dict of the source */
int case_cnt; /* Counts aggregated cases. */
struct ccase agr_case; /* Aggregate case for output. */
};
int case_cnt; /* Counts aggregated cases. */
struct ccase agr_case; /* Aggregate case for output. */
};
@@
-154,25
+155,27
@@
static void initialize_aggregate_info (struct agr_proc *,
const struct ccase *);
/* Prototypes. */
const struct ccase *);
/* Prototypes. */
-static bool parse_aggregate_functions (struct agr_proc *);
+static bool parse_aggregate_functions (struct lexer *, const struct dictionary *,
+ struct agr_proc *);
static void agr_destroy (struct agr_proc *);
static bool aggregate_single_case (struct agr_proc *agr,
static void agr_destroy (struct agr_proc *);
static bool aggregate_single_case (struct agr_proc *agr,
- const struct ccase *input,
- struct ccase *output);
+ const struct ccase *input,
+ struct ccase *output);
static void dump_aggregate_info (struct agr_proc *agr, struct ccase *output);
/* Aggregating to the active file. */
static void dump_aggregate_info (struct agr_proc *agr, struct ccase *output);
/* Aggregating to the active file. */
-static bool agr_to_active_file (const struct ccase *, void *aux);
+static bool agr_to_active_file (const struct ccase *, void *aux
, const struct dataset *
);
/* Aggregating to a system file. */
/* Aggregating to a system file. */
-static bool presorted_agr_to_sysfile (const struct ccase *, void *aux);
+static bool presorted_agr_to_sysfile (const struct ccase *, void *aux
, const struct dataset *
);
\f
/* Parsing. */
/* Parses and executes the AGGREGATE procedure. */
int
\f
/* Parsing. */
/* Parses and executes the AGGREGATE procedure. */
int
-cmd_aggregate (
void
)
+cmd_aggregate (
struct lexer *lexer, struct dataset *ds
)
{
{
+ struct dictionary *dict = dataset_dict (ds);
struct agr_proc agr;
struct file_handle *out_file = NULL;
struct agr_proc agr;
struct file_handle *out_file = NULL;
@@
-185,16
+188,17
@@
cmd_aggregate (void)
case_nullify (&agr.break_case);
agr.dict = dict_create ();
case_nullify (&agr.break_case);
agr.dict = dict_create ();
- dict_set_label (agr.dict, dict_get_label (default_dict));
- dict_set_documents (agr.dict, dict_get_documents (default_dict));
+ agr.src_dict = dict;
+ dict_set_label (agr.dict, dict_get_label (dict));
+ dict_set_documents (agr.dict, dict_get_documents (dict));
/* OUTFILE subcommand must be first. */
/* OUTFILE subcommand must be first. */
- if (!lex_force_match_id ("OUTFILE"))
+ if (!lex_force_match_id (
lexer,
"OUTFILE"))
goto error;
goto error;
- lex_match ('=');
- if (!lex_match ('*'))
+ lex_match (
lexer,
'=');
+ if (!lex_match (
lexer,
'*'))
{
{
- out_file = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+ out_file = fh_parse (
lexer,
FH_REF_FILE | FH_REF_SCRATCH);
if (out_file == NULL)
goto error;
}
if (out_file == NULL)
goto error;
}
@@
-202,28
+206,28
@@
cmd_aggregate (void)
/* Read most of the subcommands. */
for (;;)
{
/* Read most of the subcommands. */
for (;;)
{
- lex_match ('/');
+ lex_match (
lexer,
'/');
- if (lex_match_id ("MISSING"))
+ if (lex_match_id (
lexer,
"MISSING"))
{
{
- lex_match ('=');
- if (!lex_match_id ("COLUMNWISE"))
+ lex_match (
lexer,
'=');
+ if (!lex_match_id (
lexer,
"COLUMNWISE"))
{
{
- lex_error (_("while expecting COLUMNWISE"));
+ lex_error (
lexer,
_("while expecting COLUMNWISE"));
goto error;
}
agr.missing = COLUMNWISE;
}
goto error;
}
agr.missing = COLUMNWISE;
}
- else if (lex_match_id ("DOCUMENT"))
+ else if (lex_match_id (
lexer,
"DOCUMENT"))
copy_documents = true;
copy_documents = true;
- else if (lex_match_id ("PRESORTED"))
+ else if (lex_match_id (
lexer,
"PRESORTED"))
presorted = true;
presorted = true;
- else if (lex_match_id ("BREAK"))
+ else if (lex_match_id (
lexer,
"BREAK"))
{
int i;
{
int i;
- lex_match ('=');
- agr.sort = sort_parse_criteria (
default_
dict,
+ lex_match (
lexer,
'=');
+ agr.sort = sort_parse_criteria (
lexer,
dict,
&agr.break_vars, &agr.break_var_cnt,
&saw_direction, NULL);
if (agr.sort == NULL)
&agr.break_vars, &agr.break_var_cnt,
&saw_direction, NULL);
if (agr.sort == NULL)
@@
-238,7
+242,7
@@
cmd_aggregate (void)
}
else
{
}
else
{
- lex_error (_("expecting BREAK"));
+ lex_error (
lexer,
_("expecting BREAK"));
goto error;
}
}
goto error;
}
}
@@
-248,8
+252,8
@@
cmd_aggregate (void)
"the same way as the input data."));
/* Read in the aggregate functions. */
"the same way as the input data."));
/* Read in the aggregate functions. */
- lex_match ('/');
- if (!parse_aggregate_functions (&agr))
+ lex_match (
lexer,
'/');
+ if (!parse_aggregate_functions (
lexer, dict,
&agr))
goto error;
/* Delete documents. */
goto error;
/* Delete documents. */
@@
-268,19
+272,21
@@
cmd_aggregate (void)
{
/* The active file will be replaced by the aggregated data,
so TEMPORARY is moot. */
{
/* The active file will be replaced by the aggregated data,
so TEMPORARY is moot. */
- proc_cancel_temporary_transformations ();
+ proc_cancel_temporary_transformations (
ds
);
if (agr.sort != NULL && !presorted)
{
if (agr.sort != NULL && !presorted)
{
- if (!sort_active_file_in_place (agr.sort))
+ if (!sort_active_file_in_place (
ds,
agr.sort))
goto error;
}
agr.sink = create_case_sink (&storage_sink_class, agr.dict, NULL);
if (agr.sink->class->open != NULL)
agr.sink->class->open (agr.sink);
goto error;
}
agr.sink = create_case_sink (&storage_sink_class, agr.dict, NULL);
if (agr.sink->class->open != NULL)
agr.sink->class->open (agr.sink);
- proc_set_sink (create_case_sink (&null_sink_class, default_dict, NULL));
- if (!procedure (agr_to_active_file, &agr))
+ proc_set_sink (ds,
+ create_case_sink (&null_sink_class,
+ dict, NULL));
+ if (!procedure (ds, agr_to_active_file, &agr))
goto error;
if (agr.case_cnt > 0)
{
goto error;
if (agr.case_cnt > 0)
{
@@
-288,11
+294,12
@@
cmd_aggregate (void)
if (!agr.sink->class->write (agr.sink, &agr.agr_case))
goto error;
}
if (!agr.sink->class->write (agr.sink, &agr.agr_case))
goto error;
}
- discard_variables ();
- dict_destroy (d
efault_d
ict);
- d
efault_dict = agr.dict
;
+ discard_variables (
ds
);
+ dict_destroy (dict);
+ d
ataset_set_dict (ds, agr.dict)
;
agr.dict = NULL;
agr.dict = NULL;
- proc_set_source (agr.sink->class->make_source (agr.sink));
+ proc_set_source (ds,
+ agr.sink->class->make_source (agr.sink));
free_case_sink (agr.sink);
}
else
free_case_sink (agr.sink);
}
else
@@
-309,7
+316,7
@@
cmd_aggregate (void)
struct ccase c;
bool ok = true;
struct ccase c;
bool ok = true;
- dst = sort_active_file_to_casefile (agr.sort);
+ dst = sort_active_file_to_casefile (
ds,
agr.sort);
if (dst == NULL)
goto error;
reader = casefile_get_destructive_reader (dst);
if (dst == NULL)
goto error;
reader = casefile_get_destructive_reader (dst);
@@
-329,7
+336,7
@@
cmd_aggregate (void)
else
{
/* Active file is already sorted. */
else
{
/* Active file is already sorted. */
- if (!procedure (presorted_agr_to_sysfile, &agr))
+ if (!procedure (
ds,
presorted_agr_to_sysfile, &agr))
goto error;
}
goto error;
}
@@
-352,7
+359,7
@@
error:
/* Parse all the aggregate functions. */
static bool
/* Parse all the aggregate functions. */
static bool
-parse_aggregate_functions (struct agr_proc *agr)
+parse_aggregate_functions (struct
lexer *lexer, const struct dictionary *dict, struct
agr_proc *agr)
{
struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
{
struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
@@
-363,6
+370,7
@@
parse_aggregate_functions (struct agr_proc *agr)
char **dest;
char **dest_label;
size_t n_dest;
char **dest;
char **dest_label;
size_t n_dest;
+ struct string function_name;
int include_missing;
const struct agr_func *function;
int include_missing;
const struct agr_func *function;
@@
-385,11
+393,11
@@
parse_aggregate_functions (struct agr_proc *agr)
arg[1].c = NULL;
/* Parse the list of target variables. */
arg[1].c = NULL;
/* Parse the list of target variables. */
- while (!lex_match ('='))
+ while (!lex_match (
lexer,
'='))
{
size_t n_dest_prev = n_dest;
{
size_t n_dest_prev = n_dest;
- if (!parse_DATA_LIST_vars (&dest, &n_dest,
+ if (!parse_DATA_LIST_vars (
lexer,
&dest, &n_dest,
PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
goto error;
PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
goto error;
@@
-401,42
+409,52
@@
parse_aggregate_functions (struct agr_proc *agr)
for (j = n_dest_prev; j < n_dest; j++)
dest_label[j] = NULL;
}
for (j = n_dest_prev; j < n_dest; j++)
dest_label[j] = NULL;
}
+
+
- if (
token
== T_STRING)
+ if (
lex_token (lexer)
== T_STRING)
{
{
- ds_truncate (&tokstr, 255);
- dest_label[n_dest - 1] = ds_xstrdup (&tokstr);
- lex_get ();
+ struct string label;
+ ds_init_string (&label, lex_tokstr (lexer));
+
+ ds_truncate (&label, 255);
+ dest_label[n_dest - 1] = ds_xstrdup (&label);
+ lex_get (lexer);
+ ds_destroy (&label);
}
}
/* Get the name of the aggregation function. */
}
}
/* Get the name of the aggregation function. */
- if (
token
!= T_ID)
+ if (
lex_token (lexer)
!= T_ID)
{
{
- lex_error (_("expecting aggregation function"));
+ lex_error (
lexer,
_("expecting aggregation function"));
goto error;
}
include_missing = 0;
goto error;
}
include_missing = 0;
- if (tokid[strlen (tokid) - 1] == '.')
- {
+
+ ds_init_string (&function_name, lex_tokstr (lexer));
+
+ ds_chomp (&function_name, '.');
+
+ if (lex_tokid(lexer)[strlen (lex_tokid (lexer)) - 1] == '.')
include_missing = 1;
include_missing = 1;
- tokid[strlen (tokid) - 1] = 0;
- }
-
+
for (function = agr_func_tab; function->name; function++)
for (function = agr_func_tab; function->name; function++)
- if (!strcasecmp (function->name,
tokid
))
+ if (!strcasecmp (function->name,
ds_cstr (&function_name)
))
break;
if (NULL == function->name)
{
break;
if (NULL == function->name)
{
- msg (SE, _("Unknown aggregation function %s."), tokid);
+ msg (SE, _("Unknown aggregation function %s."),
+ ds_cstr (&function_name));
goto error;
}
goto error;
}
+ ds_destroy (&function_name);
func_index = function - agr_func_tab;
func_index = function - agr_func_tab;
- lex_get ();
+ lex_get (
lexer
);
/* Check for leading lparen. */
/* Check for leading lparen. */
- if (!lex_match ('('))
+ if (!lex_match (
lexer,
'('))
{
if (func_index == N)
func_index = N_NO_VARS;
{
if (func_index == N)
func_index = N_NO_VARS;
@@
-444,7
+462,7
@@
parse_aggregate_functions (struct agr_proc *agr)
func_index = NU_NO_VARS;
else
{
func_index = NU_NO_VARS;
else
{
- lex_error (_("expecting `('"));
+ lex_error (
lexer,
_("expecting `('"));
goto error;
}
}
goto error;
}
}
@@
-459,7
+477,7
@@
parse_aggregate_functions (struct agr_proc *agr)
else if (function->n_args)
pv_opts |= PV_SAME_TYPE;
else if (function->n_args)
pv_opts |= PV_SAME_TYPE;
- if (!parse_variables (
default_
dict, &src, &n_src, pv_opts))
+ if (!parse_variables (
lexer,
dict, &src, &n_src, pv_opts))
goto error;
}
goto error;
}
@@
-470,15
+488,15
@@
parse_aggregate_functions (struct agr_proc *agr)
{
int type;
{
int type;
- lex_match (',');
- if (
token
== T_STRING)
+ lex_match (
lexer,
',');
+ if (
lex_token (lexer)
== T_STRING)
{
{
- arg[i].c = ds_xstrdup (
&tokstr
);
+ arg[i].c = ds_xstrdup (
lex_tokstr (lexer)
);
type = ALPHA;
}
type = ALPHA;
}
- else if (lex_is_number ())
+ else if (lex_is_number (
lexer
))
{
{
- arg[i].f =
tokval
;
+ arg[i].f =
lex_tokval (lexer)
;
type = NUMERIC;
} else {
msg (SE, _("Missing argument %d to %s."), i + 1,
type = NUMERIC;
} else {
msg (SE, _("Missing argument %d to %s."), i + 1,
@@
-486,7
+504,7
@@
parse_aggregate_functions (struct agr_proc *agr)
goto error;
}
goto error;
}
- lex_get ();
+ lex_get (
lexer
);
if (type != src[0]->type)
{
if (type != src[0]->type)
{
@@
-498,9
+516,9
@@
parse_aggregate_functions (struct agr_proc *agr)
}
/* Trailing rparen. */
}
/* Trailing rparen. */
- if (!lex_match
(
')'))
+ if (!lex_match
(lexer,
')'))
{
{
- lex_error (_("expecting `)'"));
+ lex_error (
lexer,
_("expecting `)'"));
goto error;
}
goto error;
}
@@
-576,21
+594,24
@@
parse_aggregate_functions (struct agr_proc *agr)
destvar = dict_create_var (agr->dict, dest[i], 0);
if (destvar != NULL)
{
destvar = dict_create_var (agr->dict, dest[i], 0);
if (destvar != NULL)
{
+ struct fmt_spec f;
if ((func_index == N || func_index == NMISS)
if ((func_index == N || func_index == NMISS)
- && dict_get_weight (d
efault_d
ict) != NULL)
-
destvar->print = destvar->write = f8_2
;
+ && dict_get_weight (dict) != NULL)
+
f = fmt_for_output (FMT_F, 8, 2)
;
else
else
- destvar->print = destvar->write = function->format;
+ f = function->format;
+ destvar->print = destvar->write = f;
}
}
} else {
}
}
} else {
+ struct fmt_spec f;
v->src = NULL;
destvar = dict_create_var (agr->dict, dest[i], 0);
v->src = NULL;
destvar = dict_create_var (agr->dict, dest[i], 0);
- if (func_index == N_NO_VARS
- && dict_get_weight (default_dict) != NULL)
- destvar->print = destvar->write = f8_2;
+ if (func_index == N_NO_VARS && dict_get_weight (dict) != NULL)
+ f = fmt_for_output (FMT_F, 8, 2);
else
else
- destvar->print = destvar->write = function->format;
+ f = function->format;
+ destvar->print = destvar->write = f;
}
if (!destvar)
}
if (!destvar)
@@
-639,17
+660,18
@@
parse_aggregate_functions (struct agr_proc *agr)
free (dest);
free (dest_label);
free (dest);
free (dest_label);
- if (!lex_match ('/'))
+ if (!lex_match (
lexer,
'/'))
{
{
- if (
token
== '.')
+ if (
lex_token (lexer)
== '.')
return true;
return true;
- lex_error ("expecting end of command");
+ lex_error (
lexer,
"expecting end of command");
return false;
}
continue;
error:
return false;
}
continue;
error:
+ ds_destroy (&function_name);
for (i = 0; i < n_dest; i++)
{
free (dest[i]);
for (i = 0; i < n_dest; i++)
{
free (dest[i]);
@@
-745,7
+767,7
@@
accumulate_aggregate_info (struct agr_proc *agr,
double weight;
bool bad_warn = true;
double weight;
bool bad_warn = true;
- weight = dict_get_case_weight (
default
_dict, input, &bad_warn);
+ weight = dict_get_case_weight (
agr->src
_dict, input, &bad_warn);
for (iter = agr->agr_vars; iter; iter = iter->next)
if (iter->src)
for (iter = agr->agr_vars; iter; iter = iter->next)
if (iter->src)
@@
-1083,7
+1105,7
@@
initialize_aggregate_info (struct agr_proc *agr, const struct ccase *input)
are dropped.
Returns true if successful, false if an I/O error occurred. */
static bool
are dropped.
Returns true if successful, false if an I/O error occurred. */
static bool
-agr_to_active_file (const struct ccase *c, void *agr_)
+agr_to_active_file (const struct ccase *c, void *agr_
, const struct dataset *ds UNUSED
)
{
struct agr_proc *agr = agr_;
{
struct agr_proc *agr = agr_;
@@
-1096,7
+1118,8
@@
agr_to_active_file (const struct ccase *c, void *agr_)
/* Aggregate the current case and output it if we passed a
breakpoint. */
static bool
/* Aggregate the current case and output it if we passed a
breakpoint. */
static bool
-presorted_agr_to_sysfile (const struct ccase *c, void *agr_)
+presorted_agr_to_sysfile (const struct ccase *c, void *agr_,
+ const struct dataset *ds UNUSED)
{
struct agr_proc *agr = agr_;
{
struct agr_proc *agr = agr_;