X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fcrosstabs.q;h=5695ed6478b64490095ea0c8abde83873fb38030;hb=refs%2Ftags%2Flenny-x64-build82;hp=99fa41d9c056a039ef9d92fdc9090758539c9d15;hpb=bd17d2af982332ee1791998361b1ac6731fe14fa;p=pspp-builds.git diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index 99fa41d9..5695ed64 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -201,6 +201,12 @@ struct crosstabs_proc unsigned int statistics; /* Bit k is 1 if statistic k is requested. */ }; +/* Auxiliary data structure for tab_dim. */ +struct crosstabs_dim_aux + { + enum mv_class exclude; + }; + static void init_proc (struct crosstabs_proc *proc, struct dataset *ds) { @@ -230,8 +236,8 @@ free_proc (struct crosstabs_proc *proc) The rest of the data was allocated and destroyed at a lower level already. */ - free (pt); } + free (proc->pivots); } static int internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds, @@ -836,7 +842,7 @@ make_summary_table (struct crosstabs_proc *proc) struct string name; int i; - summary = tab_create (7, 3 + proc->n_pivots, 1); + summary = tab_create (7, 3 + proc->n_pivots); tab_title (summary, _("Summary.")); tab_headers (summary, 1, 0, 3, 0); tab_joint_text (summary, 1, 0, 6, 0, TAB_CENTER, _("Cases")); @@ -914,8 +920,8 @@ static void display_symmetric (struct crosstabs_proc *, struct pivot_table *, static void display_risk (struct pivot_table *, struct tab_table *); static void display_directional (struct crosstabs_proc *, struct pivot_table *, struct tab_table *); -static void crosstabs_dim (struct tab_table *, struct outp_driver *, - void *proc); +static void crosstabs_dim (struct tab_rendering *, void *aux); +static void crosstabs_dim_free (void *aux); static void table_value_missing (struct crosstabs_proc *proc, struct tab_table *table, int c, int r, unsigned char opt, const union value *v, @@ -1147,8 +1153,7 @@ create_crosstab_table (struct crosstabs_proc *proc, struct pivot_table *pt) int i; table = tab_create (pt->n_consts + 1 + pt->n_cols + 1, - (pt->n_entries / pt->n_cols) * 3 / 2 * proc->n_cells + 10, - true); + (pt->n_entries / pt->n_cols) * 3 / 2 * proc->n_cells + 10); tab_headers (table, pt->n_consts + 1, 0, 2, 0); /* First header line. */ @@ -1224,8 +1229,7 @@ create_chisq_table (struct pivot_table *pt) struct tab_table *chisq; chisq = tab_create (6 + (pt->n_vars - 2), - pt->n_entries / pt->n_cols * 3 / 2 * N_CHISQ + 10, - 1); + pt->n_entries / pt->n_cols * 3 / 2 * N_CHISQ + 10); tab_headers (chisq, 1 + (pt->n_vars - 2), 0, 1, 0); tab_title (chisq, _("Chi-square tests.")); @@ -1252,7 +1256,7 @@ create_sym_table (struct pivot_table *pt) struct tab_table *sym; sym = tab_create (6 + (pt->n_vars - 2), - pt->n_entries / pt->n_cols * 7 + 10, 1); + pt->n_entries / pt->n_cols * 7 + 10); tab_headers (sym, 2 + (pt->n_vars - 2), 0, 1, 0); tab_title (sym, _("Symmetric measures.")); @@ -1274,8 +1278,7 @@ create_risk_table (struct pivot_table *pt) { struct tab_table *risk; - risk = tab_create (4 + (pt->n_vars - 2), pt->n_entries / pt->n_cols * 4 + 10, - 1); + risk = tab_create (4 + (pt->n_vars - 2), pt->n_entries / pt->n_cols * 4 + 10); tab_headers (risk, 1 + pt->n_vars - 2, 0, 2, 0); tab_title (risk, _("Risk estimate.")); @@ -1300,7 +1303,7 @@ create_direct_table (struct pivot_table *pt) struct tab_table *direct; direct = tab_create (7 + (pt->n_vars - 2), - pt->n_entries / pt->n_cols * 7 + 10, 1); + pt->n_entries / pt->n_cols * 7 + 10); tab_headers (direct, 3 + (pt->n_vars - 2), 0, 1, 0); tab_title (direct, _("Directional measures.")); @@ -1348,6 +1351,7 @@ static void submit (struct crosstabs_proc *proc, struct pivot_table *pt, struct tab_table *t) { + struct crosstabs_dim_aux *aux; int i; if (t == NULL) @@ -1370,33 +1374,39 @@ submit (struct crosstabs_proc *proc, struct pivot_table *pt, tab_box (t, -1, -1, -1, TAL_GAP, 0, tab_t (t), tab_l (t) - 1, tab_nr (t) - 1); tab_vline (t, TAL_2, tab_l (t), 0, tab_nr (t) - 1); - tab_dim (t, crosstabs_dim, proc); + + aux = xmalloc (sizeof *aux); + aux->exclude = proc->exclude; + tab_dim (t, crosstabs_dim, crosstabs_dim_free, aux); + tab_submit (t); } /* Sets the widths of all the columns and heights of all the rows in table T for driver D. */ static void -crosstabs_dim (struct tab_table *t, struct outp_driver *d, void *proc_) +crosstabs_dim (struct tab_rendering *r, void *aux_) { - struct crosstabs_proc *proc = proc_; + const struct tab_table *t = r->table; + struct outp_driver *d = r->driver; + struct crosstabs_dim_aux *aux = aux_; int i; /* Width of a numerical column. */ int c = outp_string_width (d, "0.000000", OUTP_PROPORTIONAL); - if (proc->exclude == MV_NEVER) + if (aux->exclude == MV_NEVER) c += outp_string_width (d, "M", OUTP_PROPORTIONAL); /* Set width for header columns. */ - if (t->l != 0) + if (tab_l (t) != 0) { size_t i; int w; - w = d->width - c * (t->nc - t->l); - for (i = 0; i <= t->nc; i++) - w -= t->wrv[i]; - w /= t->l; + w = d->width - c * (tab_nc (t) - tab_l (t)); + for (i = 0; i <= tab_nc (t); i++) + w -= r->wrv[i]; + w /= tab_l (t); if (w < d->prop_em_width * 8) w = d->prop_em_width * 8; @@ -1404,15 +1414,22 @@ crosstabs_dim (struct tab_table *t, struct outp_driver *d, void *proc_) if (w > d->prop_em_width * 15) w = d->prop_em_width * 15; - for (i = 0; i < t->l; i++) - t->w[i] = w; + for (i = 0; i < tab_l (t); i++) + r->w[i] = w; } - for (i = t->l; i < t->nc; i++) - t->w[i] = c; + for (i = tab_l (t); i < tab_nc (t); i++) + r->w[i] = c; + + for (i = 0; i < tab_nr (t); i++) + r->h[i] = tab_natural_height (r, i); +} - for (i = 0; i < t->nr; i++) - t->h[i] = tab_natural_height (t, d, i); +static void +crosstabs_dim_free (void *aux_) +{ + struct crosstabs_dim_aux *aux = aux_; + free (aux); } static bool @@ -1513,26 +1530,21 @@ table_value_missing (struct crosstabs_proc *proc, struct tab_table *table, int c, int r, unsigned char opt, const union value *v, const struct variable *var) { - struct substring s; - const struct fmt_spec *print = var_get_print_format (var); - const char *label = var_lookup_value_label (var, v); - if (label) - { - tab_text (table, c, r, TAB_LEFT, label); - return; - } - - s = ss_cstr (data_out_pool (v, dict_get_encoding (proc->dict), print, - table->container)); - if (proc->exclude == MV_NEVER && var_is_num_missing (var, v->f, MV_USER)) - s.string[s.length++] = 'M'; - while (s.length && *s.string == ' ') + if (label != NULL) + tab_text (table, c, r, TAB_LEFT, label); + else { - s.length--; - s.string++; + const struct fmt_spec *print = var_get_print_format (var); + if (proc->exclude == MV_NEVER && var_is_value_missing (var, v, MV_USER)) + { + char *s = data_out (v, dict_get_encoding (proc->dict), print); + tab_text_format (table, c, r, opt, "%sM", s + strspn (s, " ")); + free (s); + } + else + tab_value (table, c, r, opt, v, proc->dict, print); } - tab_raw (table, c, r, opt, &s); } /* Draws a line across TABLE at the current row to indicate the most @@ -1561,22 +1573,22 @@ format_cell_entry (struct tab_table *table, int c, int r, double value, { const struct fmt_spec f = {FMT_F, 10, 1}; union value v; - struct substring s; + char suffixes[3]; + int suffix_len; + char *s; v.f = value; - s = ss_cstr (data_out_pool (&v, dict_get_encoding (dict), &f, table->container)); + s = data_out (&v, dict_get_encoding (dict), &f); - while (*s.string == ' ') - { - s.length--; - s.string++; - } + suffix_len = 0; if (suffix != 0) - s.string[s.length++] = suffix; + suffixes[suffix_len++] = suffix; if (mark_missing) - s.string[s.length++] = 'M'; + suffixes[suffix_len++] = 'M'; + suffixes[suffix_len] = '\0'; - tab_raw (table, c, r, TAB_RIGHT, &s); + tab_text_format (table, c, r, TAB_RIGHT, "%s%s", + s + strspn (s, " "), suffixes); } /* Displays the crosstabulation table. */