Add scratch file handles.
[pspp-builds.git] / src / aggregate.c
index fb955330a4102e0aea3f13156573f4d9414a2438..67e8bb91b1c4e27d2006d1e8e7e08646dafb13e9 100644 (file)
 
    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 "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "any-writer.h"
 #include "case.h"
 #include "casefile.h"
 #include "command.h"
 #include "pool.h"
 #include "settings.h"
 #include "sfm-write.h"
+#include "sort-prs.h"
 #include "sort.h"
 #include "str.h"
 #include "var.h"
 #include "vfm.h"
 #include "vfmP.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /* Specifies how to make an aggregate variable. */
 struct agr_var
   {
@@ -73,7 +78,7 @@ enum
 struct agr_func
   {
     const char *name;          /* Aggregation function name. */
-    int n_args;                        /* Number of arguments. */
+    size_t n_args;              /* Number of arguments. */
     int alpha_type;            /* When given ALPHA arguments, output type. */
     struct fmt_spec format;    /* Format spec if alpha_type != ALPHA. */
   };
@@ -117,7 +122,7 @@ enum missing_treatment
 struct agr_proc 
   {
     /* We have either an output file or a sink. */
-    struct sfm_writer *writer;          /* Output file, or null if none. */
+    struct any_writer *writer;          /* Output file, or null if none. */
     struct case_sink *sink;             /* Sink, or null if none. */
 
     /* Break variables. */
@@ -177,7 +182,7 @@ cmd_aggregate (void)
   lex_match ('=');
   if (!lex_match ('*'))
     {
-      out_file = fh_parse ();
+      out_file = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
       if (out_file == NULL)
         goto error;
     }
@@ -208,18 +213,13 @@ cmd_aggregate (void)
          lex_match ('=');
           agr.sort = sort_parse_criteria (default_dict,
                                           &agr.break_vars, &agr.break_var_cnt,
-                                          &saw_direction);
+                                          &saw_direction, NULL);
           if (agr.sort == NULL)
             goto error;
          
           for (i = 0; i < agr.break_var_cnt; i++)
-            {
-              struct variable *v = dict_clone_var (agr.dict, agr.break_vars[i],
-                                                   agr.break_vars[i]->name, 
-                                                  agr.break_vars[i]->longname 
-                                                  );
-              assert (v != NULL);
-            }
+            dict_clone_var_assert (agr.dict, agr.break_vars[i],
+                                   agr.break_vars[i]->name);
 
           /* BREAK must follow the options. */
           break;
@@ -279,7 +279,7 @@ cmd_aggregate (void)
     }
   else
     {
-      agr.writer = sfm_open_writer (out_file, agr.dict, get_scompression (), 0);
+      agr.writer = any_writer_open (out_file, agr.dict);
       if (agr.writer == NULL)
         goto error;
       
@@ -297,7 +297,7 @@ cmd_aggregate (void)
           while (casereader_read_xfer (reader, &c)) 
             {
               if (aggregate_single_case (&agr, &c, &agr.agr_case)) 
-                sfm_write_case (agr.writer, &agr.agr_case);
+                any_writer_write (agr.writer, &agr.agr_case);
               case_destroy (&c);
             }
           casereader_destroy (reader);
@@ -312,7 +312,7 @@ cmd_aggregate (void)
       if (agr.case_cnt > 0) 
         {
           dump_aggregate_info (&agr, &agr.agr_case);
-          sfm_write_case (agr.writer, &agr.agr_case);
+          any_writer_write (agr.writer, &agr.agr_case);
         }
     }
   
@@ -336,7 +336,7 @@ parse_aggregate_functions (struct agr_proc *agr)
     {
       char **dest;
       char **dest_label;
-      int n_dest;
+      size_t n_dest;
 
       int include_missing;
       const struct agr_func *function;
@@ -345,9 +345,9 @@ parse_aggregate_functions (struct agr_proc *agr)
       union value arg[2];
 
       struct variable **src;
-      int n_src;
+      size_t n_src;
 
-      int i;
+      size_t i;
 
       dest = NULL;
       dest_label = NULL;
@@ -361,7 +361,7 @@ parse_aggregate_functions (struct agr_proc *agr)
       /* Parse the list of target variables. */
       while (!lex_match ('='))
        {
-         int n_dest_prev = n_dest;
+         size_t n_dest_prev = n_dest;
          
          if (!parse_DATA_LIST_vars (&dest, &n_dest,
                                      PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
@@ -371,7 +371,7 @@ parse_aggregate_functions (struct agr_proc *agr)
          {
            int j;
 
-           dest_label = xrealloc (dest_label, sizeof *dest_label * n_dest);
+           dest_label = xnrealloc (dest_label, n_dest, sizeof *dest_label);
            for (j = n_dest_prev; j < n_dest; j++)
              dest_label[j] = NULL;
          }
@@ -455,7 +455,8 @@ parse_aggregate_functions (struct agr_proc *agr)
                    arg[i].f = tokval;
                    type = NUMERIC;
                  } else {
-                   msg (SE, _("Missing argument %d to %s."), i + 1, function->name);
+                   msg (SE, _("Missing argument %d to %s."), i + 1,
+                         function->name);
                    goto error;
                  }
            
@@ -485,9 +486,9 @@ parse_aggregate_functions (struct agr_proc *agr)
             like `unknown variable t'. */
          if (n_src != n_dest)
            {
-             msg (SE, _("Number of source variables (%d) does not match "
-                        "number of target variables (%d)."),
-                  n_src, n_dest);
+             msg (SE, _("Number of source variables (%u) does not match "
+                        "number of target variables (%u)."),
+                  (unsigned) n_src, (unsigned) n_dest);
              goto error;
            }
 
@@ -495,8 +496,7 @@ parse_aggregate_functions (struct agr_proc *agr)
               || func_index == FIN || func_index == FOUT) 
               && ((src[0]->type == NUMERIC && arg[0].f > arg[1].f)
                   || (src[0]->type == ALPHA
-                      && st_compare_pad (arg[0].c, strlen (arg[0].c),
-                                         arg[1].c, strlen (arg[1].c)) > 0)))
+                      && str_compare_rpad (arg[0].c, arg[1].c) > 0)))
             {
               union value t = arg[0];
               arg[0] = arg[1];
@@ -527,7 +527,6 @@ parse_aggregate_functions (struct agr_proc *agr)
          /* Create the target variable in the aggregate
              dictionary. */
          {
-            static const struct fmt_spec f8_2 = {FMT_F, 8, 2};
            struct variable *destvar;
            
            v->function = func_index;
@@ -543,10 +542,11 @@ parse_aggregate_functions (struct agr_proc *agr)
                  }
 
                if (function->alpha_type == ALPHA)
-                 destvar = dict_clone_var (agr->dict, v->src, 0, dest[i] );
-               else if (v->src->type == NUMERIC
-                         || function->alpha_type == NUMERIC)
+                 destvar = dict_clone_var (agr->dict, v->src, dest[i]);
+               else
                   {
+                    assert (v->src->type == NUMERIC
+                            || function->alpha_type == NUMERIC);
                     destvar = dict_create_var (agr->dict, dest[i], 0);
                     if (destvar != NULL) 
                       {
@@ -652,7 +652,7 @@ agr_destroy (struct agr_proc *agr)
 {
   struct agr_var *iter, *next;
 
-  sfm_close_writer (agr->writer);
+  any_writer_close (agr->writer);
   if (agr->sort != NULL)
     sort_destroy_criteria (agr->sort);
   free (agr->break_vars);
@@ -663,8 +663,8 @@ agr_destroy (struct agr_proc *agr)
 
       if (iter->function & FSTRING)
        {
-         int n_args;
-         int i;
+         size_t n_args;
+         size_t i;
 
          n_args = agr_func_tab[iter->function & FUNC].n_args;
          for (i = 0; i < n_args; i++)
@@ -727,7 +727,8 @@ accumulate_aggregate_info (struct agr_proc *agr,
       {
        const union value *v = case_data (input, iter->src->fv);
 
-       if ((!iter->include_missing && is_missing (v, iter->src))
+       if ((!iter->include_missing
+             && mv_is_value_missing (&iter->src->miss, v))
            || (iter->include_missing && iter->src->type == NUMERIC
                && v->f == SYSMIS))
          {
@@ -1074,7 +1075,7 @@ presorted_agr_to_sysfile (struct ccase *c, void *agr_)
   struct agr_proc *agr = agr_;
 
   if (aggregate_single_case (agr, c, &agr->agr_case)) 
-    sfm_write_case (agr->writer, &agr->agr_case);
+    any_writer_write (agr->writer, &agr->agr_case);
 
   return 1;
 }