Fixed a bug causing pspp to crash when computed variables had no format
[pspp-builds.git] / src / vfm.c
index 65df0dd0f2aff2e37ae5ef5ba389037f6e93119f..42e6b7ccd29dfef5e2b5792cbe16c705fdceaec9 100644 (file)
--- a/src/vfm.c
+++ b/src/vfm.c
@@ -28,7 +28,6 @@
 #include <unistd.h>    /* Required by SunOS4. */
 #endif
 #include "alloc.h"
-#include "approx.h"
 #include "do-ifP.h"
 #include "error.h"
 #include "expr.h"
@@ -112,7 +111,7 @@ static int exclude_this_case (void);
 
 /* Reads all the cases from the active file, transforms them by
    the active set of transformations, calls PROCFUNC with CURCASE
-   set to the case , and writes them to a new active file.
+   set to the case, and writes them to a new active file.
 
    Divides the active file into zero or more series of one or more
    cases each.  BEGINFUNC is called before each series.  ENDFUNC is
@@ -126,9 +125,13 @@ procedure (void (*beginfunc) (void *),
           void (*endfunc) (void *),
            void *aux)
 {
+  static int recursive_call;
+
   struct write_case_data procedure_write_data;
   struct write_case_data split_file_data;
 
+  assert (++recursive_call == 1);
+
   if (dict_get_split_cnt (default_dict) == 0) 
     {
       /* Normally we just use the data passed by the user. */
@@ -156,6 +159,8 @@ procedure (void (*beginfunc) (void *),
   open_active_file ();
   vfm_source->read (procedure_write_case, &procedure_write_data);
   close_active_file (&procedure_write_data);
+
+  assert (--recursive_call == 0);
 }
 \f
 /* Active file processing support.  Subtly different semantics from
@@ -275,10 +280,8 @@ prepare_for_writing (void)
      file--it's just a waste of time and space. */
 
   vfm_sink_info.ncases = 0;
-  vfm_sink_info.nval = dict_get_value_cnt (default_dict);
-  vfm_sink_info.case_size = (sizeof (struct ccase)
-                            + ((dict_get_value_cnt (default_dict) - 1)
-                                * sizeof (union value)));
+  vfm_sink_info.nval = dict_get_next_value_idx (default_dict);
+  vfm_sink_info.case_size = dict_get_case_size (default_dict);
   
   if (vfm_sink == NULL)
     {
@@ -318,14 +321,17 @@ arrange_compaction (void)
             count_values += v->nv;
           } 
       }
-    assert (temporary == 2 || count_values <= dict_get_value_cnt (temp_dict));
+    assert (temporary == 2
+            || count_values <= dict_get_next_value_idx (temp_dict));
   }
   
   /* Compaction is only necessary if the number of `value's to output
      differs from the number already present. */
   compaction_nval = count_values;
-  compaction_necessary = (temporary == 2
-                          || count_values != dict_get_value_cnt (temp_dict));
+  if (temporary == 2 || count_values != dict_get_next_value_idx (temp_dict))
+    compaction_necessary = 1;
+  else
+    compaction_necessary = 0;
   
   if (vfm_sink->init)
     vfm_sink->init ();
@@ -399,8 +405,7 @@ setup_lag (void)
   lag_head = 0;
   lag_queue = xmalloc (n_lag * sizeof *lag_queue);
   for (i = 0; i < n_lag; i++)
-    lag_queue[i] = xmalloc (dict_get_value_cnt (temp_dict)
-                            * sizeof **lag_queue);
+    lag_queue[i] = xmalloc (dict_get_case_size (temp_dict));
 }
 
 /* There is a lot of potential confusion in the vfm and related
@@ -881,7 +886,7 @@ lag_case (void)
   if (lag_count < n_lag)
     lag_count++;
   memcpy (lag_queue[lag_head], temp_case,
-          sizeof (union value) * dict_get_value_cnt (temp_dict));
+          dict_get_case_size (temp_dict));
   if (++lag_head >= n_lag)
     lag_head = 0;
 }
@@ -1091,12 +1096,7 @@ dump_splits (struct ccase *c)
       assert (v->type == NUMERIC || v->type == ALPHA);
       tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", v->name);
       
-      {
-       union value val = c->data[v->fv];
-       if (v->type == ALPHA)
-         val.c = c->data[v->fv].s;
-       data_out (temp_buf, &v->print, &val);
-      }
+      data_out (temp_buf, &v->print, &c->data[v->fv]);
       
       temp_buf[v->print.w] = 0;
       tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", v->print.w, temp_buf);
@@ -1148,7 +1148,7 @@ SPLIT_FILE_procfunc (struct ccase *c, void *data_)
       switch (v->type)
        {
        case NUMERIC:
-         if (approx_ne (c->data[v->fv].f, prev_case->data[v->fv].f))
+         if (c->data[v->fv].f != prev_case->data[v->fv].f)
            goto not_equal;
          break;
        case ALPHA: