/* PSPP - computes sample statistics.
Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
- Written by Ben Pfaff <blp@gnu.org>.
Code for parsing floating-point numbers adapted from GNU C
library.
#include "dictionary.h"
#include "file-handle-def.h"
#include "format.h"
+#include "missing-values.h"
#include <libpspp/hash.h>
#include <libpspp/magic.h>
#include <libpspp/misc.h>
/* Check that we had some digits. */
if (!got_digit)
- error (r, "Number expected.");
+ error (r, _("Number expected."));
/* Get exponent if any. */
if (r->cc == '+' || r->cc == '-')
/* Read file. */
if (!match (r, 'A'))
- error (r, "Unrecognized version code `%c'.", r->cc);
+ error (r, _("Unrecognized version code `%c'."), r->cc);
date = read_pool_string (r);
time = read_pool_string (r);
product = match (r, '1') ? read_pool_string (r) : empty_string;
/* Validate file. */
if (strlen (date) != 8)
- error (r, _("Bad date string length %d."), strlen (date));
+ error (r, _("Bad date string length %d."), (int) strlen (date));
if (strlen (time) != 6)
- error (r, _("Bad time string length %d."), strlen (time));
+ error (r, _("Bad time string length %d."), (int) strlen (time));
/* Save file info. */
if (info != NULL)
/* Translates a format specification read from portable file R as
the three integers INTS into a normal format specifier FORMAT,
checking that the format is appropriate for variable V. */
-static void
+static struct fmt_spec
convert_format (struct pfm_reader *r, const int portable_format[3],
- struct fmt_spec *format, struct variable *v)
+ struct variable *v)
{
+ struct fmt_spec format;
bool ok;
- if (!fmt_from_io (portable_format[0], &format->type))
+ if (!fmt_from_io (portable_format[0], &format.type))
error (r, _("%s: Bad format specifier byte (%d)."),
- v->name, portable_format[0]);
- format->w = portable_format[1];
- format->d = portable_format[2];
+ var_get_name (v), portable_format[0]);
+ format.w = portable_format[1];
+ format.d = portable_format[2];
msg_disable ();
- ok = fmt_check_output (format) && fmt_check_width_compat (format, v->width);
+ ok = (fmt_check_output (&format)
+ && fmt_check_width_compat (&format, var_get_width (v)));
msg_enable ();
if (!ok)
{
char fmt_string[FMT_STRING_LEN_MAX + 1];
error (r, _("%s variable %s has invalid format specifier %s."),
- v->type == NUMERIC ? _("Numeric") : _("String"),
- v->name, fmt_to_string (format, fmt_string));
+ var_is_numeric (v) ? _("Numeric") : _("String"),
+ var_get_name (v), fmt_to_string (&format, fmt_string));
+ format = fmt_default_for_width (var_get_width (v));
}
+
+ return format;
}
static union value parse_value (struct pfm_reader *, struct variable *);
char name[256];
int fmt[6];
struct variable *v;
+ struct missing_values miss;
+ struct fmt_spec print, write;
int j;
if (!match (r, '7'))
str_uppercase (name);
if (width < 0 || width > 255)
- error (r, "Bad width %d for variable %s.", width, name);
+ error (r, _("Bad width %d for variable %s."), width, name);
v = dict_create_var (dict, name, width);
if (v == NULL)
error (r, _("Duplicate variable name %s."), name);
- convert_format (r, &fmt[0], &v->print, v);
- convert_format (r, &fmt[3], &v->write, v);
+ print = convert_format (r, &fmt[0], v);
+ write = convert_format (r, &fmt[3], v);
+ var_set_print_format (v, &print);
+ var_set_write_format (v, &write);
/* Range missing values. */
+ mv_init (&miss, var_get_width (v));
if (match (r, 'B'))
{
double x = read_float (r);
double y = read_float (r);
- mv_add_num_range (&v->miss, x, y);
+ mv_add_num_range (&miss, x, y);
}
else if (match (r, 'A'))
- mv_add_num_range (&v->miss, read_float (r), HIGHEST);
+ mv_add_num_range (&miss, read_float (r), HIGHEST);
else if (match (r, '9'))
- mv_add_num_range (&v->miss, LOWEST, read_float (r));
+ mv_add_num_range (&miss, LOWEST, read_float (r));
/* Single missing values. */
while (match (r, '8'))
{
union value value = parse_value (r, v);
- mv_add_value (&v->miss, &value);
+ mv_add_value (&miss, &value);
}
+ var_set_missing_values (v, &miss);
+
if (match (r, 'C'))
{
char label[256];
read_string (r, label);
- v->label = xstrdup (label);
+ var_set_label (v, label);
}
}
{
union value v;
- if (vv->type == ALPHA)
+ if (var_is_alpha (vv))
{
char string[256];
read_string (r, string);
if (v[i] == NULL)
error (r, _("Unknown variable %s while parsing value labels."), name);
- if (v[0]->width != v[i]->width)
+ if (var_get_width (v[0]) != var_get_width (v[i]))
error (r, _("Cannot assign value labels to %s and %s, which "
"have different variable types or widths."),
- v[0]->name, v[i]->name);
+ var_get_name (v[0]), var_get_name (v[i]));
}
n_labels = read_int (r);
{
struct variable *var = v[j];
- if (!val_labs_replace (var->val_labs, val, label))
+ if (!var_add_value_label (var, &val, label))
continue;
- if (var->type == NUMERIC)
+ if (var_is_numeric (var))
error (r, _("Duplicate label for value %g for variable %s."),
- val.f, var->name);
+ val.f, var_get_name (var));
else
error (r, _("Duplicate label for value `%.*s' for variable %s."),
- var->width, val.s, var->name);
+ var_get_width (var), val.s, var_get_name (var));
}
}
}
if (width == 0)
{
- case_data_rw (c, idx)->f = read_float (r);
+ case_data_rw_idx (c, idx)->f = read_float (r);
idx++;
}
else
{
char string[256];
read_string (r, string);
- buf_copy_str_rpad (case_data_rw (c, idx)->s, width, string);
+ buf_copy_str_rpad (case_data_rw_idx (c, idx)->s, width, string);
idx += DIV_RND_UP (width, MAX_SHORT_STRING);
}
}