pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] Changes to pspp/src/pfm-write.c


From: Ben Pfaff
Subject: [Pspp-cvs] Changes to pspp/src/pfm-write.c
Date: Sun, 21 Aug 2005 03:21:09 -0400

Index: pspp/src/pfm-write.c
diff -u pspp/src/pfm-write.c:1.16 pspp/src/pfm-write.c:1.17
--- pspp/src/pfm-write.c:1.16   Sun Aug  7 04:39:28 2005
+++ pspp/src/pfm-write.c        Sun Aug 21 07:21:06 2005
@@ -22,11 +22,14 @@
 #include "error.h"
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <float.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include <time.h>
+#include <unistd.h>
 #include "alloc.h"
 #include "case.h"
 #include "dictionary.h"
@@ -35,6 +38,7 @@
 #include "hash.h"
 #include "magic.h"
 #include "misc.h"
+#include "stat-macros.h"
 #include "str.h"
 #include "value-labels.h"
 #include "var.h"
@@ -55,6 +59,8 @@
 
     size_t var_cnt;             /* Number of variables. */
     struct pfm_var *vars;       /* Variables. */
+
+    int digits;                 /* Digits of precision. */
   };
 
 /* A variable to write to the portable file. */
@@ -73,36 +79,55 @@
 static void format_trig_double (long double, int base_10_precision, char[]);
 static char *format_trig_int (int, bool force_sign, char[]);
 
-/* Writes the dictionary DICT to portable file HANDLE.  Returns
-   nonzero only if successful.  DICT will not be modified, except
-   to assign short names. */
+/* Returns default options for writing a portable file. */
+struct pfm_write_options
+pfm_writer_default_options (void) 
+{
+  struct pfm_write_options opts;
+  opts.create_writeable = true;
+  opts.type = PFM_COMM;
+  opts.digits = DBL_DIG;
+  return opts;
+}
+
+/* Writes the dictionary DICT to portable file HANDLE according
+   to the given OPTS.  Returns nonzero only if successful.  DICT
+   will not be modified, except to assign short names. */
 struct pfm_writer *
-pfm_open_writer (struct file_handle *fh, struct dictionary *dict)
+pfm_open_writer (struct file_handle *fh, struct dictionary *dict,
+                 struct pfm_write_options opts)
 {
   struct pfm_writer *w = NULL;
+  mode_t mode;
+  int fd;
   size_t i;
 
+  /* Create file. */
+  mode = S_IRUSR | S_IRGRP | S_IROTH;
+  if (opts.create_writeable)
+    mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+  fd = open (handle_get_filename (fh), O_WRONLY | O_CREAT | O_TRUNC, mode);
+  if (fd < 0) 
+    goto open_error;
+
+  /* Open file handle. */
   if (!fh_open (fh, "portable file", "we"))
     goto error;
-  
-  /* Open the physical disk file. */
+
+  /* Initialize data structures. */
   w = xmalloc (sizeof *w);
   w->fh = fh;
-  w->file = fopen (handle_get_filename (fh), "wb");
+  w->file = fdopen (fd, "w");
+  if (w->file == NULL) 
+    {
+      close (fd);
+      goto open_error;
+    }
+  
   w->lc = 0;
   w->var_cnt = 0;
   w->vars = NULL;
   
-  /* Check that file create succeeded. */
-  if (w->file == NULL)
-    {
-      msg (ME, _("An error occurred while opening \"%s\" for writing "
-          "as a portable file: %s."),
-           handle_get_filename (fh), strerror (errno));
-      err_cond_fail ();
-      goto error;
-    }
-  
   w->var_cnt = dict_get_var_cnt (dict);
   w->vars = xmalloc (sizeof *w->vars * w->var_cnt);
   for (i = 0; i < w->var_cnt; i++) 
@@ -113,6 +138,14 @@
       pv->fv = dv->fv;
     }
 
+  w->digits = opts.digits;
+  if (w->digits < 1) 
+    {
+      msg (ME, _("Invalid decimal digits count %d.  Treating as %d."),
+           w->digits, DBL_DIG);
+      w->digits = DBL_DIG;
+    }
+
   /* Write file header. */
   if (!write_header (w)
       || !write_version_data (w)
@@ -123,9 +156,16 @@
 
   return w;
 
-error:
+ error:
   pfm_close_writer (w);
   return NULL;
+
+ open_error:
+  msg (ME, _("An error occurred while opening \"%s\" for writing "
+             "as a portable file: %s."),
+       handle_get_filename (fh), strerror (errno));
+  err_cond_fail ();
+  goto error;
 }
   
 /* Write NBYTES starting at BUF to the portable file represented by
@@ -169,7 +209,7 @@
 write_float (struct pfm_writer *w, double d)
 {
   char buffer[64];
-  format_trig_double (d, DBL_DIG, buffer);
+  format_trig_double (d, floor (d) == d ? DBL_DIG : w->digits, buffer);
   return buf_write (w, buffer, strlen (buffer)) && buf_write (w, "/", 1);
 }
 
@@ -754,6 +794,8 @@
      required base-30 precision as 2/3 of the base-10 precision
      (log30(10) = .68). */
   assert (base_10_precision > 0);
+  if (base_10_precision > LDBL_DIG)
+    base_10_precision = LDBL_DIG;
   base_30_precision = DIV_RND_UP (base_10_precision * 2, 3);
   if (trig_cnt > base_30_precision)
     {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]