/[pspp]/pspp/src/pfm-write.c
ViewVC logotype

Diff of /pspp/src/pfm-write.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.16 by blp, Sun Aug 7 04:39:28 2005 UTC revision 1.17 by blp, Sun Aug 21 07:21:06 2005 UTC
# Line 22  Line 22 
22  #include "error.h"  #include "error.h"
23  #include <ctype.h>  #include <ctype.h>
24  #include <errno.h>  #include <errno.h>
25    #include <fcntl.h>
26  #include <float.h>  #include <float.h>
27  #include <math.h>  #include <math.h>
28  #include <stdio.h>  #include <stdio.h>
29  #include <stdlib.h>  #include <stdlib.h>
30    #include <sys/stat.h>
31  #include <time.h>  #include <time.h>
32    #include <unistd.h>
33  #include "alloc.h"  #include "alloc.h"
34  #include "case.h"  #include "case.h"
35  #include "dictionary.h"  #include "dictionary.h"
# Line 35  Line 38 
38  #include "hash.h"  #include "hash.h"
39  #include "magic.h"  #include "magic.h"
40  #include "misc.h"  #include "misc.h"
41    #include "stat-macros.h"
42  #include "str.h"  #include "str.h"
43  #include "value-labels.h"  #include "value-labels.h"
44  #include "var.h"  #include "var.h"
# Line 55  struct pfm_writer Line 59  struct pfm_writer
59    
60      size_t var_cnt;             /* Number of variables. */      size_t var_cnt;             /* Number of variables. */
61      struct pfm_var *vars;       /* Variables. */      struct pfm_var *vars;       /* Variables. */
62    
63        int digits;                 /* Digits of precision. */
64    };    };
65    
66  /* A variable to write to the portable file. */  /* A variable to write to the portable file. */
# Line 73  static int write_value_labels (struct pf Line 79  static int write_value_labels (struct pf
79  static void format_trig_double (long double, int base_10_precision, char[]);  static void format_trig_double (long double, int base_10_precision, char[]);
80  static char *format_trig_int (int, bool force_sign, char[]);  static char *format_trig_int (int, bool force_sign, char[]);
81    
82  /* Writes the dictionary DICT to portable file HANDLE.  Returns  /* Returns default options for writing a portable file. */
83     nonzero only if successful.  DICT will not be modified, except  struct pfm_write_options
84     to assign short names. */  pfm_writer_default_options (void)
85    {
86      struct pfm_write_options opts;
87      opts.create_writeable = true;
88      opts.type = PFM_COMM;
89      opts.digits = DBL_DIG;
90      return opts;
91    }
92    
93    /* Writes the dictionary DICT to portable file HANDLE according
94       to the given OPTS.  Returns nonzero only if successful.  DICT
95       will not be modified, except to assign short names. */
96  struct pfm_writer *  struct pfm_writer *
97  pfm_open_writer (struct file_handle *fh, struct dictionary *dict)  pfm_open_writer (struct file_handle *fh, struct dictionary *dict,
98                     struct pfm_write_options opts)
99  {  {
100    struct pfm_writer *w = NULL;    struct pfm_writer *w = NULL;
101      mode_t mode;
102      int fd;
103    size_t i;    size_t i;
104    
105      /* Create file. */
106      mode = S_IRUSR | S_IRGRP | S_IROTH;
107      if (opts.create_writeable)
108        mode |= S_IWUSR | S_IWGRP | S_IWOTH;
109      fd = open (handle_get_filename (fh), O_WRONLY | O_CREAT | O_TRUNC, mode);
110      if (fd < 0)
111        goto open_error;
112    
113      /* Open file handle. */
114    if (!fh_open (fh, "portable file", "we"))    if (!fh_open (fh, "portable file", "we"))
115      goto error;      goto error;
116      
117    /* Open the physical disk file. */    /* Initialize data structures. */
118    w = xmalloc (sizeof *w);    w = xmalloc (sizeof *w);
119    w->fh = fh;    w->fh = fh;
120    w->file = fopen (handle_get_filename (fh), "wb");    w->file = fdopen (fd, "w");
121      if (w->file == NULL)
122        {
123          close (fd);
124          goto open_error;
125        }
126      
127    w->lc = 0;    w->lc = 0;
128    w->var_cnt = 0;    w->var_cnt = 0;
129    w->vars = NULL;    w->vars = NULL;
130        
   /* 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;  
     }  
     
131    w->var_cnt = dict_get_var_cnt (dict);    w->var_cnt = dict_get_var_cnt (dict);
132    w->vars = xmalloc (sizeof *w->vars * w->var_cnt);    w->vars = xmalloc (sizeof *w->vars * w->var_cnt);
133    for (i = 0; i < w->var_cnt; i++)    for (i = 0; i < w->var_cnt; i++)
# Line 113  pfm_open_writer (struct file_handle *fh, Line 138  pfm_open_writer (struct file_handle *fh,
138        pv->fv = dv->fv;        pv->fv = dv->fv;
139      }      }
140    
141      w->digits = opts.digits;
142      if (w->digits < 1)
143        {
144          msg (ME, _("Invalid decimal digits count %d.  Treating as %d."),
145               w->digits, DBL_DIG);
146          w->digits = DBL_DIG;
147        }
148    
149    /* Write file header. */    /* Write file header. */
150    if (!write_header (w)    if (!write_header (w)
151        || !write_version_data (w)        || !write_version_data (w)
# Line 123  pfm_open_writer (struct file_handle *fh, Line 156  pfm_open_writer (struct file_handle *fh,
156    
157    return w;    return w;
158    
159  error:   error:
160    pfm_close_writer (w);    pfm_close_writer (w);
161    return NULL;    return NULL;
162    
163     open_error:
164      msg (ME, _("An error occurred while opening \"%s\" for writing "
165                 "as a portable file: %s."),
166           handle_get_filename (fh), strerror (errno));
167      err_cond_fail ();
168      goto error;
169  }  }
170        
171  /* Write NBYTES starting at BUF to the portable file represented by  /* Write NBYTES starting at BUF to the portable file represented by
# Line 169  static int Line 209  static int
209  write_float (struct pfm_writer *w, double d)  write_float (struct pfm_writer *w, double d)
210  {  {
211    char buffer[64];    char buffer[64];
212    format_trig_double (d, DBL_DIG, buffer);    format_trig_double (d, floor (d) == d ? DBL_DIG : w->digits, buffer);
213    return buf_write (w, buffer, strlen (buffer)) && buf_write (w, "/", 1);    return buf_write (w, buffer, strlen (buffer)) && buf_write (w, "/", 1);
214  }  }
215    
# Line 754  format_trig_double (long double value, i Line 794  format_trig_double (long double value, i
794       required base-30 precision as 2/3 of the base-10 precision       required base-30 precision as 2/3 of the base-10 precision
795       (log30(10) = .68). */       (log30(10) = .68). */
796    assert (base_10_precision > 0);    assert (base_10_precision > 0);
797      if (base_10_precision > LDBL_DIG)
798        base_10_precision = LDBL_DIG;
799    base_30_precision = DIV_RND_UP (base_10_precision * 2, 3);    base_30_precision = DIV_RND_UP (base_10_precision * 2, 3);
800    if (trig_cnt > base_30_precision)    if (trig_cnt > base_30_precision)
801      {      {

Legend:
Removed from v.1.16  
changed lines
  Added in v.1.17

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26