/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-2000, 2006-2007, 2009-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2000, 2006-2007, 2009-2016, 2021 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
sfm_open (struct file_handle *fh)
{
size_t allocated_mrsets = 0;
- struct sfm_reader *r;
/* Create and initialize reader. */
- r = xzalloc (sizeof *r);
+ struct sfm_reader *r = XZALLOC (struct sfm_reader);
r->any_reader.klass = &sys_file_reader_class;
r->pool = pool_create ();
pool_register (r->pool, free, r);
case 6:
if (r->document != NULL)
- {
- sys_error (r, r->pos, _("Duplicate type 6 (document) record."));
- return false;
- }
+ sys_warn (r, r->pos, _("Duplicate type 6 (document) record."));
return read_document_record (r);
case 7:
va_end (args);
}
+static const char *
+skip_prefix (const char *s, const char *prefix)
+{
+ size_t prefix_len = strlen (prefix);
+ return !strncmp (s, prefix, prefix_len) ? s + prefix_len : s;
+}
+
/* Retrieves significant string data from R in its raw format, to allow the
caller to try to detect the encoding in use.
add_string (&aux, r->header.creation_date, _("Creation Date"));
add_string (&aux, r->header.creation_time, _("Creation Time"));
- add_string (&aux, r->header.eye_catcher, _("Product"));
+ add_string (&aux, skip_prefix (r->header.eye_catcher, "@(#) "), _("Product"));
add_string (&aux, r->header.file_label, _("File Label"));
if (r->extensions[EXT_PRODUCT_INFO])
r->compression = ANY_COMP_NONE;
else if (compressed == 1)
r->compression = ANY_COMP_SIMPLE;
- else if (compressed != 0)
+ else
{
sys_error (r, 0, "System file header has invalid compression "
"value %d.", compressed);
info->product = ss_xstrdup (product);
}
+static struct variable *
+add_var_with_generated_name (struct dictionary *dict, int width)
+{
+ char *name = dict_make_unique_var_name (dict, NULL, NULL);
+ struct variable *var = dict_create_var_assert (dict, name, width);
+ free (name);
+ return var;
+}
+
/* Reads a variable (type 2) record from R and adds the
corresponding variable to DICT.
Also skips past additional variable records for long string
for (rec = var_recs; rec < &var_recs[n_var_recs];)
{
- struct variable *var;
size_t n_values;
char *name;
size_t i;
rec->name, -1, r->pool);
name[strcspn (name, " ")] = '\0';
- if (!dict_id_is_valid (dict, name, false)
- || name[0] == '$' || name[0] == '#')
- {
- sys_error (r, rec->pos, _("Invalid variable name `%s'."), name);
- return false;
- }
-
if (rec->width < 0 || rec->width > 255)
{
sys_error (r, rec->pos,
return false;
}
- var = rec->var = dict_create_var (dict, name, rec->width);
- if (var == NULL)
+ struct variable *var;
+ if (!dict_id_is_valid (dict, name, false)
+ || name[0] == '$' || name[0] == '#')
{
- char *new_name = dict_make_unique_var_name (dict, NULL, NULL);
- sys_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_set_short_name (var, 0, new_name);
- free (new_name);
+ var = add_var_with_generated_name (dict, rec->width);
+ sys_warn (r, rec->pos, _("Renaming variable with invalid name "
+ "`%s' to `%s'."), name, var_get_name (var));
}
+ else
+ {
+ var = dict_create_var (dict, name, rec->width);
+ if (var == NULL)
+ {
+ var = add_var_with_generated_name (dict, rec->width);
+ sys_warn (r, rec->pos, _("Renaming variable with duplicate name "
+ "`%s' to `%s'."),
+ name, var_get_name (var));
+ }
+ }
+ rec->var = var;
/* Set the short name the same as the long name (even if we renamed
it). */
text = open_text_record (r, record, false);
for (;;)
{
- struct sfm_mrset *mrset;
- size_t allocated_vars;
- char delimiter;
+ struct sfm_mrset *mrset = NULL;
+ size_t allocated_vars = 0;
+ char delimiter = '4';
/* Skip extra line feeds if present. */
while (text_match (text, '\n'))
for (i = 0; i < n_short_names; i++)
{
const char *s = var_get_short_name (var, i);
- short_names[i] = s != NULL ? xstrdup (s) : NULL;
+ short_names[i] = xstrdup_if_nonnull (s);
}
/* Set long name. */
char *end;
if (!ss_tokenize (text->buffer, delimiters, &text->pos, &token))
- return NULL;
+ {
+ if (delimiter != NULL)
+ *delimiter = ss_data (text->buffer)[text->pos-1];
+ return NULL;
+ }
end = &ss_data (token)[ss_length (token)];
if (delimiter != NULL)
ds_put_format (&text, _("`%s': "), fh_get_file_name (r->fh));
ds_put_vformat (&text, format, args);
- struct msg m = {
+ struct msg *m = xmalloc (sizeof *m);
+ *m = (struct msg) {
.category = msg_class_to_category (class),
.severity = msg_class_to_severity (class),
- .text = ds_cstr (&text),
+ .text = ds_steal_cstr (&text),
};
- msg_emit (&m);
+ msg_emit (m);
}
/* Displays a warning for offset OFFSET in the file. */