/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007 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
int flt64_cnt; /* Number of 8-byte units per case. */
struct sfm_var *vars; /* Variables. */
size_t var_cnt; /* Number of variables. */
+ int32_t case_cnt; /* Number of cases */
bool has_long_var_names; /* File has a long variable name map */
bool has_vls; /* File has one or more very long strings? */
name, but we want to retain it, so re-set it
explicitly. */
dict_rename_var (*dict, var, long_name);
- var_set_short_name (var, short_name);
+ var_set_short_name (var, 0, short_name);
}
r->has_long_var_names = true;
pool_free (r->pool, var_by_value_idx);
r->value_cnt = dict_get_next_value_idx (*dict);
- return casereader_create_sequential (NULL, r->value_cnt, CASENUMBER_MAX,
+ return casereader_create_sequential
+ (NULL, r->value_cnt,
+ r->case_cnt == -1 ? CASENUMBER_MAX: r->case_cnt,
&sys_file_casereader_class, r);
}
char rec_type[5];
char eye_catcher[61];
uint8_t raw_layout_code[4];
- int case_cnt;
uint8_t raw_bias[8];
char creation_date[10];
char creation_time[9];
*weight_idx = read_int32 (r);
- case_cnt = read_int32 (r);
- if (case_cnt < -1 || case_cnt > INT_MAX / 2)
- case_cnt = -1;
+ r->case_cnt = read_int32 (r);
+ if ( r->case_cnt > INT_MAX / 2)
+ r->case_cnt = -1;
+
/* Identify floating-point format and obtain compression bias. */
read_bytes (r, raw_bias, sizeof raw_bias);
info->integer_format = r->integer_format;
info->float_format = r->float_format;
info->compressed = r->compressed;
- info->case_cnt = case_cnt;
+ info->case_cnt = r->case_cnt;
product = ss_cstr (eye_catcher);
ss_match_string (&product, ss_cstr ("@(#) SPSS DATA FILE"));
_("Duplicate variable name `%s' within system file."),
name);
- /* Set the short name the same as the long name */
- var_set_short_name (var, var_get_name (var));
+ /* Set the short name the same as the long name. */
+ var_set_short_name (var, 0, var_get_name (var));
/* Get variable label, if any. */
if (has_variable_label != 0 && has_variable_label != 1)
while (read_variable_to_value_map (r, dict, map, &var, &long_name,
&warning_cnt))
{
- char short_name[SHORT_NAME_LEN + 1];
- strcpy (short_name, var_get_short_name (var));
+ char **short_names;
+ size_t short_name_cnt;
+ size_t i;
/* Validate long name. */
if (!var_is_valid_name (long_name, false))
}
/* Identify any duplicates. */
- if (strcasecmp (short_name, long_name)
+ if (strcasecmp (var_get_short_name (var, 0), long_name)
&& dict_lookup_var (dict, long_name) != NULL)
{
sys_warn (r, _("Duplicate long variable name `%s' "
continue;
}
- /* Set long name. Renaming a variable may clear the short
- name, but we want to retain it, so re-set it
- explicitly. */
+ /* Renaming a variable may clear its short names, but we
+ want to retain them, so we save them and re-set them
+ afterward. */
+ short_name_cnt = var_get_short_name_cnt (var);
+ short_names = xnmalloc (short_name_cnt, sizeof *short_names);
+ for (i = 0; i < short_name_cnt; i++)
+ {
+ const char *s = var_get_short_name (var, i);
+ short_names[i] = s != NULL ? xstrdup (s) : NULL;
+ }
+
+ /* Set long name. */
dict_rename_var (dict, var, long_name);
- var_set_short_name (var, short_name);
+
+ /* Restore short names. */
+ for (i = 0; i < short_name_cnt; i++)
+ {
+ var_set_short_name (var, i, short_names[i]);
+ free (short_names[i]);
+ }
}
close_variable_to_value_map (r, map);
r->has_long_var_names = true;
static void partial_record (struct sfm_reader *r)
NO_RETURN;
+
+static void read_error (struct casereader *, const struct sfm_reader *);
+
+
static bool read_case_number (struct sfm_reader *, double *);
static bool read_case_string (struct sfm_reader *, char *, size_t);
static int read_opcode (struct sfm_reader *);
sizeof (union value) * r->flt64_cnt))
{
case_destroy (c);
+ if ( r->case_cnt != -1 )
+ read_error (reader, r);
return false;
}
case_destroy (c);
if (i != 0)
partial_record (r);
+ if ( r->case_cnt != -1 )
+ read_error (reader, r);
return false;
}
}
sys_error (r, _("File ends in partial case."));
}
+static void
+read_error (struct casereader *r, const struct sfm_reader *sfm)
+{
+ msg (ME, _("Error reading case from file %s"), fh_get_name (sfm->fh));
+ casereader_force_error (r);
+}
+
/* Reads a number from R and stores its value in *D.
If R is compressed, reads a compressed number;
otherwise, reads a number in the regular way.
/* First try looking up by full name. This often succeeds. */
var = dict_lookup_var (d, short_name);
- if (var != NULL && !strcasecmp (var_get_short_name (var), short_name))
+ if (var != NULL && !strcasecmp (var_get_short_name (var, 0), short_name))
return var;
/* Iterate through the whole dictionary as a fallback. */
for (i = 0; i < var_cnt; i++)
{
var = dict_get_var (d, i);
- if (!strcasecmp (var_get_short_name (var), short_name))
+ if (!strcasecmp (var_get_short_name (var, 0), short_name))
return var;
}