/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009 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
#include <data/file-name.h>
#include <data/format.h>
#include <data/missing-values.h>
+#include <data/short-names.h>
#include <data/value-labels.h>
#include <data/variable.h>
-#include <libpspp/alloc.h>
#include <libpspp/compiler.h>
#include <libpspp/hash.h>
#include <libpspp/message.h>
#include <libpspp/pool.h>
#include <libpspp/str.h>
+#include "xalloc.h"
+
#include "gettext.h"
#define _(msgid) gettext (msgid)
+#define N_(msgid) (msgid)
/* portable_to_local[PORTABLE] translates the given portable
character into the local character set. */
jmp_buf bail_out; /* longjmp() target for error handling. */
struct file_handle *fh; /* File handle. */
+ struct fh_lock *lock; /* Read lock for file. */
FILE *file; /* File stream. */
int line_length; /* Number of characters so far on this line. */
char cc; /* Current character. */
bool ok; /* Set false on I/O error. */
};
-static struct casereader_class por_file_casereader_class;
+static const struct casereader_class por_file_casereader_class;
static void
error (struct pfm_reader *r, const char *msg,...)
r->file = NULL;
}
- if (r->fh != NULL)
- fh_close (r->fh, "portable file", "rs");
+ fh_unlock (r->lock);
+ fh_unref (r->fh);
ok = r->ok;
pool_destroy (r->pool);
struct pfm_reader *volatile r = NULL;
*dict = dict_create ();
- if (!fh_open (fh, FH_REF_FILE, "portable file", "rs"))
- goto error;
/* Create and initialize reader. */
pool = pool_create ();
r = pool_alloc (pool, sizeof *r);
r->pool = pool;
- r->fh = fh;
- r->file = fn_open (fh_get_file_name (r->fh), "rb");
+ r->fh = fh_ref (fh);
+ r->lock = NULL;
+ r->file = NULL;
r->line_length = 0;
r->weight_index = -1;
r->trans = NULL;
r->widths = NULL;
r->value_cnt = 0;
r->ok = true;
-
if (setjmp (r->bail_out))
goto error;
- /* Check that file open succeeded. */
+ /* Lock file. */
+ /* TRANSLATORS: this fragment will be interpolated into
+ messages in fh_lock() that identify types of files. */
+ r->lock = fh_lock (fh, FH_REF_FILE, N_("portable file"), FH_ACC_READ, false);
+ if (r->lock == NULL)
+ goto error;
+
+ /* Open file. */
+ r->file = fn_open (fh_get_file_name (r->fh), "rb");
if (r->file == NULL)
{
msg (ME, _("An error occurred while opening \"%s\" for reading "
static void
read_version_data (struct pfm_reader *r, struct pfm_read_info *info)
{
- static char empty_string[] = "";
- char *date, *time, *product, *author, *subproduct;
+ static const char empty_string[] = "";
+ char *date, *time;
+ const char *product, *author, *subproduct;
int i;
/* Read file. */
/* Validate file. */
if (strlen (date) != 8)
- error (r, _("Bad date string length %d."), (int) strlen (date));
+ error (r, _("Bad date string length %zu."), strlen (date));
if (strlen (time) != 6)
- error (r, _("Bad time string length %d."), (int) strlen (time));
+ error (r, _("Bad time string length %zu."), strlen (time));
/* Save file info. */
if (info != NULL)
int i;
for (i = 1; i < 100000; i++)
{
- char try_name[LONG_NAME_LEN + 1];
- sprintf (try_name, "%.*s_%d", LONG_NAME_LEN - 6, name, i);
+ char try_name[VAR_NAME_LEN + 1];
+ sprintf (try_name, "%.*s_%d", VAR_NAME_LEN - 6, name, i);
v = dict_create_var (dict, try_name, width);
if (v != NULL)
break;
{
double x = read_float (r);
double y = read_float (r);
- mv_add_num_range (&miss, x, y);
+ mv_add_range (&miss, x, y);
}
else if (match (r, 'A'))
- mv_add_num_range (&miss, read_float (r), HIGHEST);
+ mv_add_range (&miss, read_float (r), HIGHEST);
else if (match (r, '9'))
- mv_add_num_range (&miss, LOWEST, read_float (r));
+ mv_add_range (&miss, LOWEST, read_float (r));
/* Single missing values. */
while (match (r, '8'))
}
}
-/* Reads one case from portable file R into C. */
-static bool
-por_file_casereader_read (struct casereader *reader, void *r_, struct ccase *c)
+/* Reads and returns one case from portable file R. Returns a
+ null pointer on failure. */
+static struct ccase *
+por_file_casereader_read (struct casereader *reader, void *r_)
{
struct pfm_reader *r = r_;
+ struct ccase *volatile c;
size_t i;
size_t idx;
- case_create (c, casereader_get_value_cnt (reader));
+ c = case_create (casereader_get_value_cnt (reader));
setjmp (r->bail_out);
if (!r->ok)
{
casereader_force_error (reader);
- case_destroy (c);
- return false;
+ case_unref (c);
+ return NULL;
}
/* Check for end of file. */
if (r->cc == 'Z')
{
- case_destroy (c);
- return false;
+ case_unref (c);
+ return NULL;
}
idx = 0;
}
}
- return true;
+ return c;
}
/* Returns true if FILE is an SPSS portable file,
return true;
}
-static struct casereader_class por_file_casereader_class =
+static const struct casereader_class por_file_casereader_class =
{
por_file_casereader_read,
por_file_casereader_destroy,