#include "libpspp/array.h"
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
-#include "libpspp/hash.h"
#include "libpspp/i18n.h"
#include "libpspp/message.h"
#include "libpspp/misc.h"
static char *text_get_token (struct text_record *,
struct substring delimiters, char *delimiter);
static bool text_match (struct text_record *, char c);
+static bool text_read_variable_name (struct sfm_reader *, struct dictionary *,
+ struct text_record *,
+ struct substring delimiters,
+ struct variable **);
static bool text_read_short_name (struct sfm_reader *, struct dictionary *,
struct text_record *,
struct substring delimiters,
sys_error (r, _("Variable label indicator field is not 0 or 1."));
if (has_variable_label == 1)
{
- size_t len;
+ size_t len, read_len;
char label[255 + 1];
len = read_int (r);
- if (len >= sizeof label)
- sys_error (r, _("Variable %s has label of invalid length %zu."),
- name, len);
- read_string (r, label, len + 1);
+
+ /* Read up to 255 bytes of label. */
+ read_len = MIN (sizeof label - 1, len);
+ read_string (r, label, read_len + 1);
var_set_label (var, label);
+ /* Skip unread label bytes. */
+ skip_bytes (r, len - read_len);
+
+ /* Skip label padding up to multiple of 4 bytes. */
skip_bytes (r, ROUND_UP (len, 4) - len);
}
dict_add_mrset (dict, mrset);
mrset = NULL;
+ stringi_set_destroy (&var_names);
}
mrset_destroy (mrset);
close_text_record (r, text);
first 255 bytes. The maximum documented length
of a label is 120 bytes so this is more than
generous. */
- skip_bytes (r, sizeof label - (label_length + 1));
+ skip_bytes (r, (label_length + 1) - sizeof label);
}
if (!skip && !var_add_value_label (v, &value, label))
for (;;)
{
struct variable *var;
- if (!text_read_short_name (r, dict, text, ss_cstr (":"), &var))
+ if (!text_read_variable_name (r, dict, text, ss_cstr (":"), &var))
break;
read_attributes (r, text, var != NULL ? var_get_attributes (var) : NULL);
}
}
}
+static bool
+text_read_variable_name (struct sfm_reader *r, struct dictionary *dict,
+ struct text_record *text, struct substring delimiters,
+ struct variable **var)
+{
+ char *name;
+
+ name = text_get_token (text, delimiters, NULL);
+ if (name == NULL)
+ return false;
+
+ *var = dict_lookup_var (dict, name);
+ if (*var != NULL)
+ return true;
+
+ text_warn (r, text, _("Dictionary record refers to unknown variable %s."),
+ name);
+ return false;
+}
+
+
static bool
text_read_short_name (struct sfm_reader *r, struct dictionary *dict,
struct text_record *text, struct substring delimiters,