Adopt use of gnulib for portability.
[pspp-builds.git] / src / vfm.c
index 796e3bcff07eda9daac4101bb5793d8721d2dd8f..0414234c01d2be666208fb4c7db1e67c5b315974 100644 (file)
--- a/src/vfm.c
+++ b/src/vfm.c
@@ -14,8 +14,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
 #include <config.h>
 #include "vfm.h"
@@ -42,6 +42,9 @@
 #include "var.h"
 #include "value-labels.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /*
    Virtual File Manager (vfm):
 
@@ -95,7 +98,6 @@ static int execute_transformations (struct ccase *c,
                                     int case_num);
 static int filter_case (const struct ccase *c, int case_num);
 static void lag_case (const struct ccase *c);
-static void compact_case (struct ccase *dest, const struct ccase *src);
 static void clear_case (struct ccase *c);
 static void close_active_file (void);
 \f
@@ -260,7 +262,8 @@ write_case (struct write_case_data *wc_data)
     {
       if (compaction_necessary) 
         {
-          compact_case (&wc_data->sink_case, &wc_data->trns_case);
+          dict_compact_case (temp_dict, &wc_data->sink_case,
+                             &wc_data->trns_case);
           vfm_sink->class->write (vfm_sink, &wc_data->sink_case);
         }
       else
@@ -357,43 +360,6 @@ lag_case (const struct ccase *c)
     lag_head = 0;
 }
 
-/* Copies case SRC to case DEST, compacting it in the process. */
-static void
-compact_case (struct ccase *dest, const struct ccase *src)
-{
-  int i;
-  int nval = 0;
-  size_t var_cnt;
-  
-  assert (compaction_necessary);
-
-  /* Copy all the variables except scratch variables from SRC to
-     DEST. */
-  /* FIXME: this should be temp_dict not default_dict I guess. */
-  var_cnt = dict_get_var_cnt (default_dict);
-  for (i = 0; i < var_cnt; i++)
-    {
-      struct variable *v = dict_get_var (default_dict, i);
-      
-      if (dict_class_from_id (v->name) == DC_SCRATCH)
-       continue;
-
-      if (v->type == NUMERIC) 
-        {
-          case_data_rw (dest, nval)->f = case_num (src, v->fv);
-          nval++; 
-        }
-      else
-       {
-         int w = DIV_RND_UP (v->width, sizeof (union value));
-         
-         memcpy (case_data_rw (dest, nval), case_str (src, v->fv),
-                  w * sizeof (union value));
-         nval += w;
-       }
-    }
-}
-
 /* Clears the variables in C that need to be cleared between
    processing cases.  */
 static void
@@ -443,11 +409,8 @@ close_active_file (void)
     dict_compact_values (default_dict);
     
   /* Free data source. */
-  if (vfm_source != NULL) 
-    {
-      free_case_source (vfm_source);
-      vfm_source = NULL;
-    }
+  free_case_source (vfm_source);
+  vfm_source = NULL;
 
   /* Old data sink becomes new data source. */
   if (vfm_sink->class->make_source != NULL)
@@ -518,7 +481,7 @@ static struct case_source *
 storage_sink_make_source (struct case_sink *sink) 
 {
   struct case_source *source
-    = create_case_source (&storage_source_class, sink->dict, sink->aux);
+    = create_case_source (&storage_source_class, sink->aux);
   sink->aux = NULL;
   return source;
 }
@@ -594,14 +557,14 @@ storage_source_get_casefile (struct case_source *source)
 }
 
 struct case_source *
-storage_source_create (struct casefile *cf, const struct dictionary *dict) 
+storage_source_create (struct casefile *cf)
 {
   struct storage_stream_info *info;
 
   info = xmalloc (sizeof *info);
   info->casefile = cf;
 
-  return create_case_source (&storage_source_class, dict, info);
+  return create_case_source (&storage_source_class, info);
 }
 \f
 /* Null sink.  Used by a few procedures that keep track of output
@@ -622,7 +585,9 @@ const struct case_sink_class null_sink_class =
 struct ccase *
 lagged_case (int n_before)
 {
-  assert (n_before >= 1 && n_before <= n_lag);
+  assert (n_before >= 1 );
+  assert (n_before <= n_lag);
+
   if (n_before <= lag_count)
     {
       int index = lag_head - n_before;
@@ -662,7 +627,7 @@ cancel_transformations (void)
     }
   n_trns = f_trns = 0;
   free (t_trns);
-  t_trns=NULL;
+  t_trns = NULL;
   m_trns = 0;
 }
 \f
@@ -670,12 +635,10 @@ cancel_transformations (void)
    and based on dictionary DICT. */
 struct case_source *
 create_case_source (const struct case_source_class *class,
-                    const struct dictionary *dict,
                     void *aux) 
 {
   struct case_source *source = xmalloc (sizeof *source);
   source->class = class;
-  source->value_cnt = dict_get_next_value_idx (dict);
   source->aux = aux;
   return source;
 }
@@ -709,8 +672,8 @@ case_source_is_class (const struct case_source *source,
   return source != NULL && source->class == class;
 }
 
-/* Creates a case sink with class CLASS and auxiliary data
-   AUX. */
+/* Creates a case sink to accept cases from the given DICT with
+   class CLASS and auxiliary data AUX. */
 struct case_sink *
 create_case_sink (const struct case_sink_class *class,
                   const struct dictionary *dict,
@@ -718,8 +681,6 @@ create_case_sink (const struct case_sink_class *class,
 {
   struct case_sink *sink = xmalloc (sizeof *sink);
   sink->class = class;
-  sink->dict = dict;
-  sink->idx_to_fv = dict_get_compacted_idx_to_fv (dict);
   sink->value_cnt = dict_get_compacted_value_cnt (dict);
   sink->aux = aux;
   return sink;
@@ -733,7 +694,6 @@ free_case_sink (struct case_sink *sink)
     {
       if (sink->class->destroy != NULL)
         sink->class->destroy (sink);
-      free (sink->idx_to_fv);
       free (sink); 
     }
 }
@@ -783,10 +743,12 @@ procedure_with_splits (void (*begin_func) (void *aux),
   split_aux.end_func = end_func;
   split_aux.func_aux = func_aux;
 
-  procedure (procedure_with_splits_callback, &split_aux);
-
+  open_active_file ();
+  internal_procedure (procedure_with_splits_callback, &split_aux);
   if (split_aux.case_count > 0 && end_func != NULL)
     end_func (func_aux);
+  close_active_file ();
+
   case_destroy (&split_aux.prev_case);
 }
 
@@ -823,32 +785,9 @@ procedure_with_splits_callback (struct ccase *c, void *split_aux_)
 static int
 equal_splits (const struct ccase *a, const struct ccase *b) 
 {
-  struct variable *const *split;
-  size_t split_cnt;
-  size_t i;
-    
-  split = dict_get_split_vars (default_dict);
-  split_cnt = dict_get_split_cnt (default_dict);
-  for (i = 0; i < split_cnt; i++)
-    {
-      struct variable *v = split[i];
-      
-      switch (v->type)
-       {
-       case NUMERIC:
-         if (case_num (a, v->fv) != case_num (b, v->fv))
-            return 0;
-         break;
-       case ALPHA:
-         if (memcmp (case_str (a, v->fv), case_str (b, v->fv), v->width))
-            return 0;
-         break;
-       default:
-         assert (0);
-       }
-    }
-
-  return 1;
+  return case_compare (a, b,
+                       dict_get_split_vars (default_dict),
+                       dict_get_split_cnt (default_dict)) == 0;
 }
 
 /* Dumps out the values of all the split variables for the case C. */