fbuf: New data structure for buffered file I/O.
[pspp] / src / data / por-file-writer.c
index 9889cfd95378ed7593c1cfbb2ba9ad187427d06f..1853ad3a56a5877e265abbff7b2f5caa35313112 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 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
@@ -15,7 +15,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
-#include "por-file-writer.h"
+
+#include "data/por-file-writer.h"
 
 #include <ctype.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <time.h>
 
-#include <data/case.h>
-#include <data/casewriter-provider.h>
-#include <data/casewriter.h>
-#include <data/dictionary.h>
-#include <data/file-handle-def.h>
-#include <data/file-name.h>
-#include <data/format.h>
-#include <data/make-file.h>
-#include <data/missing-values.h>
-#include <data/short-names.h>
-#include <data/value-labels.h>
-#include <data/variable.h>
-
-#include <libpspp/message.h>
-#include <libpspp/misc.h>
-#include <libpspp/str.h>
-#include <libpspp/version.h>
-
-#include "minmax.h"
-#include "xalloc.h"
+#include "data/case.h"
+#include "data/casewriter-provider.h"
+#include "data/casewriter.h"
+#include "data/dictionary.h"
+#include "data/file-handle-def.h"
+#include "data/format.h"
+#include "data/make-file.h"
+#include "data/missing-values.h"
+#include "data/short-names.h"
+#include "data/value-labels.h"
+#include "data/variable.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
+#include "libpspp/str.h"
+#include "libpspp/version.h"
+
+#include "gl/minmax.h"
+#include "gl/xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -74,7 +73,7 @@ struct pfm_writer
 struct pfm_var
   {
     int width;                  /* 0=numeric, otherwise string var width. */
-    int fv;                     /* Starting case index. */
+    int case_index;             /* Index in case. */
   };
 
 static const struct casewriter_class por_file_casewriter_class;
@@ -131,7 +130,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 = MIN (var_get_width (dv), MAX_POR_WIDTH);
-      pv->fv = var_get_case_index (dv);
+      pv->case_index = var_get_case_index (dv);
     }
 
   w->digits = opts.digits;
@@ -153,11 +152,10 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict,
   mode = 0444;
   if (opts.create_writeable)
     mode |= 0222;
-  w->rf = replace_file_start (fh_get_file_name (fh), "w", mode,
-                              &w->file, NULL);
+  w->rf = replace_file_start (fh, false, mode, &w->file);
   if (w->rf == NULL)
     {
-      msg (ME, _("Error opening \"%s\" for writing as a portable file: %s."),
+      msg (ME, _("Error opening `%s' for writing as a portable file: %s."),
            fh_get_file_name (fh), strerror (errno));
       goto error;
     }
@@ -328,15 +326,17 @@ write_variables (struct pfm_writer *w, struct dictionary *dict)
 
   short_names_assign (dict);
 
-  if (dict_get_weight (dict) != NULL) 
+  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);
+
+  buf_write (w, "5", 1);
+  write_int (w, ceil (w->digits * (log (10) / log (30))));
 
   for (i = 0; i < dict_get_var_cnt (dict); i++)
     {
@@ -404,6 +404,7 @@ write_value_labels (struct pfm_writer *w, const struct dictionary *dict)
       const struct val_labs *val_labs = var_get_value_labels (v);
       size_t n_labels = val_labs_count (val_labs);
       const struct val_lab **labels;
+      int j;
 
       if (n_labels == 0)
        continue;
@@ -415,11 +416,11 @@ write_value_labels (struct pfm_writer *w, const struct dictionary *dict)
 
       n_labels = val_labs_count (val_labs);
       labels = val_labs_sorted (val_labs);
-      for (i = 0; i < n_labels; i++)
+      for (j = 0; j < n_labels; j++)
         {
-          const struct val_lab *vl = labels[i];
+          const struct val_lab *vl = labels[j];
           write_value (w, val_lab_get_value (vl), var_get_width (v));
-          write_string (w, val_lab_get_label (vl));
+          write_string (w, val_lab_get_escaped_label (vl));
         }
       free (labels);
     }
@@ -436,10 +437,7 @@ write_documents (struct pfm_writer *w, const struct dictionary *dict)
   buf_write (w, "E", 1);
   write_int (w, line_cnt);
   for (i = 0; i < line_cnt; i++)
-    {
-      dict_get_document_line (dict, i, &line);
-      write_string (w, ds_cstr (&line));
-    }
+    write_string (w, dict_get_document_line (dict, i));
   ds_destroy (&line);
 }
 
@@ -458,11 +456,11 @@ por_file_casewriter_write (struct casewriter *writer, void *w_,
           struct pfm_var *v = &w->vars[i];
 
           if (v->width == 0)
-            write_float (w, case_num_idx (c, v->fv));
+            write_float (w, case_num_idx (c, v->case_index));
           else
             {
               write_int (w, v->width);
-              buf_write (w, case_str_idx (c, v->fv), v->width);
+              buf_write (w, case_str_idx (c, v->case_index), v->width);
             }
         }
     }
@@ -502,7 +500,7 @@ close_writer (struct pfm_writer *w)
         ok = false;
 
       if (!ok)
-        msg (ME, _("An I/O error occurred writing portable file \"%s\"."),
+        msg (ME, _("An I/O error occurred writing portable file `%s'."),
              fh_get_file_name (w->fh));
 
       if (ok ? !replace_file_commit (w->rf) : !replace_file_abort (w->rf))