You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
#include "sfm-read.h"
static void
corrupt_msg (int class, const char *format,...)
{
- char buf[1024];
-
- {
- va_list args;
-
- va_start (args, format);
- vsnprintf (buf, 1024, format, args);
- va_end (args);
- }
-
- {
- struct error e;
+ struct error e;
+ va_list args;
- e.class = class;
- getl_location (&e.where.filename, &e.where.line_number);
- e.title = _("corrupt system file: ");
- e.text = buf;
+ e.class = class;
+ getl_location (&e.where.filename, &e.where.line_number);
+ e.title = _("corrupt system file: ");
- err_vmsg (&e);
- }
+ va_start (args, format);
+ err_vmsg (&e, format, args);
+ va_end (args);
}
/* Closes a system file after we're done with it. */
int32 count P;
}
data;
+ unsigned long bytes;
int skip = 0;
bswap_int32 (&data.size);
bswap_int32 (&data.count);
}
+ bytes = data.size * data.count;
+ if (bytes < data.size || bytes < data.count)
+ lose ((ME, "%s: Record type %d subtype %d too large.",
+ handle_get_filename (r->fh), rec_type, data.subtype));
switch (data.subtype)
{
break;
case 5:
- case 6:
- case 11: /* ?? Used by SPSS 8.0. */
+ case 6: /* ?? Used by SPSS 8.0. */
skip = 1;
break;
+
+ case 11: /* Variable display parameters */
+ {
+ const int n_vars = data.count / 3 ;
+ int i;
+ if ( data.count % 3 )
+ {
+ msg (MW, _("%s: Invalid subrecord length. "
+ "Record: 7; Subrecord: 11"),
+ handle_get_filename (r->fh));
+ skip = 1;
+ }
+
+ for ( i = 0 ; i < n_vars ; ++i )
+ {
+ struct
+ {
+ int32 measure P;
+ int32 width P;
+ int32 align P;
+ }
+ params;
+
+ struct variable *v;
+
+ assertive_buf_read (r, ¶ms, sizeof(params), 0);
+
+ v = dict_get_var(*dict, i);
+
+ v->measure = params.measure;
+ v->display_width = params.width;
+ v->alignment = params.align;
+ }
+ }
+ break;
+
+ case 13: /* SPSS 12.0 Long variable name map */
+ {
+ char *buf, *short_name, *save_ptr;
+ int idx;
+
+ /* Read data. */
+ buf = xmalloc (bytes + 1);
+ if (!buf_read (r, buf, bytes, 0))
+ {
+ free (buf);
+ goto error;
+ }
+ buf[bytes] = '\0';
+
+ /* Parse data. */
+ for (short_name = strtok_r (buf, "=", &save_ptr), idx = 0;
+ short_name != NULL;
+ short_name = strtok_r (NULL, "=", &save_ptr), idx++)
+ {
+ char *long_name = strtok_r (NULL, "\t", &save_ptr);
+ struct variable *v;
+
+ /* Validate long name. */
+ if (long_name == NULL)
+ {
+ msg (MW, _("%s: Trailing garbage in long variable "
+ "name map."),
+ handle_get_filename (r->fh));
+ break;
+ }
+ if (!var_is_valid_name (long_name, false))
+ {
+ msg (MW, _("%s: Long variable mapping to invalid "
+ "variable name `%s'."),
+ handle_get_filename (r->fh), long_name);
+ break;
+ }
+
+ /* Find variable using short name. */
+ v = dict_lookup_var (*dict, short_name);
+ if (v == NULL)
+ {
+ msg (MW, _("%s: Long variable mapping for "
+ "nonexistent variable %s."),
+ handle_get_filename (r->fh), short_name);
+ break;
+ }
+
+ /* Set long name.
+ Renaming a variable may clear the short
+ name, but we want to retain it, so
+ re-set it explicitly. */
+ dict_rename_var (*dict, v, long_name);
+ var_set_short_name (v, short_name);
+
+ /* For compatability, make sure dictionary
+ is in long variable name map order. In
+ the common case, this has no effect,
+ because the dictionary and the long
+ variable name map are already in the
+ same order. */
+ dict_reorder_var (*dict, v, idx);
+ }
+
+ /* Free data. */
+ free (buf);
+ }
+ break;
default:
msg (MW, _("%s: Unrecognized record type 7, subtype %d "
int next_value = 0; /* Index to next `value' structure. */
size_t var_cap = 0;
+ assert(r);
+
/* Allocate variables. */
*var_by_idx = xmalloc (sizeof **var_by_idx * r->value_cnt);
name[0] = toupper ((unsigned char) (sv.name[0]));
/* Copy remaining characters of variable name. */
- for (j = 1; j < 8; j++)
+ for (j = 1; j < SHORT_NAME_LEN; j++)
{
int c = (unsigned char) sv.name[j];
if (vv == NULL)
lose ((ME, _("%s: Duplicate variable name `%s' within system file."),
handle_get_filename (r->fh), name));
+ var_set_short_name (vv, vv->name);
/* Case reading data. */
nv = sv.type == 0 ? 1 : DIV_RND_UP (sv.type, sizeof (flt64));
"length %d."),
handle_get_filename (r->fh), vv->name, len));
- /* Read label into variable structure. */
- vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
- if (vv->label == NULL)
- goto error;
- vv->label[len] = '\0';
+ if ( len != 0 )
+ {
+ /* Read label into variable structure. */
+ vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
+ if (vv->label == NULL)
+ goto error;
+ vv->label[len] = '\0';
+ }
}
/* Set missing values. */
static void *
buf_read (struct sfm_reader *r, void *buf, size_t byte_cnt, size_t min_alloc)
{
- if (buf == NULL)
+ assert (r);
+
+ if (buf == NULL && byte_cnt > 0 )
buf = xmalloc (max (byte_cnt, min_alloc));
+
+ if ( byte_cnt == 0 )
+ return buf;
+
+
if (1 != fread (buf, byte_cnt, 1, r->file))
{
if (ferror (r->file))