From 008fe5fdec4f94535df888ff8cdd94f802a3660d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 8 Feb 2014 08:56:45 -0800 Subject: [PATCH] sys-file-reader: Successfully read files with duplicate names. This allows PSPP to read some files written by SPSS. Bug #41475. --- NEWS | 3 +++ doc/dev/system-file-format.texi | 7 +++++++ src/data/sys-file-reader.c | 11 +++++++++-- tests/data/sys-file-reader.at | 17 +++++++++++++++-- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 4e7581c243..57de7877b2 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,9 @@ Changes since 0.8.2: - File|Display Data File Information|External File... now allows an encoding to be selected. + * System files that contain duplicate variable names may now be read + successfully (bug #41475). + Changes from 0.8.1 to 0.8.2: * Charts are now rendered with colours from the Tango palette instead diff --git a/doc/dev/system-file-format.texi b/doc/dev/system-file-format.texi index 0da1997b3f..a480195857 100644 --- a/doc/dev/system-file-format.texi +++ b/doc/dev/system-file-format.texi @@ -316,6 +316,13 @@ the at-sign (@samp{@@}). Subsequent characters may also be digits, octothorpes (@samp{#}), dollar signs (@samp{$}), underscores (@samp{_}), or full stops (@samp{.}). The variable name is padded on the right with spaces. +The @samp{name} fields should be unique within a system file. System +files written by SPSS that contain very long string variables with +similar names sometimes contain duplicate names that are later +eliminated by resolving the very long string names (@pxref{Very Long +String Record}). PSPP handles duplicates by assigning them new, +unique names. + @item int32 label_len; This field is present only if @code{has_var_label} is set to 1. It is set to the length, in characters, of the variable label. The diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index 9a4ef86042..2c18abe322 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-2000, 2006-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2006-2007, 2009-2014 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 @@ -1090,7 +1090,14 @@ parse_variable_records (struct sfm_reader *r, struct dictionary *dict, var = rec->var = dict_create_var (dict, name, rec->width); if (var == NULL) - sys_error (r, rec->pos, _("Duplicate variable name `%s'."), name); + { + 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); + free (new_name); + } /* Set the short name the same as the long name. */ var_set_short_name (var, 0, name); diff --git a/tests/data/sys-file-reader.at b/tests/data/sys-file-reader.at index 60d5ff7054..3bbc8060d6 100644 --- a/tests/data/sys-file-reader.at +++ b/tests/data/sys-file-reader.at @@ -1755,6 +1755,8 @@ do done AT_CLEANUP +dnl SPSS-generated system file can contain duplicate variable names +dnl (see bug #41475). AT_SETUP([duplicate variable name]) AT_KEYWORDS([sack synthetic system file negative]) AT_DATA([sys-file.sack], [dnl @@ -1777,9 +1779,20 @@ do AT_CHECK_UNQUOTED([sack --$[1] sys-file.sack > sys-file.sav], [0], [], [$[2] ]) AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'. +DISPLAY DICTIONARY. ]) - AT_CHECK([pspp -O format=csv sys-file.sps], [1], - [error: `sys-file.sav' near offset 0xd4: Duplicate variable name `VAR1'. + AT_CHECK([pspp -O format=csv sys-file.sps], [0], + [warning: `sys-file.sav' near offset 0xd4: Renaming variable with duplicate name `VAR1' to `VAR001'. + +Variable,Description,,Position +var1,Format: F8.0,,1 +,Measure: Scale,, +,Display Alignment: Right,, +,Display Width: 8,, +var001,Format: F8.0,,2 +,Measure: Scale,, +,Display Alignment: Right,, +,Display Width: 8,, ]) done AT_CLEANUP -- 2.30.2