From: John Darrington Date: Wed, 1 Apr 2009 01:58:49 +0000 (+0800) Subject: Merge commit 'origin/master' into charset X-Git-Tag: v0.7.3~185 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6ede2e8f16079edae2e308583f8af4f7e9daddd;hp=b106c9452e2682e7923dc43028cf0e4b353e5443;p=pspp-builds.git Merge commit 'origin/master' into charset --- diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index 16195b0d..26511614 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009 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 @@ -384,10 +384,11 @@ lex_get (struct lexer *lexer) } else { - if (c_isgraph ((unsigned char) *lexer->prog)) - msg (SE, _("Bad character in input: `%c'."), *lexer->prog++); + unsigned char c = *lexer->prog++; + if (c_isgraph (c)) + msg (SE, _("Bad character in input: `%c'."), c); else - msg (SE, _("Bad character in input: `\\%o'."), *lexer->prog++); + msg (SE, _("Bad character in input: `\\%o'."), c); continue; } } diff --git a/src/language/stats/examine.q b/src/language/stats/examine.q index 78ea0e63..2649968b 100644 --- a/src/language/stats/examine.q +++ b/src/language/stats/examine.q @@ -198,7 +198,7 @@ factor_destroy (struct xfactor *fctr) } static struct xfactor level0_factor; -static struct ll_list factor_list = LL_INITIALIZER (factor_list); +static struct ll_list factor_list; /* Parse the clause specifying the factors */ static int examine_parse_independent_vars (struct lexer *lexer, @@ -268,6 +268,8 @@ cmd_examine (struct lexer *lexer, struct dataset *ds) subc_list_double_create (&percentile_list); percentile_algorithm = PC_HAVERAGE; + ll_init (&factor_list); + if ( !parse_examine (lexer, ds, &cmd, NULL) ) { subc_list_double_destroy (&percentile_list); diff --git a/src/language/stats/wilcoxon.c b/src/language/stats/wilcoxon.c index e44233a7..1bdcc06d 100644 --- a/src/language/stats/wilcoxon.c +++ b/src/language/stats/wilcoxon.c @@ -124,6 +124,7 @@ wilcoxon_execute (const struct dataset *ds, /* Central point values should be dropped */ ws[i].n_zeros += w; + case_unref (output); continue; } diff --git a/src/math/covariance-matrix.c b/src/math/covariance-matrix.c index a33c33b2..bb17d99a 100644 --- a/src/math/covariance-matrix.c +++ b/src/math/covariance-matrix.c @@ -57,7 +57,7 @@ struct covariance_matrix { struct design_matrix *cov; struct design_matrix *ssize; - struct design_matrix *means; + struct design_matrix *sums; struct hsh_table *ca; struct moments1 **m1; struct moments **m; @@ -182,7 +182,7 @@ covariance_matrix_destroy (struct covariance_matrix *cov) assert (cov != NULL); design_matrix_destroy (cov->cov); design_matrix_destroy (cov->ssize); - design_matrix_destroy (cov->means); + design_matrix_destroy (cov->sums); hsh_destroy (cov->ca); if (cov->n_pass == ONE_PASS) { @@ -219,9 +219,9 @@ covariance_update_categorical_numeric (struct design_matrix *cov, double mean, col = design_matrix_var_to_column (cov, v2); assert (val2 != NULL); - tmp = gsl_matrix_get (cov->m, row, col); - gsl_matrix_set (cov->m, row, col, (val2->f - mean) * x + tmp); - gsl_matrix_set (cov->m, col, row, (val2->f - mean) * x + tmp); + tmp = design_matrix_get_element (cov, row, col); + design_matrix_set_element (cov, row, col, (val2->f - mean) * x + tmp); + design_matrix_set_element (cov, col, row, (val2->f - mean) * x + tmp); } static void column_iterate (struct design_matrix *cov, const struct variable *v, @@ -243,9 +243,9 @@ column_iterate (struct design_matrix *cov, const struct variable *v, { y += -1.0; } - tmp = gsl_matrix_get (cov->m, row, col); - gsl_matrix_set (cov->m, row, col, x * y + tmp); - gsl_matrix_set (cov->m, col, row, x * y + tmp); + tmp = design_matrix_get_element (cov, row, col); + design_matrix_set_element (cov, row, col, x * y + tmp); + design_matrix_set_element (cov, col, row, x * y + tmp); } } @@ -306,9 +306,9 @@ covariance_pass_two (struct design_matrix *cov, double mean1, double mean2, row = design_matrix_var_to_column (cov, v1); col = design_matrix_var_to_column (cov, v2); x = (val1->f - mean1) * (val2->f - mean2); - x += gsl_matrix_get (cov->m, col, row); - gsl_matrix_set (cov->m, row, col, x); - gsl_matrix_set (cov->m, col, row, x); + x += design_matrix_get_element (cov, col, row); + design_matrix_set_element (cov, row, col, x); + design_matrix_set_element (cov, col, row, x); } } @@ -778,7 +778,7 @@ covariance_matrix_insert (struct design_matrix *cov, col = get_exact_subscript (cov, v2, val2); if (row != -1u && col != -1u) { - gsl_matrix_set (cov->m, row, col, product); + design_matrix_set_element (cov, row, col, product); } } @@ -811,6 +811,37 @@ is_covariance_contributor (const struct covariance_accumulator *ca, const struct } return false; } +static double +get_sum (const struct covariance_matrix *cov, size_t i) +{ + size_t k; + const struct variable *var; + const union value *val = NULL; + struct covariance_accumulator ca; + struct covariance_accumulator *c; + + assert ( cov != NULL); + var = design_matrix_col_to_var (cov->cov, i); + if (var != NULL) + { + if (var_is_alpha (var)) + { + k = design_matrix_var_to_column (cov->cov, var); + i -= k; + val = cat_subscript_to_value (i, var); + } + ca.v1 = var; + ca.v2 = var; + ca.val1 = val; + ca.val2 = val; + c = (struct covariance_accumulator *) hsh_find (cov->ca, &ca); + if (c != NULL) + { + return c->sum1; + } + } + return 0.0; +} static void update_ssize (struct design_matrix *dm, size_t i, size_t j, struct covariance_accumulator *ca) { @@ -822,9 +853,9 @@ update_ssize (struct design_matrix *dm, size_t i, size_t j, struct covariance_ac var = design_matrix_col_to_var (dm, j); if (var_get_dict_index (ca->v2) == var_get_dict_index (var)) { - tmp = gsl_matrix_get (dm->m, i, j); + tmp = design_matrix_get_element (dm, i, j); tmp += ca->ssize; - gsl_matrix_set (dm->m, i, j, tmp); + design_matrix_set_element (dm, i, j, tmp); } } } @@ -833,23 +864,26 @@ covariance_accumulator_to_matrix (struct covariance_matrix *cov) { size_t i; size_t j; - double tmp; + double sum_i = 0.0; + double sum_j = 0.0; + double tmp = 0.0; struct covariance_accumulator *entry; struct hsh_iterator iter; cov->cov = covariance_matrix_create (cov->n_variables, cov->v_variables); cov->ssize = covariance_matrix_create (cov->n_variables, cov->v_variables); - cov->means = covariance_matrix_create (cov->n_variables, cov->v_variables); + cov->sums = covariance_matrix_create (cov->n_variables, cov->v_variables); for (i = 0; i < design_matrix_get_n_cols (cov->cov); i++) { + sum_i = get_sum (cov, i); for (j = i; j < design_matrix_get_n_cols (cov->cov); j++) { + sum_j = get_sum (cov, j); entry = hsh_first (cov->ca, &iter); - + design_matrix_set_element (cov->sums, i, j, sum_i); while (entry != NULL) { update_ssize (cov->ssize, i, j, entry); - /* We compute the centered, un-normalized covariance matrix. */ @@ -857,14 +891,12 @@ covariance_accumulator_to_matrix (struct covariance_matrix *cov) { covariance_matrix_insert (cov->cov, entry->v1, entry->v2, entry->val1, entry->val2, entry->dot_product); - covariance_matrix_insert (cov->cov, entry->v1, entry->v2, entry->val1, - entry->val2, entry->sum1 * entry->sum2); } entry = hsh_next (cov->ca, &iter); } - tmp = gsl_matrix_get (cov->cov->m, i, j); - tmp -= gsl_matrix_get (cov->means->m, i, j) / gsl_matrix_get (cov->ssize->m, i, j); - gsl_matrix_set (cov->cov->m, i, j, tmp); + tmp = design_matrix_get_element (cov->cov, i, j); + tmp -= sum_i * sum_j / design_matrix_get_element (cov->ssize, i, j); + design_matrix_set_element (cov->cov, i, j, tmp); } } } @@ -891,3 +923,10 @@ covariance_to_design (const struct covariance_matrix *c) } return NULL; } + +double +covariance_matrix_get_element (const struct covariance_matrix *c, size_t row, size_t col) +{ + return (design_matrix_get_element (c->cov, row, col)); +} + diff --git a/src/math/covariance-matrix.h b/src/math/covariance-matrix.h index b692e7e8..24ce791c 100644 --- a/src/math/covariance-matrix.h +++ b/src/math/covariance-matrix.h @@ -56,4 +56,5 @@ void covariance_matrix_free (struct covariance_matrix *); void covariance_matrix_accumulate (struct covariance_matrix *, const struct ccase *, void **, size_t); struct design_matrix *covariance_to_design (const struct covariance_matrix *); +double covariance_matrix_get_element (const struct covariance_matrix *, size_t, size_t); #endif diff --git a/src/math/design-matrix.c b/src/math/design-matrix.c index 8195a408..b81859aa 100644 --- a/src/math/design-matrix.c +++ b/src/math/design-matrix.c @@ -270,4 +270,14 @@ design_matrix_get_n_rows (const struct design_matrix *d) return d->m->size1; } +double +design_matrix_get_element (const struct design_matrix *d, size_t row, size_t col) +{ + return (gsl_matrix_get (d->m, row, col)); +} +void +design_matrix_set_element (const struct design_matrix *d, size_t row, size_t col, double x) +{ + gsl_matrix_set (d->m, row, col, x); +} diff --git a/src/math/design-matrix.h b/src/math/design-matrix.h index 5250b490..45814580 100644 --- a/src/math/design-matrix.h +++ b/src/math/design-matrix.h @@ -92,4 +92,6 @@ void design_matrix_set_case_count (struct design_matrix *, const struct variable size_t design_matrix_get_case_count (const struct design_matrix *, const struct variable *); size_t design_matrix_get_n_cols (const struct design_matrix *); size_t design_matrix_get_n_rows (const struct design_matrix *); +double design_matrix_get_element (const struct design_matrix *, size_t, size_t); +void design_matrix_set_element (const struct design_matrix *, size_t, size_t, double); #endif diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 0d3bbc18..11106640 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -29,8 +29,7 @@ src_ui_gui_psppire_LDADD = \ src/libpspp.la \ src/libpspp-core.la \ $(GTK_LIBS) \ - @LIBINTL@ \ - $(LIB_CLOSE) + @LIBINTL@ src_ui_gui_psppiredir = $(pkgdatadir) diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 405e1350..a1f48e7b 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -276,7 +276,59 @@ parse_non_options (int key, char *arg, struct argp_state *state) { case ARGP_KEY_ARG: { - psppire_window_load (PSPPIRE_WINDOW (the_data_window), arg); + gchar *filename = NULL; + gchar *utf8 = NULL; + const gchar *local_encoding = NULL; + gsize written = -1; + const gboolean local_is_utf8 = g_get_charset (&local_encoding); + + /* There seems to be no Glib function to convert from local encoding + to filename encoding. Therefore it has to be done in two steps: + the intermediate encoding is UTF8. + + Either step could fail. However, in many cases the file can still + be loaded even if the conversion fails. So in those cases, after showing + a warning, we simply copy the locally encoded filename to the destination + and hope for the best. + */ + + if ( local_is_utf8) + { + utf8 = strdup (arg); + } + else + { + GError *err = NULL; + utf8 = g_locale_to_utf8 (arg, -1, NULL, &written, &err); + if ( NULL == utf8) + { + g_warning ("Cannot convert filename from local encoding \"%s\" to UTF-8: %s", + local_encoding, + err->message); + g_clear_error (&err); + } + } + + if ( NULL != utf8) + { + GError *err = NULL; + filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err); + if ( NULL == filename) + { + g_warning ("Cannot convert filename from UTF8 to filename encoding: %s", + err->message); + g_clear_error (&err); + } + } + + g_free (utf8); + + if ( filename == NULL) + filename = strdup (arg); + + psppire_window_load (PSPPIRE_WINDOW (the_data_window), filename); + + g_free (filename); break; } default: diff --git a/src/ui/terminal/automake.mk b/src/ui/terminal/automake.mk index cd47b62e..5ab09857 100644 --- a/src/ui/terminal/automake.mk +++ b/src/ui/terminal/automake.mk @@ -27,8 +27,7 @@ src_ui_terminal_pspp_LDADD = \ src/libpspp-core.la \ $(NCURSES_LIBS) \ $(LIBICONV) \ - @LIBINTL@ @LIBREADLINE@ \ - $(LIB_CLOSE) + @LIBINTL@ @LIBREADLINE@ src_ui_terminal_pspp_LDFLAGS = $(PSPP_LDFLAGS) $(PG_LDFLAGS) diff --git a/tests/automake.mk b/tests/automake.mk index 4c3899b1..5c84354f 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -116,6 +116,7 @@ dist_TESTS = \ tests/bugs/empty-do-repeat.sh \ tests/bugs/get.sh \ tests/bugs/examine-crash.sh \ + tests/bugs/examine-crash2.sh \ tests/bugs/examine-1sample.sh \ tests/bugs/examine-missing.sh \ tests/bugs/examine-missing2.sh \ @@ -214,7 +215,7 @@ tests_libpspp_heap_test_SOURCES = \ src/libpspp/pool.c \ src/libpspp/pool.h \ tests/libpspp/heap-test.c -tests_libpspp_heap_test_LDADD = gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_libpspp_heap_test_LDADD = gl/libgl.la @LIBINTL@ tests_libpspp_heap_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 tests_libpspp_hmap_test_SOURCES = \ @@ -264,12 +265,12 @@ tests_libpspp_range_set_test_SOURCES = \ src/libpspp/range-set.c \ src/libpspp/range-set.h \ tests/libpspp/range-set-test.c -tests_libpspp_range_set_test_LDADD = gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_libpspp_range_set_test_LDADD = gl/libgl.la @LIBINTL@ tests_libpspp_range_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 tests_libpspp_str_test_SOURCES = \ tests/libpspp/str-test.c -tests_libpspp_str_test_LDADD = src/libpspp/libpspp.la gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_libpspp_str_test_LDADD = src/libpspp/libpspp.la gl/libgl.la @LIBINTL@ tests_libpspp_tower_test_SOURCES = \ src/libpspp/abt.c \ @@ -279,7 +280,7 @@ tests_libpspp_tower_test_SOURCES = \ src/libpspp/tower.c \ src/libpspp/tower.h \ tests/libpspp/tower-test.c -tests_libpspp_tower_test_LDADD = gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_libpspp_tower_test_LDADD = gl/libgl.la @LIBINTL@ tests_libpspp_tower_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 tests_libpspp_sparse_array_test_SOURCES = \ @@ -288,7 +289,7 @@ tests_libpspp_sparse_array_test_SOURCES = \ src/libpspp/pool.c \ src/libpspp/pool.h \ tests/libpspp/sparse-array-test.c -tests_libpspp_sparse_array_test_LDADD = gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_libpspp_sparse_array_test_LDADD = gl/libgl.la @LIBINTL@ tests_libpspp_sparse_array_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 tests_formats_inexactify_SOURCES = tests/formats/inexactify.c @@ -298,7 +299,7 @@ tests_dissect_sysfile_SOURCES = \ src/libpspp/integer-format.c \ src/libpspp/float-format.c \ tests/dissect-sysfile.c -tests_dissect_sysfile_LDADD = gl/libgl.la @LIBINTL@ @LIB_CLOSE@ +tests_dissect_sysfile_LDADD = gl/libgl.la @LIBINTL@ tests_dissect_sysfile_CPPFLAGS = $(AM_CPPFLAGS) -DINSTALLDIR=\"$(bindir)\" EXTRA_DIST += \ diff --git a/tests/bugs/examine-crash2.sh b/tests/bugs/examine-crash2.sh new file mode 100755 index 00000000..01fe8f9a --- /dev/null +++ b/tests/bugs/examine-crash2.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# This program tests for a bug which crashed pspp +# when two consecutive EXAMINE commands are run. + +TEMPDIR=/tmp/pspp-tst-$$ +TESTFILE=$TEMPDIR/`basename $0`.sps + +# ensure that top_srcdir and top_builddir are absolute +if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi +if [ -z "$top_builddir" ] ; then top_builddir=. ; fi +top_srcdir=`cd $top_srcdir; pwd` +top_builddir=`cd $top_builddir; pwd` + +PSPP=$top_builddir/src/ui/terminal/pspp + +STAT_CONFIG_PATH=$top_srcdir/config +export STAT_CONFIG_PATH + +LANG=C +export LANG + + +cleanup() +{ + if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then + echo "NOT cleaning $TEMPDIR" + return ; + fi + rm -rf $TEMPDIR +} + + +fail() +{ + echo $activity + echo FAILED + cleanup; + exit 1; +} + + +no_result() +{ + echo $activity + echo NO RESULT; + cleanup; + exit 2; +} + +pass() +{ + cleanup; + exit 0; +} + +mkdir -p $TEMPDIR + +cd $TEMPDIR + +cat < $TESTFILE +data list list /y * z *. +begin data. +6 4 +5 3 +7 6 +end data. + +EXAMINE /VARIABLES= z BY y. + +EXAMINE /VARIABLES= z. +EOF +if [ $? -ne 0 ] ; then no_result ; fi + + +activity="run program" +$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE +if [ $? -ne 0 ] ; then fail ; fi + + +pass;