FACTOR: Avoid assertion failures on syntax errors expecting numbers.
[pspp] / src / language / stats / factor.c
index c3a7e8ee2418b889499080e283d31c3dbe1c5cd3..ed10d16d6d25ee24ed98bf9770eb7b90e2560355 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2011, 2012, 2014, 2015, 2016 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
@@ -316,7 +316,7 @@ ssq_od_n (const gsl_matrix *m, int n)
 
 
 
-#if 1
+#if 0
 static void
 dump_matrix (const gsl_matrix *m)
 {
@@ -904,6 +904,23 @@ rotate (const struct cmd_factor *cf, const gsl_matrix *unrot,
                              pm1);
 
       gsl_matrix_memcpy (result, pm1);
+
+
+      gsl_matrix_free (QQinv);
+      gsl_matrix_free (C);
+      gsl_matrix_free (Cinv);
+
+      gsl_matrix_free (D);
+      gsl_matrix_free (Q);
+      gsl_matrix_free (L);
+      gsl_matrix_free (P);
+
+      gsl_permutation_free (perm);
+
+      gsl_matrix_free (mm1);
+      gsl_matrix_free (mm2);
+      gsl_matrix_free (mp1);
+      gsl_matrix_free (pm1);
     }
 
 
@@ -1034,7 +1051,28 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
     {
       lex_match (lexer, T_SLASH);
 
-      if (lex_match_id (lexer, "PLOT"))
+      if (lex_match_id (lexer, "ANALYSIS"))
+        {
+          struct const_var_set *vs;
+          const struct variable **vars;
+          size_t n_vars;
+          bool ok;
+
+          lex_match (lexer, T_EQUALS);
+
+          vs = const_var_set_create_from_array (factor.vars, factor.n_vars);
+          ok = parse_const_var_set_vars (lexer, vs, &vars, &n_vars,
+                                         PV_NO_DUPLICATE | PV_NUMERIC);
+          const_var_set_destroy (vs);
+
+          if (!ok)
+            goto error;
+
+          free (factor.vars);
+          factor.vars = vars;
+          factor.n_vars = n_vars;
+        }
+      else if (lex_match_id (lexer, "PLOT"))
        {
           lex_match (lexer, T_EQUALS);
           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
@@ -1096,9 +1134,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
              else if (lex_match_id (lexer, "PROMAX"))
                {
                  factor.promax_power = 5;
-                 if (lex_match (lexer, T_LPAREN))
+                 if (lex_match (lexer, T_LPAREN)
+                      && lex_force_int (lexer))
                    {
-                     lex_force_int (lexer);
                      factor.promax_power = lex_integer (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
@@ -1124,9 +1162,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
            {
              if (lex_match_id (lexer, "FACTORS"))
                {
-                 if ( lex_force_match (lexer, T_LPAREN))
+                 if ( lex_force_match (lexer, T_LPAREN)
+                       && lex_force_int (lexer))
                    {
-                     lex_force_int (lexer);
                      factor.n_factors = lex_integer (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
@@ -1134,9 +1172,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
                }
              else if (lex_match_id (lexer, "MINEIGEN"))
                {
-                 if ( lex_force_match (lexer, T_LPAREN))
+                 if ( lex_force_match (lexer, T_LPAREN)
+                       && lex_force_num (lexer))
                    {
-                     lex_force_num (lexer);
                      factor.min_eigen = lex_number (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
@@ -1144,29 +1182,29 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
                }
              else if (lex_match_id (lexer, "ECONVERGE"))
                {
-                 if ( lex_force_match (lexer, T_LPAREN))
+                 if ( lex_force_match (lexer, T_LPAREN)
+                       && lex_force_num (lexer))
                    {
-                     lex_force_num (lexer);
                      factor.econverge = lex_number (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
                    }
                }
              else if (lex_match_id (lexer, "RCONVERGE"))
-               {
-                 if ( lex_force_match (lexer, T_LPAREN))
-                   {
-                     lex_force_num (lexer);
-                     factor.rconverge = lex_number (lexer);
-                     lex_get (lexer);
-                     lex_force_match (lexer, T_RPAREN);
-                   }
+                {
+                  if (lex_force_match (lexer, T_LPAREN)
+                      && lex_force_num (lexer))
+                    {
+                      factor.rconverge = lex_number (lexer);
+                      lex_get (lexer);
+                      lex_force_match (lexer, T_RPAREN);
+                    }
                }
              else if (lex_match_id (lexer, "ITERATE"))
                {
-                 if ( lex_force_match (lexer, T_LPAREN))
+                 if ( lex_force_match (lexer, T_LPAREN)
+                       && lex_force_int (lexer))
                    {
-                     lex_force_int (lexer);
                      n_iterations = lex_integer (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
@@ -1225,9 +1263,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
                }
              else if (lex_match_id (lexer, "BLANK"))
                {
-                 if ( lex_force_match (lexer, T_LPAREN))
+                 if ( lex_force_match (lexer, T_LPAREN)
+                       && lex_force_num (lexer))
                    {
-                     lex_force_num (lexer);
                      factor.blank = lex_number (lexer);
                      lex_get (lexer);
                      lex_force_match (lexer, T_RPAREN);
@@ -1830,12 +1868,12 @@ show_factor_correlation (const struct cmd_factor * factor, const gsl_matrix *fcm
 
   for (i = 0 ; i < fcm->size1; ++i)
     {
-      tab_text_format (t, heading_columns + i, 0, TAB_CENTER | TAT_TITLE, _("%d"), i + 1);
+      tab_text_format (t, heading_columns + i, 0, TAB_CENTER | TAT_TITLE, _("%zu"), i + 1);
     }
 
   for (i = 0 ; i < fcm->size2; ++i)
     {
-      tab_text_format (t, 0, heading_rows + i, TAB_CENTER | TAT_TITLE, _("%d"), i + 1);
+      tab_text_format (t, 0, heading_rows + i, TAB_CENTER | TAT_TITLE, _("%zu"), i + 1);
     }