#include "libpspp/pool.h"
#include "libpspp/str.h"
-#include "gl/intprops.h"
#include "gl/minmax.h"
#include "gl/xalloc.h"
#include "gl/xmemdup0.h"
int line_length; /* Number of characters so far on this line. */
char cc; /* Current character. */
char *trans; /* 256-byte character set translation table. */
- int var_cnt; /* Number of variables. */
+ int n_vars; /* Number of variables. */
int weight_index; /* 0-based index of weight variable, or -1. */
struct caseproto *proto; /* Format of output cases. */
bool ok; /* Set false on I/O error. */
static void
error (struct pfm_reader *r, const char *msg, ...)
{
- struct msg m;
struct string text;
va_list args;
ds_put_vformat (&text, msg, args);
va_end (args);
- m.category = MSG_C_GENERAL;
- m.severity = MSG_S_ERROR;
- 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_C_GENERAL,
+ .severity = MSG_S_ERROR,
+ .text = ds_steal_cstr (&text),
+ };
+ msg_emit (m);
r->ok = false;
static void
warning (struct pfm_reader *r, const char *msg, ...)
{
- struct msg m;
struct string text;
va_list args;
ds_put_vformat (&text, msg, args);
va_end (args);
- m.category = MSG_C_GENERAL;
- m.severity = MSG_S_WARNING;
- 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_C_GENERAL,
+ .severity = MSG_S_WARNING,
+ .text = ds_steal_cstr (&text),
+ };
+ msg_emit (m);
}
/* Close and destroy R.
struct pfm_reader *r = pfm_reader_cast (r_);
bool ok;
- dict_destroy (r->dict);
+ dict_unref (r->dict);
any_read_info_destroy (&r->info);
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 portable file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
r->line_length = 0;
}
if (c == EOF)
- error (r, _("unexpected end of file"));
+ error (r, _("Unexpected end of file"));
if (r->trans != NULL)
c = r->trans[c];
/* Reads the dictionary from file with handle H, and returns it in a
dictionary structure. This dictionary may be modified in order to
rename, reorder, and delete variables, etc. */
-struct any_reader *
+static struct any_reader *
pfm_open (struct file_handle *fh)
{
struct pool *volatile pool = NULL;
r->line_length = 0;
r->weight_index = -1;
r->trans = NULL;
- r->var_cnt = 0;
+ r->n_vars = 0;
r->proto = NULL;
r->ok = true;
if (setjmp (r->bail_out))
goto error;
/* Open file. */
- r->file = fn_open (fh_get_file_name (r->fh), "rb");
+ r->file = fn_open (r->fh, "rb");
if (r->file == NULL)
{
msg (ME, _("An error occurred while opening `%s' for reading "
return NULL;
}
-struct casereader *
+static struct casereader *
pfm_decode (struct any_reader *r_, const char *encoding UNUSED,
struct dictionary **dictp, struct any_read_info *info)
{
info->float_format = FLOAT_NATIVE_DOUBLE;
info->integer_format = INTEGER_NATIVE;
info->compression = ANY_COMP_NONE;
- info->case_cnt = -1;
+ info->n_cases = -1;
/* Date. */
info->creation_date = xmalloc (11);
convert_format (struct pfm_reader *r, const int portable_format[3],
struct variable *v, bool *report_error)
{
- struct fmt_spec format;
- bool ok;
-
- if (!fmt_from_io (portable_format[0], &format.type))
+ enum fmt_type type;
+ if (fmt_from_io (portable_format[0], &type))
{
- if (*report_error)
- warning (r, _("%s: Bad format specifier byte (%d). Variable "
- "will be assigned a default format."),
- var_get_name (v), portable_format[0]);
- goto assign_default;
- }
-
- format.w = portable_format[1];
- format.d = portable_format[2];
+ struct fmt_spec format = {
+ .type = type,
+ .w = portable_format[1],
+ .d = portable_format[2],
+ };
- msg_disable ();
- ok = (fmt_check_output (&format)
- && fmt_check_width_compat (&format, var_get_width (v)));
- msg_enable ();
+ if (fmt_check_output (format)
+ && fmt_check_width_compat (format, var_get_width (v)))
+ return format;
- if (!ok)
- {
if (*report_error)
{
char fmt_string[FMT_STRING_LEN_MAX + 1];
- fmt_to_string (&format, fmt_string);
+ fmt_to_string (format, fmt_string);
if (var_is_numeric (v))
warning (r, _("Numeric variable %s has invalid format "
"specifier %s."),
"invalid format specifier %s."),
var_get_name (v), var_get_width (v), fmt_string);
}
- goto assign_default;
+ }
+ else
+ {
+ if (*report_error)
+ warning (r, _("%s: Bad format specifier byte (%d). Variable "
+ "will be assigned a default format."),
+ var_get_name (v), portable_format[0]);
}
- return format;
-
-assign_default:
*report_error = false;
return fmt_default_for_width (var_get_width (v));
}
if (!match (r, '4'))
error (r, _("Expected variable count record."));
- r->var_cnt = read_int (r);
- if (r->var_cnt <= 0)
- error (r, _("Invalid number of variables %d."), r->var_cnt);
+ r->n_vars = read_int (r);
+ if (r->n_vars <= 0)
+ error (r, _("Invalid number of variables %d."), r->n_vars);
if (match (r, '5'))
read_int (r);
error (r, _("Weight variable name (%s) truncated."), weight_name);
}
- for (i = 0; i < r->var_cnt; i++)
+ for (i = 0; i < r->n_vars; i++)
{
int width;
char name[256];
for (j = 0; j < 6; j++)
fmt[j] = read_int (r);
- if (!dict_id_is_valid (dict, name, false)
- || *name == '#' || *name == '$')
+ if (!dict_id_is_valid (dict, name) || *name == '#' || *name == '$')
error (r, _("Invalid variable name `%s' in position %d."), name, i);
str_uppercase (name);
unsigned long int i;
for (i = 1; ; i++)
{
- char try_name[8 + 1 + INT_STRLEN_BOUND (i) + 1];
- sprintf (try_name, "%s_%lu", name, i);
+ char *try_name = xasprintf ("%s_%lu", name, i);
v = dict_create_var (dict, try_name, width);
+ free (try_name);
if (v != NULL)
break;
}
print = convert_format (r, &fmt[0], v, &report_error);
write = convert_format (r, &fmt[3], v, &report_error);
- var_set_print_format (v, &print);
- var_set_write_format (v, &write);
+ var_set_print_format (v, print);
+ var_set_write_format (v, write);
/* Range missing values. */
mv_init (&miss, width);
static void
read_documents (struct pfm_reader *r, struct dictionary *dict)
{
- int line_cnt;
- int i;
-
- line_cnt = read_int (r);
- for (i = 0; i < line_cnt; i++)
+ int n_lines = read_int (r);
+ for (int i = 0; i < n_lines; i++)
{
char line[256];
read_string (r, line);
return NULL;
}
- for (i = 0; i < r->var_cnt; i++)
+ for (i = 0; i < r->n_vars; i++)
{
int width = caseproto_get_width (r->proto, i);
if (width == 0)
- case_data_rw_idx (c, i)->f = read_float (r);
+ *case_num_rw_idx (c, i) = read_float (r);
else
{
uint8_t buf[256];
/* Detects whether FILE is an SPSS portable file. Returns 1 if so, 0 if not,
and a negative errno value if there is an error reading FILE. */
-int
+static int
pfm_detect (FILE *file)
{
unsigned char header[464];
char trans[256];
- int cooked_cnt, raw_cnt, line_len;
+ int n_cooked, n_raws, line_len;
int i;
- cooked_cnt = raw_cnt = 0;
+ n_cooked = n_raws = 0;
line_len = 0;
- while (cooked_cnt < sizeof header)
+ while (n_cooked < sizeof header)
{
int c = getc (file);
- if (c == EOF || raw_cnt++ > 512)
+ if (c == EOF || n_raws++ > 512)
return ferror (file) ? -errno : 0;
else if (c == '\n')
{
- while (line_len < 80 && cooked_cnt < sizeof header)
+ while (line_len < 80 && n_cooked < sizeof header)
{
- header[cooked_cnt++] = ' ';
+ header[n_cooked++] = ' ';
line_len++;
}
line_len = 0;
}
else if (c != '\r')
{
- header[cooked_cnt++] = c;
+ header[n_cooked++] = c;
line_len++;
}
}