pivot table procedure conceptually works
[pspp] / perl-module / PSPP.xs
index 874bd3bcad22274506f6c9db7db378e8a2341190..7577b7ad2c7be4d54b37fad06013aca3d6be0332 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -46,7 +46,6 @@
 #include <data/identifier.h>
 #include <data/settings.h>
 #include <data/sys-file-writer.h>
-#include <data/sys-file-reader.h>
 #include <data/value.h>
 #include <data/vardict.h>
 #include <data/value-labels.h>
@@ -78,7 +77,7 @@ struct syswriter_info
 /*  A thin wrapper around sfm_reader */
 struct sysreader_info
 {
-  struct sfm_read_info opts;
+  struct any_read_info opts;
 
   /* A pointer to the reader. The reader is owned by the struct */
   struct casereader *reader;
@@ -88,10 +87,16 @@ struct sysreader_info
 };
 
 
+struct input_format {
+  struct hmap_node hmap_node;   /* In struct pspp_dict's input_formats map. */
+  const struct variable *var;
+  struct fmt_spec input_format;
+};
 
 /* A thin wrapper around struct dictionary.*/
 struct pspp_dict {
   struct dictionary *dict;
+  struct hmap input_formats;   /* Contains struct input_format. */
 };
 
 
@@ -156,14 +161,6 @@ value_to_scalar (const union value *val, const struct variable *var)
 }
 
 
-static void
-var_set_input_format (struct variable *v, input_format ip_fmt)
-{
-  struct fmt_spec *if_copy = malloc (sizeof (*if_copy));
-  memcpy (if_copy, &ip_fmt, sizeof (ip_fmt));
-  var_attach_aux (v, if_copy, var_dtor_free);
-}
-
 static void
 make_value_from_scalar (union value *uv, SV *val, const struct variable *var)
 {
@@ -176,9 +173,23 @@ create_pspp_dict (struct dictionary *dict)
 {
   struct pspp_dict *pspp_dict = xmalloc (sizeof *pspp_dict);
   pspp_dict->dict = dict;
+  hmap_init (&pspp_dict->input_formats);
   return pspp_dict;
 }
 
+static const struct fmt_spec *
+find_input_format (const struct pspp_dict *dict, const struct variable *var)
+{
+  struct input_format *input_format;
+
+  HMAP_FOR_EACH_IN_BUCKET (input_format, struct input_format, hmap_node,
+                           hash_pointer (var, 0), &dict->input_formats)
+    if (input_format->var == var)
+      return &input_format->input_format;
+
+  return NULL;
+}
+
 
 MODULE = PSPP
 
@@ -251,6 +262,15 @@ DESTROY (dict)
 CODE:
  if (dict != NULL)
    {
+     struct input_format *input_format, *next_input_format;
+
+     HMAP_FOR_EACH_SAFE (input_format, next_input_format,
+                        struct input_format, hmap_node, &dict->input_formats)
+       {
+         hmap_delete (&dict->input_formats, &input_format->hmap_node);
+        free (input_format);
+       }
+     hmap_destroy (&dict->input_formats);
      dict_destroy (dict->dict);
      free (dict);
    }
@@ -353,6 +373,7 @@ INIT:
   }
 CODE:
  struct fmt_spec op_fmt;
+ struct input_format *input_format;
 
  struct variable *v;
  op_fmt = fmt_for_output_from_input (&ip_fmt);
@@ -364,7 +385,13 @@ CODE:
     XSRETURN_UNDEF;
   }
  var_set_both_formats (v, &op_fmt);
- var_set_input_format (v, ip_fmt);
+
+ input_format = xmalloc (sizeof *input_format);
+ input_format->var = v;
+ input_format->input_format = ip_fmt;
+ hmap_insert (&dict->input_formats, &input_format->hmap_node,
+              hash_pointer (v, 0));
+
  RETVAL = v;
 OUTPUT:
  RETVAL
@@ -396,7 +423,7 @@ set_label (var, label)
  struct variable *var;
  char *label
 CODE:
-  var_set_label (var, label, false);
+  var_set_label (var, label);
 
 
 void
@@ -604,7 +631,9 @@ INIT:
     SV** version = hv_fetch(opt_h, "version", 7, 0);
 
     opts.create_writeable = readonly ? ! SvIV (*readonly) : true;
-    opts.compress = compress ? SvIV (*compress) : false;
+    opts.compression = (compress && SvIV (*compress)
+                        ? ANY_COMP_SIMPLE
+                       : ANY_COMP_NONE);
     opts.version = version ? SvIV (*version) : 3 ;
   }
 CODE:
@@ -668,7 +697,7 @@ CODE:
  for (sv = av_shift (av_case); SvOK (sv);  sv = av_shift (av_case))
  {
     const struct variable *v = vv[i++];
-    const struct fmt_spec *ifmt = var_get_aux (v);
+    const struct fmt_spec *ifmt = find_input_format (swi->dict, v);
 
     /* If an input format has been set, then use it.
        Otherwise just convert the raw value.
@@ -727,9 +756,8 @@ CODE:
  struct dictionary *dict;
 
  sri = xmalloc (sizeof (*sri));
- sri->reader = sfm_open_reader (fh, NULL, &dict, &sri->opts);
-
- if ( sri->reader != NULL)
+ sri->reader = any_reader_open_and_decode (fh, NULL, &dict, &sri->opts);
+ if (sri->reader)
    sri->dict = create_pspp_dict (dict);
  else
    {