Merge commit 'origin/master' into charset
authorJohn Darrington <john@darrington.wattle.id.au>
Wed, 1 Apr 2009 01:58:49 +0000 (09:58 +0800)
committerJohn Darrington <john@darrington.wattle.id.au>
Wed, 1 Apr 2009 01:58:49 +0000 (09:58 +0800)
12 files changed:
src/language/lexer/lexer.c
src/language/stats/examine.q
src/language/stats/wilcoxon.c
src/math/covariance-matrix.c
src/math/covariance-matrix.h
src/math/design-matrix.c
src/math/design-matrix.h
src/ui/gui/automake.mk
src/ui/gui/psppire.c
src/ui/terminal/automake.mk
tests/automake.mk
tests/bugs/examine-crash2.sh [new file with mode: 0755]

index 16195b0dd22303a92f5c3075488f58ec8da5d088..265116141eb36f0d8ffa685a326431cd79f7b7ad 100644 (file)
@@ -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;
             }
         }
index 78ea0e63c0b1989f3f35a0a1e1105e5bb269f76d..2649968b31485b105f6a80f3119ab39bdc851eea 100644 (file)
@@ -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);
index e44233a7ab7904fb437a1988f6505cb3af4559cf..1bdcc06dc252851f93c7172a13c35fdfaba62367 100644 (file)
@@ -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;
            }
 
index a33c33b243e46c07c8997a8825f27b00cfbc458b..bb17d99aa9c616d49aa1f7d3f3f62201d3508710 100644 (file)
@@ -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));
+}
+
index b692e7e8003e4ee852a09a22c8acda31864c4901..24ce791cf5f74da3bb27ae48b11c4a9591a9f2b8 100644 (file)
@@ -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
index 8195a4088db246b1d8f67012d1da5b26ee306a0f..b81859aa5a539099f6e7a437ab053f31ce5fa202 100644 (file)
@@ -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);
+}
index 5250b4901ba384cf67a65860ac622844e0f28404..458145801fa0d4686776c923becc270b2a328056 100644 (file)
@@ -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
index 0d3bbc187dbf86d9bd503e9ea8b0ac92f617fe9c..11106640d66db78c5e685b112048da79042eae88 100644 (file)
@@ -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)
 
index 405e135024870f8348e7de84c78e70c4e12ebeee..a1f48e7b64d016f1cee8c5fb4b13c2be0bcf6af4 100644 (file)
@@ -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:
index cd47b62e7863af1859a725b206225526fa4363e8..5ab098577a57f015040543faf7387960ab46a8cd 100644 (file)
@@ -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)
index 4c3899b144f4147e4c91162962651444ea8d998d..5c84354f1b4dbc5185f27fba40c8a455f06a2adf 100644 (file)
@@ -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 (executable)
index 0000000..01fe8f9
--- /dev/null
@@ -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 <<EOF > $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;