made matrix argument const in coefficient initialization
[pspp-builds.git] / src / math / sort.c
index 9725da80a1a9896149636905599319f9e5d9c229..3ce5da5707cb2ab1d3508eadf3c48a7ad5b6f0a2 100644 (file)
 #include <data/case-source.h>
 #include <data/case.h>
 #include <data/casefile.h>
+#include <data/procedure.h>
 #include <data/settings.h>
 #include <data/variable.h>
 #include <data/storage-stream.h>
 #include <language/expressions/public.h>
 #include <libpspp/alloc.h>
 #include <libpspp/array.h>
+#include <libpspp/assertion.h>
 #include <libpspp/message.h>
 #include <libpspp/message.h>
 #include <libpspp/misc.h>
 #include <libpspp/str.h>
-#include <procedure.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -57,24 +58,11 @@ static struct casefile *do_internal_sort (struct casereader *,
 static struct casefile *do_external_sort (struct casereader *,
                                           const struct sort_criteria *);
 
-/* Gets ready to sort the active file, either in-place or to a
-   separate casefile. */
-static bool
+/* Get ready to sort the active file. */
+static void
 prepare_to_sort_active_file (void) 
 {
-  bool ok;
-  
-  /* Cancel temporary transformations and PROCESS IF. */
-  if (temporary != 0)
-    cancel_temporary (); 
-  expr_free (process_if_expr);
-  process_if_expr = NULL;
-
-  /* Make sure source cases are in a storage source. */
-  ok = procedure (NULL, NULL);
-  assert (case_source_is_class (vfm_source, &storage_source_class));
-
-  return ok;
+  proc_cancel_temporary_transformations (); 
 }
 
 /* Sorts the active file in-place according to CRITERIA.
@@ -82,21 +70,35 @@ prepare_to_sort_active_file (void)
 int
 sort_active_file_in_place (const struct sort_criteria *criteria) 
 {
-  struct casefile *src, *dst;
+  struct casefile *in, *out;
+
+  prepare_to_sort_active_file ();
+  if (!procedure (NULL, NULL))
+    return 0;
   
-  if (!prepare_to_sort_active_file ())
+  in = proc_capture_output ();
+  out = sort_execute (casefile_get_destructive_reader (in), criteria);
+  if (out == NULL) 
     return 0;
 
-  src = storage_source_get_casefile (vfm_source);
-  dst = sort_execute (casefile_get_destructive_reader (src), criteria);
-  free_case_source (vfm_source);
-  vfm_source = NULL;
+  proc_set_source (storage_source_create (out));
+  return 1;
+}
 
-  if (dst == NULL) 
-    return 0;
+/* Data passed to sort_to_casefile_callback(). */
+struct sort_to_casefile_cb_data 
+  {
+    const struct sort_criteria *criteria;
+    struct casefile *output;
+  };
 
-  vfm_source = storage_source_create (dst);
-  return 1;
+/* Sorts casefile CF according to the criteria in CB_DATA. */
+static bool
+sort_to_casefile_callback (const struct casefile *cf, void *cb_data_) 
+{
+  struct sort_to_casefile_cb_data *cb_data = cb_data_;
+  cb_data->output = sort_execute (casefile_get_reader (cf), cb_data->criteria);
+  return cb_data->output != NULL;
 }
 
 /* Sorts the active file to a separate casefile.  If successful,
@@ -105,13 +107,18 @@ sort_active_file_in_place (const struct sort_criteria *criteria)
 struct casefile *
 sort_active_file_to_casefile (const struct sort_criteria *criteria) 
 {
-  struct casefile *src;
+  struct sort_to_casefile_cb_data cb_data;
   
-  if (!prepare_to_sort_active_file ())
-    return NULL;
+  prepare_to_sort_active_file ();
 
-  src = storage_source_get_casefile (vfm_source);
-  return sort_execute (casefile_get_reader (src), criteria);
+  cb_data.criteria = criteria;
+  cb_data.output = NULL;
+  if (!multipass_procedure (sort_to_casefile_callback, &cb_data)) 
+    {
+      casefile_destroy (cb_data.output);
+      return NULL;
+    }
+  return cb_data.output;
 }
 
 
@@ -167,7 +174,7 @@ do_internal_sort (struct casereader *reader,
             {
               bool ok = casereader_read_xfer (reader, &cases[i].c);
               if (!ok)
-                abort ();
+                NOT_REACHED ();
               cases[i].idx = i;
             }
 
@@ -177,7 +184,7 @@ do_internal_sort (struct casereader *reader,
           for (i = 0; i < case_cnt; i++)
             casefile_append_xfer (dst, &cases[i].c);
           if (casefile_error (dst))
-            abort ();
+            NOT_REACHED ();
 
           free (cases);
         }