X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fcrosstabs.q;h=a6b224693737a2e85212687c053c066190684c49;hb=2cf38ce51a9f34961d68a75e0b312a591b5c9abf;hp=46b5e41323955d6e06128fbd64f401e66f9b4773;hpb=5c3291dc396b795696e94f47780308fd7ace6fc4;p=pspp-builds.git diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index 46b5e413..a6b22469 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -161,41 +161,6 @@ struct pivot_table double total; /* Grand total. */ }; -/* A crosstabulation of exactly 2 variables, conditional on zero - or more other variables having given values. */ -struct crosstab - { - /* Case counts. */ - double missing; - - /* Variables. */ - int n_vars; /* Number of variables (at least 2). */ - const struct variable **vars; - union value *values; /* Values of variables beyond 2. */ - - /* Data. */ - struct table_entry **entries; - size_t n_entries; - - /* Column values, number of columns. */ - union value *cols; - int n_cols; - - /* Row values, number of rows. */ - union value *rows; - int n_rows; - - /* Number of statistically interesting columns/rows - (columns/rows with data in them). */ - int ns_cols, ns_rows; - - /* Matrix contents. */ - double *mat; /* Matrix proper. */ - double *row_tot; /* Row totals. */ - double *col_tot; /* Column totals. */ - double total; /* Grand total. */ - }; - /* Integer mode variable info. */ struct var_range { @@ -248,9 +213,23 @@ init_proc (struct crosstabs_proc *proc, struct dataset *ds) } static void -free_proc (struct crosstabs_proc *proc UNUSED) +free_proc (struct crosstabs_proc *proc) { - /* XXX */ + struct pivot_table *pt; + + free (proc->variables); + for (pt = &proc->pivots[0]; pt < &proc->pivots[proc->n_pivots]; pt++) + { + free (pt->vars); + free (pt->const_vars); + /* We must not call value_destroy on const_values because + it is a wild pointer; it never pointed to anything owned + by the pivot_table. + + The rest of the data was allocated and destroyed at a + lower level already. */ + free (pt); + } } static int internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds, @@ -740,7 +719,23 @@ postcalc (struct crosstabs_proc *proc) } } - /* XXX clear output and prepare for next split file. */ + /* Free output and prepare for next split file. */ + for (pt = &proc->pivots[0]; pt < &proc->pivots[proc->n_pivots]; pt++) + { + size_t i; + + pt->missing = 0.0; + + /* Free only the members that were allocated in this + function. The other pointer members are either both + allocated and destroyed at a lower level (in + output_pivot_table), or both allocated and destroyed at + a higher level (in crs_custom_tables and free_proc, + respectively). */ + for (i = 0; i < pt->n_entries; i++) + free (pt->entries[i]); + free (pt->entries); + } } static void @@ -886,8 +881,8 @@ make_summary_table (struct crosstabs_proc *proc) { tab_double (summary, i * 2 + 1, 0, TAB_RIGHT, n[i], &proc->weight_format); - tab_text (summary, i * 2 + 2, 0, TAB_RIGHT | TAT_PRINTF, "%.1f%%", - n[i] / n[2] * 100.); + tab_text_format (summary, i * 2 + 2, 0, TAB_RIGHT, "%.1f%%", + n[i] / n[2] * 100.); } tab_next_row (summary); @@ -998,26 +993,32 @@ output_pivot_table (struct crosstabs_proc *proc, struct pivot_table *pt) if (chisq) { display_dimensions (proc, &x, chisq, first_difference); - display_chisq (pt, chisq, &showed_fisher); + display_chisq (&x, chisq, &showed_fisher); } if (sym) { display_dimensions (proc, &x, sym, first_difference); - display_symmetric (proc, pt, sym); + display_symmetric (proc, &x, sym); } if (risk) { display_dimensions (proc, &x, risk, first_difference); - display_risk (pt, risk); + display_risk (&x, risk); } if (direct) { display_dimensions (proc, &x, direct, first_difference); - display_directional (proc, pt, direct); + display_directional (proc, &x, direct); } - /* XXX Free data in x. */ + /* Free the parts of x that are not owned by pt. In + particular we must not free x.cols, which is the same as + pt->cols, which is freed at the end of this function. */ free (x.rows); + + free (x.mat); + free (x.row_tot); + free (x.col_tot); } submit (proc, NULL, table); @@ -1182,10 +1183,17 @@ create_crosstab_table (struct crosstabs_proc *proc, struct pivot_table *pt) for (i = 0; i < pt->n_consts; i++) { const struct variable *var = pt->const_vars[i]; + size_t ofs; + ds_put_format (&title, ", %s=", var_get_name (var)); + + /* Insert the formatted value of the variable, then trim + leading spaces in what was just inserted. */ + ofs = ds_length (&title); data_out (&pt->const_values[i], var_get_print_format (var), ds_put_uninit (&title, var_get_width (var))); - /* XXX remove any leading space in what was just inserted. */ + ds_remove (&title, ofs, ss_cspan (ds_substr (&title, ofs, SIZE_MAX), + ss_cstr (" "))); } ds_put_cstr (&title, " ["); @@ -1228,7 +1236,6 @@ create_chisq_table (struct pivot_table *pt) _("Exact. Sig. (2-sided)")); tab_text (chisq, 5, 0, TAB_RIGHT | TAT_TITLE, _("Exact. Sig. (1-sided)")); - chisq = 0; tab_offset (chisq, 0, 1); return chisq; @@ -1269,8 +1276,8 @@ create_risk_table (struct pivot_table *pt) tab_title (risk, _("Risk estimate.")); tab_offset (risk, pt->n_vars - 2, 0); - tab_joint_text (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF, - _("95%% Confidence Interval")); + tab_joint_text_format (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE, + _("95%% Confidence Interval")); tab_text (risk, 0, 1, TAB_LEFT | TAT_TITLE, _("Statistic")); tab_text (risk, 1, 1, TAB_RIGHT | TAT_TITLE, _("Value")); tab_text (risk, 2, 1, TAB_RIGHT | TAT_TITLE, _("Lower")); @@ -1773,7 +1780,6 @@ display_chisq (struct pivot_table *pt, struct tab_table *chisq, double chisq_v[N_CHISQ]; double fisher1, fisher2; int df[N_CHISQ]; - int s = 0; int i; @@ -1786,7 +1792,6 @@ display_chisq (struct pivot_table *pt, struct tab_table *chisq, if ((i != 2 && chisq_v[i] == SYSMIS) || (i == 2 && fisher1 == SYSMIS)) continue; - s = 1; tab_text (chisq, 0, 0, TAB_LEFT, gettext (chisq_stats[i])); if (i != 2) @@ -2055,8 +2060,8 @@ display_directional (struct crosstabs_proc *proc, struct pivot_table *pt, else string = var_get_name (pt->vars[1]); - tab_text (direct, j, 0, TAB_LEFT | TAT_PRINTF, - gettext (stats_names[j][k]), string); + tab_text_format (direct, j, 0, TAB_LEFT, + gettext (stats_names[j][k]), string); } } }