X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Faggregate.c;h=2b1ae5a00d728b511d861cf9faedebecb1a85bf9;hb=a1a4228b112a6aca97fef5aaaf9ffa21271a1f72;hp=aa289716f5a6aaaabf26a7d7ec45b38ff7434ec9;hpb=81fff61a96bece351e381ad3fef8ab1248a952ba;p=pspp-builds.git diff --git a/src/language/stats/aggregate.c b/src/language/stats/aggregate.c index aa289716..2b1ae5a0 100644 --- a/src/language/stats/aggregate.c +++ b/src/language/stats/aggregate.c @@ -35,9 +35,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include @@ -48,6 +49,13 @@ #include "gettext.h" #define _(msgid) gettext (msgid) +/* Argument for AGGREGATE function. */ +union agr_argument + { + double f; /* Numeric. */ + char *c; /* Short or long string. */ + }; + /* Specifies how to make an aggregate variable. */ struct agr_var { @@ -58,7 +66,7 @@ struct agr_var struct variable *dest; /* Target variable. */ int function; /* Function. */ int include_missing; /* 1=Include user-missing values. */ - union value arg[2]; /* Arguments. */ + union agr_argument arg[2]; /* Arguments. */ /* Accumulated during AGGREGATE execution. */ double dbl[3]; @@ -138,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. */ + const struct dictionary *src_dict; /* Dict of the source */ int case_cnt; /* Counts aggregated cases. */ struct ccase agr_case; /* Aggregate case for output. */ }; @@ -146,25 +155,27 @@ static void initialize_aggregate_info (struct agr_proc *, const struct ccase *); /* Prototypes. */ -static int parse_aggregate_functions (struct agr_proc *); +static bool parse_aggregate_functions (const struct dictionary *, + struct agr_proc *); static void agr_destroy (struct agr_proc *); -static int aggregate_single_case (struct agr_proc *agr, - const struct ccase *input, - struct ccase *output); +static bool aggregate_single_case (struct agr_proc *agr, + 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 bool agr_to_active_file (struct ccase *, void *aux); +static bool agr_to_active_file (const struct ccase *, void *aux, const struct dataset *); /* Aggregating to a system file. */ -static bool presorted_agr_to_sysfile (struct ccase *, void *aux); +static bool presorted_agr_to_sysfile (const struct ccase *, void *aux, const struct dataset *); /* Parsing. */ /* Parses and executes the AGGREGATE procedure. */ int -cmd_aggregate (void) +cmd_aggregate (struct dataset *ds) { + struct dictionary *dict = dataset_dict (ds); struct agr_proc agr; struct file_handle *out_file = NULL; @@ -177,8 +188,9 @@ cmd_aggregate (void) 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. */ if (!lex_force_match_id ("OUTFILE")) @@ -215,7 +227,7 @@ cmd_aggregate (void) int i; lex_match ('='); - agr.sort = sort_parse_criteria (default_dict, + agr.sort = sort_parse_criteria (dict, &agr.break_vars, &agr.break_var_cnt, &saw_direction, NULL); if (agr.sort == NULL) @@ -241,7 +253,7 @@ cmd_aggregate (void) /* Read in the aggregate functions. */ lex_match ('/'); - if (!parse_aggregate_functions (&agr)) + if (!parse_aggregate_functions (dict, &agr)) goto error; /* Delete documents. */ @@ -260,19 +272,21 @@ cmd_aggregate (void) { /* 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 (!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); - 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) { @@ -280,10 +294,12 @@ cmd_aggregate (void) if (!agr.sink->class->write (agr.sink, &agr.agr_case)) goto error; } - discard_variables (); - default_dict = agr.dict; + discard_variables (ds); + dict_destroy (dict); + dataset_set_dict (ds, agr.dict); 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 @@ -300,7 +316,7 @@ cmd_aggregate (void) 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); @@ -320,7 +336,7 @@ cmd_aggregate (void) else { /* Active file is already sorted. */ - if (!procedure (presorted_agr_to_sysfile, &agr)) + if (!procedure (ds, presorted_agr_to_sysfile, &agr)) goto error; } @@ -342,8 +358,8 @@ error: } /* Parse all the aggregate functions. */ -static int -parse_aggregate_functions (struct agr_proc *agr) +static bool +parse_aggregate_functions (const struct dictionary *dict, struct agr_proc *agr) { struct agr_var *tail; /* Tail of linked list starting at agr->vars. */ @@ -359,7 +375,7 @@ parse_aggregate_functions (struct agr_proc *agr) const struct agr_func *function; int func_index; - union value arg[2]; + union agr_argument arg[2]; struct variable **src; size_t n_src; @@ -396,7 +412,7 @@ parse_aggregate_functions (struct agr_proc *agr) if (token == T_STRING) { ds_truncate (&tokstr, 255); - dest_label[n_dest - 1] = xstrdup (ds_c_str (&tokstr)); + dest_label[n_dest - 1] = ds_xstrdup (&tokstr); lex_get (); } } @@ -450,7 +466,7 @@ parse_aggregate_functions (struct agr_proc *agr) else if (function->n_args) pv_opts |= PV_SAME_TYPE; - if (!parse_variables (default_dict, &src, &n_src, pv_opts)) + if (!parse_variables (dict, &src, &n_src, pv_opts)) goto error; } @@ -464,7 +480,7 @@ parse_aggregate_functions (struct agr_proc *agr) lex_match (','); if (token == T_STRING) { - arg[i].c = xstrdup (ds_c_str (&tokstr)); + arg[i].c = ds_xstrdup (&tokstr); type = ALPHA; } else if (lex_is_number ()) @@ -515,7 +531,7 @@ parse_aggregate_functions (struct agr_proc *agr) || (src[0]->type == ALPHA && str_compare_rpad (arg[0].c, arg[1].c) > 0))) { - union value t = arg[0]; + union agr_argument t = arg[0]; arg[0] = arg[1]; arg[1] = t; @@ -568,7 +584,7 @@ parse_aggregate_functions (struct agr_proc *agr) if (destvar != NULL) { if ((func_index == N || func_index == NMISS) - && dict_get_weight (default_dict) != NULL) + && dict_get_weight (dict) != NULL) destvar->print = destvar->write = f8_2; else destvar->print = destvar->write = function->format; @@ -578,7 +594,7 @@ parse_aggregate_functions (struct agr_proc *agr) v->src = NULL; destvar = dict_create_var (agr->dict, dest[i], 0); if (func_index == N_NO_VARS - && dict_get_weight (default_dict) != NULL) + && dict_get_weight (dict) != NULL) destvar->print = destvar->write = f8_2; else destvar->print = destvar->write = function->format; @@ -633,10 +649,10 @@ parse_aggregate_functions (struct agr_proc *agr) if (!lex_match ('/')) { if (token == '.') - return 1; + return true; lex_error ("expecting end of command"); - return 0; + return false; } continue; @@ -658,7 +674,7 @@ parse_aggregate_functions (struct agr_proc *agr) } free (src); - return 0; + return false; } } @@ -704,9 +720,9 @@ static void accumulate_aggregate_info (struct agr_proc *, static void dump_aggregate_info (struct agr_proc *, struct ccase *); /* Processes a single case INPUT for aggregation. If output is - warranted, writes it to OUTPUT and returns nonzero. - Otherwise, returns zero and OUTPUT is unmodified. */ -static int + warranted, writes it to OUTPUT and returns true. + Otherwise, returns false and OUTPUT is unmodified. */ +static bool aggregate_single_case (struct agr_proc *agr, const struct ccase *input, struct ccase *output) { @@ -734,9 +750,9 @@ accumulate_aggregate_info (struct agr_proc *agr, { struct agr_var *iter; double weight; - int bad_warn = 1; + 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) @@ -883,7 +899,7 @@ accumulate_aggregate_info (struct agr_proc *agr, caught earlier. Nothing to do. */ break; default: - assert (0); + NOT_REACHED (); } } else { switch (iter->function) @@ -895,7 +911,7 @@ accumulate_aggregate_info (struct agr_proc *agr, iter->int1++; break; default: - assert (0); + NOT_REACHED (); } } } @@ -1024,7 +1040,7 @@ dump_aggregate_info (struct agr_proc *agr, struct ccase *output) v->f = i->int1; break; default: - assert (0); + NOT_REACHED (); } } } @@ -1074,7 +1090,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 -agr_to_active_file (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_; @@ -1087,7 +1103,7 @@ agr_to_active_file (struct ccase *c, void *agr_) /* Aggregate the current case and output it if we passed a breakpoint. */ static bool -presorted_agr_to_sysfile (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_;