#include <math/moments.h>
#include <math/sort.h>
+#include "minmax.h"
+
#include "gettext.h"
#define _(msgid) gettext (msgid)
const struct ccase *);
/* Prototypes. */
-static bool parse_aggregate_functions (const struct dictionary *,
+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,
/* Parses and executes the AGGREGATE procedure. */
int
-cmd_aggregate (struct dataset *ds)
+cmd_aggregate (struct lexer *lexer, struct dataset *ds)
{
struct dictionary *dict = dataset_dict (ds);
struct agr_proc agr;
dict_set_documents (agr.dict, dict_get_documents (dict));
/* OUTFILE subcommand must be first. */
- if (!lex_force_match_id ("OUTFILE"))
+ if (!lex_force_match_id (lexer, "OUTFILE"))
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;
}
/* 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;
}
- else if (lex_match_id ("DOCUMENT"))
+ else if (lex_match_id (lexer, "DOCUMENT"))
copy_documents = true;
- else if (lex_match_id ("PRESORTED"))
+ else if (lex_match_id (lexer, "PRESORTED"))
presorted = true;
- else if (lex_match_id ("BREAK"))
+ else if (lex_match_id (lexer, "BREAK"))
{
int i;
- lex_match ('=');
- agr.sort = sort_parse_criteria (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)
}
else
{
- lex_error (_("expecting BREAK"));
+ lex_error (lexer, _("expecting BREAK"));
goto error;
}
}
"the same way as the input data."));
/* Read in the aggregate functions. */
- lex_match ('/');
- if (!parse_aggregate_functions (dict, &agr))
+ lex_match (lexer, '/');
+ if (!parse_aggregate_functions (lexer, dict, &agr))
goto error;
/* Delete documents. */
/* Parse all the aggregate functions. */
static bool
-parse_aggregate_functions (const struct dictionary *dict, 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. */
char **dest;
char **dest_label;
size_t n_dest;
+ struct string function_name;
int include_missing;
const struct agr_func *function;
arg[1].c = NULL;
/* Parse the list of target variables. */
- while (!lex_match ('='))
+ while (!lex_match (lexer, '='))
{
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;
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. */
- 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;
- 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;
- tokid[strlen (tokid) - 1] = 0;
- }
-
+
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)
{
- msg (SE, _("Unknown aggregation function %s."), tokid);
+ msg (SE, _("Unknown aggregation function %s."),
+ ds_cstr (&function_name));
goto error;
}
+ ds_destroy (&function_name);
func_index = function - agr_func_tab;
- lex_get ();
+ lex_get (lexer);
/* Check for leading lparen. */
- if (!lex_match ('('))
+ if (!lex_match (lexer, '('))
{
if (func_index == N)
func_index = N_NO_VARS;
func_index = NU_NO_VARS;
else
{
- lex_error (_("expecting `('"));
+ lex_error (lexer, _("expecting `('"));
goto error;
}
}
else if (function->n_args)
pv_opts |= PV_SAME_TYPE;
- if (!parse_variables (dict, &src, &n_src, pv_opts))
+ if (!parse_variables (lexer, dict, &src, &n_src, pv_opts))
goto error;
}
{
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;
}
- 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,
goto error;
}
- lex_get ();
+ lex_get (lexer);
if (type != src[0]->type)
{
}
/* Trailing rparen. */
- if (!lex_match(')'))
+ if (!lex_match (lexer, ')'))
{
- lex_error (_("expecting `)'"));
+ lex_error (lexer, _("expecting `)'"));
goto error;
}
free (dest);
free (dest_label);
- if (!lex_match ('/'))
+ if (!lex_match (lexer, '/'))
{
- if (token == '.')
+ if (lex_token (lexer) == '.')
return true;
- lex_error ("expecting end of command");
+ lex_error (lexer, "expecting end of command");
return false;
}
continue;
error:
+ ds_destroy (&function_name);
for (i = 0; i < n_dest; i++)
{
free (dest[i]);
moments1_add (iter->moments, v->f, weight);
break;
case MAX:
- iter->dbl[0] = max (iter->dbl[0], v->f);
+ iter->dbl[0] = MAX (iter->dbl[0], v->f);
iter->int1 = 1;
break;
case MAX | FSTRING:
iter->int1 = 1;
break;
case MIN:
- iter->dbl[0] = min (iter->dbl[0], v->f);
+ iter->dbl[0] = MIN (iter->dbl[0], v->f);
iter->int1 = 1;
break;
case MIN | FSTRING:
/* Aggregate the current case and output it if we passed a
breakpoint. */
static bool
-presorted_agr_to_sysfile (const struct ccase *c, void *agr_, const struct dataset *ds UNUSED)
+presorted_agr_to_sysfile (const struct ccase *c, void *agr_,
+ const struct dataset *ds UNUSED)
{
struct agr_proc *agr = agr_;