data-in: Make data_in() parameters more uniform.
[pspp] / perl-module / PSPP.xs
index b3ac4cdc31e84670194ede7d254315ab48deea23..bf90d986f327b811fb5f67822d7cf5c332b0c0ca 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010 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
    02110-1301, USA. */
 
 
+#include <config.h>
+
+/* The Gnulib "strftime" module defines my_strftime in <config.h> for use by
+   gl/strftime.c.  Perl also defines my_strftime in embed.h for some other
+   purpose.  The former definition doesn't matter in this file, so suppress it
+   to avoid a compiler warning. */
+#undef my_strftime
+
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
 
-#include <config.h>
-
 #include "ppport.h"
 
 #include "minmax.h"
@@ -164,7 +170,11 @@ void
 onBoot (ver)
  const char *ver
 CODE:
- assert (0 == strcmp (ver, bare_version));
+ /* Check that the version is correct up to the length of 'ver'.
+    This allows PSPP autobuilders to add a "-build#" suffix to the
+    PSPP version without causing failures here. */
+ assert (0 == strncmp (ver, bare_version, strlen (ver)));
+
  i18n_init ();
  msg_init (NULL, message_handler);
  settings_init (0, 0);
@@ -177,11 +187,10 @@ format_value (val, var)
 CODE:
  SV *ret;
  const struct fmt_spec *fmt = var_get_print_format (var);
- const struct dictionary *dict = var_get_vardict (var)->dict;
  union value uv;
  char *s;
  make_value_from_scalar (&uv, val, var);
- s = data_out (&uv, dict_get_encoding (dict), fmt);
+ s = data_out (&uv, var_get_encoding (var), fmt);
  value_destroy (&uv, var_get_width (var));
  ret = newSVpv (s, fmt->w);
  free (s);
@@ -373,6 +382,37 @@ clear_value_labels (var)
 CODE:
  var_clear_value_labels (var);
 
+SV *
+get_write_format (var)
+ struct variable *var
+CODE:
+ HV *fmthash = (HV *) sv_2mortal ((SV *) newHV());
+ const struct fmt_spec *fmt = var_get_write_format (var);
+
+ hv_store (fmthash, "fmt", 3, newSVnv (fmt->type), 0);
+ hv_store (fmthash, "decimals", 8, newSVnv (fmt->d), 0);
+ hv_store (fmthash, "width", 5, newSVnv (fmt->w), 0);
+
+ RETVAL = newRV ((SV *) fmthash);
+ OUTPUT:
+RETVAL
+
+SV *
+get_print_format (var)
+ struct variable *var
+CODE:
+ HV *fmthash = (HV *) sv_2mortal ((SV *) newHV());
+ const struct fmt_spec *fmt = var_get_print_format (var);
+
+ hv_store (fmthash, "fmt", 3, newSVnv (fmt->type), 0);
+ hv_store (fmthash, "decimals", 8, newSVnv (fmt->d), 0);
+ hv_store (fmthash, "width", 5, newSVnv (fmt->w), 0);
+
+ RETVAL = newRV ((SV *) fmthash);
+ OUTPUT:
+RETVAL
+
+
 void
 pxs_set_write_format (var, fmt)
  struct variable *var
@@ -549,6 +589,7 @@ CODE:
  struct file_handle *fh =
   fh_create_file (NULL, name, fh_default_properties () );
  struct sysfile_info *sfi = xmalloc (sizeof (*sfi));
+ dict_set_encoding (dict, "UTF-8");
  sfi->writer = sfm_open_writer (fh, dict, opts);
  sfi->dict = dict;
  sfi->opened = true;
@@ -613,10 +654,9 @@ CODE:
     if ( ifmt )
       {
        struct substring ss = ss_cstr (SvPV_nolen (sv));
-       if ( ! data_in (ss, LEGACY_NATIVE, ifmt->type, 0, 0, 0,
-                       sfi->dict,
-                       case_data_rw (c, v),
-                       var_get_width (v)) )
+       if ( ! data_in (ss, LEGACY_NATIVE, ifmt->type, 0, 0,
+                       case_data_rw (c, v), var_get_width (v),
+                       dict_get_encoding (sfi->dict)))
          {
            RETVAL = 0;
            goto finish;