/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-2000, 2006-2007, 2009-2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-2000, 2006-2007, 2009-2016 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
static struct any_reader *
pcp_open (struct file_handle *fh)
{
- struct pcp_reader *r;
struct stat s;
/* Create and initialize reader. */
- r = xzalloc (sizeof *r);
+ struct pcp_reader *r = XZALLOC (struct pcp_reader);
r->any_reader.klass = &pcp_file_reader_class;
r->pool = pool_create ();
pool_register (r->pool, free, r);
goto error;
/* Open file. */
- r->file = fn_open (fh_get_file_name (fh), "rb");
+ r->file = fn_open (fh, "rb");
if (r->file == NULL)
{
msg (ME, _("Error opening `%s' for reading as an SPSS/PC+ "
/* Fetch file size. */
if (fstat (fileno (r->file), &s))
{
- pcp_error (ME, 0, _("%s: stat failed (%s)."),
+ pcp_error (r, 0, _("%s: stat failed (%s)."),
fh_get_file_name (r->fh), strerror (errno));
goto error;
}
if (s.st_size > UINT_MAX)
{
- pcp_error (ME, 0, _("%s: file too large."), fh_get_file_name (r->fh));
+ pcp_error (r, 0, _("%s: file too large."), fh_get_file_name (r->fh));
goto error;
}
r->file_size = s.st_size;
error:
pcp_close (&r->any_reader);
- dict_destroy (dict);
+ dict_unref (dict);
*dictp = NULL;
return NULL;
}
if (r->file)
{
- if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
+ if (fn_close (r->fh, r->file) == EOF)
{
msg (ME, _("Error closing system file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
pcp_close (&r->any_reader);
}
-/* Returns true if FILE is an SPSS/PC+ system file,
- false otherwise. */
+/* Detects whether FILE is an SPSS/PC+ system file. Returns 1 if so, 0 if
+ not, and a negative errno value if there is an error reading FILE. */
static int
pcp_detect (FILE *file)
{
static const char signature[4] = "SPSS";
char buf[sizeof signature];
- if (fseek (file, 0x104, SEEK_SET)
- || (fread (buf, sizeof buf, 1, file) != 1 && !feof (file)))
+ if (fseek (file, 0x104, SEEK_SET))
return -errno;
+ if (fread (buf, sizeof buf, 1, file) != 1)
+ return ferror (file) ? -errno : 0;
+
return !memcmp (buf, signature, sizeof buf);
}
\f
uint8_t len;
if (var->n_val_labs >= allocated_val_labs)
- var->val_labs = x2nrealloc (var->val_labs, &allocated_val_labs,
- sizeof *var->val_labs);
+ var->val_labs = pool_2nrealloc (r->pool, var->val_labs,
+ &allocated_val_labs,
+ sizeof *var->val_labs);
vl = &var->val_labs[var->n_val_labs];
if (!read_bytes (r, vl->value, sizeof vl->value)
info->integer_format = INTEGER_LSB_FIRST;
info->float_format = FLOAT_IEEE_DOUBLE_LE;
info->compression = r->compressed ? ANY_COMP_SIMPLE : ANY_COMP_NONE;
- info->case_cnt = r->n_cases;
+ info->n_cases = r->n_cases;
/* Convert file label to UTF-8 and put it into DICT. */
label = recode_and_trim_string (r->pool, dict_encoding, header->file_label);
if (var_is_numeric (var))
value.f = parse_float (rec->val_labs[i].value);
else
- memcpy (value_str_rw (&value, rec->width),
- rec->val_labs[i].value, rec->width);
+ memcpy (value.s, rec->val_labs[i].value, rec->width);
utf8_label = recode_string ("UTF-8", dict_encoding,
rec->val_labs[i].label, -1);
if (var->width == 0)
retval = read_case_number (r, &v->f);
else
- retval = read_case_string (r, value_str_rw (v, var->width),
- var->width);
+ retval = read_case_string (r, v->s, var->width);
if (retval != 1)
{
pcp_msg (struct pcp_reader *r, off_t offset,
int class, const char *format, va_list args)
{
- struct msg m;
struct string text;
-
ds_init_empty (&text);
if (offset >= 0)
ds_put_format (&text, _("`%s' near offset 0x%llx: "),
ds_put_format (&text, _("`%s': "), fh_get_file_name (r->fh));
ds_put_vformat (&text, format, args);
- m.category = msg_class_to_category (class);
- m.severity = msg_class_to_severity (class);
- m.file_name = NULL;
- m.first_line = 0;
- m.last_line = 0;
- m.first_column = 0;
- m.last_column = 0;
- m.text = ds_cstr (&text);
-
- msg_emit (&m);
+ struct msg *m = xmalloc (sizeof *m);
+ *m = (struct msg) {
+ .category = msg_class_to_category (class),
+ .severity = msg_class_to_severity (class),
+ .text = ds_steal_cstr (&text),
+ };
+ msg_emit (m);
}
/* Displays a warning for offset OFFSET in the file. */
an error. */
static inline int
read_bytes_internal (struct pcp_reader *r, bool eof_is_ok,
- void *buf, size_t byte_cnt)
+ void *buf, size_t n_bytes)
{
- size_t bytes_read = fread (buf, 1, byte_cnt, r->file);
+ size_t bytes_read = fread (buf, 1, n_bytes, r->file);
r->pos += bytes_read;
- if (bytes_read == byte_cnt)
+ if (bytes_read == n_bytes)
return 1;
else if (ferror (r->file))
{
Returns true if successful.
Returns false upon I/O error or if end-of-file is encountered. */
static bool
-read_bytes (struct pcp_reader *r, void *buf, size_t byte_cnt)
+read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes)
{
- return read_bytes_internal (r, false, buf, byte_cnt) == 1;
+ return read_bytes_internal (r, false, buf, n_bytes) == 1;
}
/* Reads BYTE_CNT bytes into BUF.
Returns 0 if an immediate end-of-file is encountered.
Returns -1 if an I/O error or a partial read occurs. */
static int
-try_read_bytes (struct pcp_reader *r, void *buf, size_t byte_cnt)
+try_read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes)
{
- return read_bytes_internal (r, true, buf, byte_cnt);
+ return read_bytes_internal (r, true, buf, n_bytes);
}
/* Reads a 16-bit signed integer from R and stores its value in host format in