+ record = pool_malloc (r->pool, sizeof *record);
+ read_extension_record_header (r, subtype, record);
+ n_bytes = record->count * record->size;
+
+ for (type = types; type < &types[sizeof types / sizeof *types]; type++)
+ if (subtype == type->subtype)
+ {
+ if (type->size > 0 && record->size != type->size)
+ sys_warn (r, record->pos,
+ _("Record type 7, subtype %d has bad size %zu "
+ "(expected %d)."), subtype, record->size, type->size);
+ else if (type->count > 0 && record->count != type->count)
+ sys_warn (r, record->pos,
+ _("Record type 7, subtype %d has bad count %zu "
+ "(expected %d)."), subtype, record->count, type->count);
+ else if (type->count == 0 && type->size == 0)
+ {
+ /* Ignore this record. */
+ }
+ else
+ {
+ char *data = pool_malloc (r->pool, n_bytes + 1);
+ data[n_bytes] = '\0';
+
+ record->data = data;
+ read_bytes (r, record->data, n_bytes);
+ return record;
+ }
+
+ goto skip;
+ }
+
+ sys_warn (r, record->pos,
+ _("Unrecognized record type 7, subtype %d. Please send a "
+ "copy of this file, and the syntax which created it to %s."),
+ subtype, PACKAGE_BUGREPORT);
+
+skip:
+ skip_bytes (r, n_bytes);
+ return NULL;
+}
+
+static void
+skip_extension_record (struct sfm_reader *r, int subtype)
+{
+ struct sfm_extension_record record;
+
+ read_extension_record_header (r, subtype, &record);
+ skip_bytes (r, record.count * record.size);
+}
+
+static void
+parse_file_label (struct sfm_reader *r, const char *file_label,
+ struct dictionary *dict)
+{
+ char *utf8_file_label;
+ size_t file_label_len;
+
+ utf8_file_label = recode_string_pool ("UTF-8", dict_get_encoding (dict),
+ file_label, -1, r->pool);
+ file_label_len = strlen (utf8_file_label);
+ while (file_label_len > 0 && utf8_file_label[file_label_len - 1] == ' ')
+ file_label_len--;
+ utf8_file_label[file_label_len] = '\0';
+ dict_set_label (dict, utf8_file_label);
+}
+
+/* Reads a variable (type 2) record from R and adds the
+ corresponding variable to DICT.
+ Also skips past additional variable records for long string
+ variables. */
+static void
+parse_variable_records (struct sfm_reader *r, struct dictionary *dict,
+ struct sfm_var_record *var_recs, size_t n_var_recs)
+{
+ const char *dict_encoding = dict_get_encoding (dict);
+ struct sfm_var_record *rec;
+ int n_warnings = 0;
+
+ for (rec = var_recs; rec < &var_recs[n_var_recs]; )
+ {
+ struct variable *var;
+ size_t n_values;
+ char *name;
+ size_t i;
+
+ name = recode_string_pool ("UTF-8", dict_encoding,
+ rec->name, 8, r->pool);
+ name[strcspn (name, " ")] = '\0';
+
+ if (!var_is_valid_name (name, false) || name[0] == '$' || name[0] == '#')
+ sys_error (r, rec->pos, _("Invalid variable name `%s'."), name);
+
+ if (rec->width < 0 || rec->width > 255)
+ sys_error (r, rec->pos,
+ _("Bad width %d for variable %s."), rec->width, name);
+
+ var = rec->var = dict_create_var (dict, name, rec->width);
+ if (var == NULL)
+ sys_error (r, rec->pos, _("Duplicate variable name `%s'."), name);
+
+ /* Set the short name the same as the long name. */
+ var_set_short_name (var, 0, name);
+
+ /* Get variable label, if any. */
+ if (rec->label)
+ {
+ char *utf8_label;
+
+ utf8_label = recode_string_pool ("UTF-8", dict_encoding,
+ rec->label, -1, r->pool);
+ var_set_label (var, utf8_label);
+ }
+
+ /* Set missing values. */
+ if (rec->missing_value_code != 0)