{
unsigned int pos;
+ bool drop;
+ union value tmp;
+
char name[9];
int width;
struct fmt_spec format;
struct pcp_value_label *val_labs;
size_t n_val_labs;
-
- struct variable *var;
};
struct pcp_value_label
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);
return aux.n;
}
-static void
-find_and_delete_var (struct dictionary *dict, const char *name)
-{
- struct variable *var = dict_lookup_var (dict, name);
- if (var)
- dict_delete_var (dict, var);
-}
-
-/* Decodes the dictionary read from R, saving it into into *DICT. Character
+/* Decodes the dictionary read from R, saving it into *DICT. Character
strings in R are decoded using ENCODING, or an encoding obtained from R if
ENCODING is null, or the locale encoding if R specifies no encoding.
dictionary and may destroy or modify its variables. */
r->proto = caseproto_ref_pool (dict_get_proto (dict), r->pool);
- find_and_delete_var (dict, "CASENUM_");
- find_and_delete_var (dict, "DATE_");
- find_and_delete_var (dict, "WEIGHT_");
-
*dictp = dict;
if (infop)
{
var->format.w = (format >> 8) & 0xff;
var->format.d = format & 0xff;
fmt_fix_output (&var->format);
- var->width = fmt_var_width (&var->format);
+ var->width = fmt_var_width (var->format);
if (var_label_ofs)
{
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);
for (rec = var_recs; rec < &var_recs[n_var_recs]; rec++)
{
- struct variable *var;
char *name;
size_t i;
rec->name, -1, r->pool);
name[strcspn (name, " ")] = '\0';
- /* Transform $DATE => DATE_, $WEIGHT => WEIGHT_, $CASENUM => CASENUM_. */
- if (name[0] == '$')
- name = pool_asprintf (r->pool, "%s_", name + 1);
+ /* Drop system variables. */
+ rec->drop = name[0] == '$';
+ if (rec->drop)
+ {
+ value_init_pool (r->pool, &rec->tmp, rec->width);
+ continue;
+ }
- if (!dict_id_is_valid (dict, name, false) || name[0] == '#')
+ if (!dict_id_is_valid (dict, name) || name[0] == '#')
{
pcp_error (r, rec->pos, _("Invalid variable name `%s'."), name);
return false;
}
- var = rec->var = dict_create_var (dict, name, rec->width);
+ struct variable *var = dict_create_var (dict, name, rec->width);
if (var == NULL)
{
char *new_name = dict_make_unique_var_name (dict, NULL, NULL);
pcp_warn (r, rec->pos, _("Renaming variable with duplicate name "
"`%s' to `%s'."),
name, new_name);
- var = rec->var = dict_create_var_assert (dict, new_name, rec->width);
+ var = dict_create_var_assert (dict, new_name, rec->width);
free (new_name);
}
if (rec->weight)
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);
}
/* Set formats. */
- var_set_both_formats (var, &rec->format);
+ var_set_both_formats (var, rec->format);
}
return true;
r->n_cases--;
c = case_create (r->proto);
+ size_t case_idx = 0;
for (i = 0; i < r->n_vars; i++)
{
struct pcp_var_record *var = &r->vars[i];
- union value *v = case_data_rw_idx (c, i);
+ union value *v = var->drop ? &var->tmp : case_data_rw_idx (c, case_idx++);
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