X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fdescriptives.c;h=a35878b75ad326add482f986e5336ea46f041254;hb=24c5f7c629e68801492d7ca1766953a2a954a820;hp=54bc49d946a064bd3c4eee8ffdab962d611733c3;hpb=2c0ddcd27c6e5afa944f9eca6f5cf6e7f6e32f98;p=pspp diff --git a/src/language/stats/descriptives.c b/src/language/stats/descriptives.c index 54bc49d946..a35878b75a 100644 --- a/src/language/stats/descriptives.c +++ b/src/language/stats/descriptives.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-2000, 2009-2012 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2009-2014 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -397,6 +398,13 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds) } } + /* It would be better to handle Z scores correctly (however we define + that) when TEMPORARY is in effect, but in the meantime this at least + prevents a use-after-free error. See bug #38786. */ + if (proc_make_temporary_transformations_permanent (ds)) + msg (SW, _("DESCRIPTIVES with Z scores ignores TEMPORARY. " + "Temporary transformations will be made permanent.")); + proto = caseproto_create (); for (i = 0; i < 1 + 2 * z_cnt; i++) proto = caseproto_add_width (proto, 0); @@ -434,7 +442,8 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds) dsc->vars[i].moments = moments_create (dsc->max_moment); /* Data pass. */ - grouper = casegrouper_create_splits (proc_open (ds), dict); + grouper = casegrouper_create_splits (proc_open_filtering (ds, z_cnt == 0), + dict); while (casegrouper_get_next_group (grouper, &group)) calc_descriptives (dsc, group, ds); ok = casegrouper_destroy (grouper); @@ -512,7 +521,7 @@ try_name (const struct dictionary *dict, struct dsc_proc *dsc, for (i = 0; i < dsc->var_cnt; i++) { struct dsc_var *dsc_var = &dsc->vars[i]; - if (dsc_var->z_name != NULL && !strcasecmp (dsc_var->z_name, name)) + if (dsc_var->z_name != NULL && !utf8_strcasecmp (dsc_var->z_name, name)) return false; } return true; @@ -689,6 +698,8 @@ descriptives_trns_free (void *trns_) casereader_destroy (t->z_reader); assert((t->missing_type != DSC_LISTWISE) ^ (t->vars != NULL)); free (t->vars); + free (t); + return ok; } @@ -732,11 +743,13 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds) { struct dsc_z_score *z; struct variable *dst_var; + char *label; dst_var = dict_create_var_assert (dataset_dict (ds), dv->z_name, 0); - var_set_label (dst_var, - xasprintf (_("Z-score of %s"),var_to_string (dv->v)), - false); + + label = xasprintf (_("Z-score of %s"),var_to_string (dv->v)); + var_set_label (dst_var, label); + free (label); z = &t->z_scores[cnt++]; z->src_var = dv->v; @@ -990,17 +1003,18 @@ display (struct dsc_proc *dsc) nc = 0; tab_text (t, nc++, i + 1, TAB_LEFT, var_to_string (dv->v)); - tab_text_format (t, nc++, i + 1, 0, "%g", dv->valid); + tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->valid); if (dsc->format == DSC_SERIAL) - tab_text_format (t, nc++, i + 1, 0, "%g", dv->missing); + tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->missing); for (j = 0; j < DSC_N_STATS; j++) if (dsc->show_stats & (1ul << j)) tab_double (t, nc++, i + 1, TAB_NONE, dv->stats[j], NULL); } - tab_title (t, _("Valid cases = %g; cases with missing value(s) = %g."), - dsc->valid, dsc->missing_listwise); + tab_title (t, _("Valid cases = %.*g; cases with missing value(s) = %.*g."), + DBL_DIG + 1, dsc->valid, + DBL_DIG + 1, dsc->missing_listwise); tab_submit (t); } @@ -1017,7 +1031,7 @@ descriptives_compare_dsc_vars (const void *a_, const void *b_, const void *dsc_) int result; if (dsc->sort_by_stat == DSC_NAME) - result = strcasecmp (var_get_name (a->v), var_get_name (b->v)); + result = utf8_strcasecmp (var_get_name (a->v), var_get_name (b->v)); else { double as = a->stats[dsc->sort_by_stat];