Fix bug #6113.
[pspp-builds.git] / src / data / por-file-writer.c
index f17ae5c8f09fee6e7632b6f0cdeb5183ca4d1392..0bb1df60251929d656d8c8241cfca336971abad6 100644 (file)
@@ -1,20 +1,18 @@
-/* PSPP - computes sample statistics.
+/* PSPP - a program for statistical analysis.
    Copyright (C) 1997-9, 2000, 2006 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
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
    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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
 #include "por-file-writer.h"
@@ -37,6 +35,7 @@
 #include <data/file-handle-def.h>
 #include <data/format.h>
 #include <data/missing-values.h>
+#include <data/short-names.h>
 #include <data/value-labels.h>
 #include <data/variable.h>
 
@@ -51,6 +50,9 @@
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
+/* Maximum width of a variable in a portable file. */
+#define MAX_POR_WIDTH 255
+
 /* Portable file writer. */
 struct pfm_writer
   {
@@ -140,7 +142,7 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict,
     {
       const struct variable *dv = dict_get_var (dict, i);
       struct pfm_var *pv = &w->vars[i];
-      pv->width = var_get_width (dv);
+      pv->width = MIN (var_get_width (dv), MAX_POR_WIDTH);
       pv->fv = var_get_case_index (dv);
     }
 
@@ -285,13 +287,17 @@ write_version_data (struct pfm_writer *w)
   write_string (w, host_system);
 }
 
-/* Write format F to file H. */
+/* Write format F to file H.  The format is first resized to fit
+   a value of the given WIDTH, which is handy in case F
+   represents a string longer than 255 bytes and thus WIDTH is
+   truncated to 255 bytes.  */
 static void
-write_format (struct pfm_writer *w, const struct fmt_spec *f)
+write_format (struct pfm_writer *w, struct fmt_spec f, int width)
 {
-  write_int (w, fmt_to_io (f->type));
-  write_int (w, f->w);
-  write_int (w, f->d);
+  fmt_resize (&f, width);
+  write_int (w, fmt_to_io (f.type));
+  write_int (w, f.w);
+  write_int (w, f.d);
 }
 
 /* Write value V for variable VV to file H. */
@@ -302,8 +308,9 @@ write_value (struct pfm_writer *w, union value *v, struct variable *vv)
     write_float (w, v->f);
   else
     {
-      write_int (w, var_get_width (vv));
-      buf_write (w, v->s, var_get_width (vv));
+      int width = MIN (var_get_width (vv), MAX_POR_WIDTH);
+      write_int (w, width);
+      buf_write (w, v->s, width);
     }
 }
 
@@ -313,8 +320,14 @@ write_variables (struct pfm_writer *w, struct dictionary *dict)
 {
   int i;
 
-  dict_assign_short_names (dict);
+  short_names_assign (dict);
 
+  if (dict_get_weight (dict) != NULL) 
+    {
+      buf_write (w, "6", 1);
+      write_string (w, var_get_short_name (dict_get_weight (dict), 0));
+    }
+  
   buf_write (w, "4", 1);
   write_int (w, dict_get_var_cnt (dict));
   write_int (w, 161);
@@ -323,12 +336,13 @@ write_variables (struct pfm_writer *w, struct dictionary *dict)
     {
       struct variable *v = dict_get_var (dict, i);
       struct missing_values mv;
+      int width = MIN (var_get_width (v), MAX_POR_WIDTH);
 
       buf_write (w, "7", 1);
-      write_int (w, var_get_width (v));
-      write_string (w, var_get_short_name (v));
-      write_format (w, var_get_print_format (v));
-      write_format (w, var_get_write_format (v));
+      write_int (w, width);
+      write_string (w, var_get_short_name (v, 0));
+      write_format (w, *var_get_print_format (v), width);
+      write_format (w, *var_get_write_format (v), width);
 
       /* Write missing values. */
       mv_copy (&mv, var_get_missing_values (v));
@@ -388,7 +402,7 @@ write_value_labels (struct pfm_writer *w, const struct dictionary *dict)
 
       buf_write (w, "D", 1);
       write_int (w, 1);
-      write_string (w, var_get_short_name (v));
+      write_string (w, var_get_short_name (v, 0));
       write_int (w, val_labs_count (val_labs));
 
       for (vl = val_labs_first_sorted (val_labs, &j); vl != NULL;