These are written by "Stata 14.1/-savespss- 1.77 by S.Radyakin". I think
it's really a bug in that writer, but if SPSS accepts these files then I
guess PSPP should too.
Reported by news <news.ftr@free.fr>.
Bug #47089.
Extension (type 7) records, in ascending numerical order of their
subtypes.
Extension (type 7) records, in ascending numerical order of their
subtypes.
+System files written by SPSS include at most one of each kind of
+extension record. This is generally true of system files written by
+other software as well, with known exceptions noted below in the
+individual sections about each type of record.
+
@item
Dictionary termination record.
@item
Dictionary termination record.
@item char attributes[];
The attributes, in a text-based format.
@item char attributes[];
The attributes, in a text-based format.
-In record type 17, this field contains a single attribute set. An
+In record subtype 17, this field contains a single attribute set. An
attribute set is a sequence of one or more attributes concatenated
together. Each attribute consists of a name, which has the same
syntax as a variable name, followed by, inside parentheses, a sequence
attribute set is a sequence of one or more attributes concatenated
together. Each attribute consists of a name, which has the same
syntax as a variable name, followed by, inside parentheses, a sequence
an attribute with a single value and an attribute array with one
element.
an attribute with a single value and an attribute array with one
element.
-In record type 18, this field contains a sequence of one or more
+In record subtype 18, this field contains a sequence of one or more
variable attribute sets. If more than one variable attribute set is
present, each one after the first is delimited from the previous by
@code{/}. Each variable attribute set consists of a long
variable name,
followed by @code{:}, followed by an attribute set with the same
variable attribute sets. If more than one variable attribute set is
present, each one after the first is delimited from the previous by
@code{/}. Each variable attribute set consists of a long
variable name,
followed by @code{:}, followed by an attribute set with the same
-syntax as on record type 17.
+syntax as on record subtype 17.
+
+System files written by @code{Stata 14.1/-savespss- 1.77 by
+S.Radyakin} may include multiple records with subtype 18, one per
+variable that has variable attributes.
The total length is @code{count} bytes.
@end table
The total length is @code{count} bytes.
@end table
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
#include "libpspp/i18n.h"
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
#include "libpspp/i18n.h"
#include "libpspp/message.h"
#include "libpspp/misc.h"
#include "libpspp/pool.h"
#include "libpspp/message.h"
#include "libpspp/misc.h"
#include "libpspp/pool.h"
struct sfm_extension_record
{
struct sfm_extension_record
{
+ struct ll ll; /* In struct sfm_reader 'var_attrs' list. */
int subtype; /* Record subtype. */
off_t pos; /* Starting offset in file. */
unsigned int size; /* Size of data elements. */
int subtype; /* Record subtype. */
off_t pos; /* Starting offset in file. */
unsigned int size; /* Size of data elements. */
struct sfm_mrset *mrsets;
size_t n_mrsets;
struct sfm_extension_record *extensions[32];
struct sfm_mrset *mrsets;
size_t n_mrsets;
struct sfm_extension_record *extensions[32];
+ struct ll_list var_attrs; /* Contains "struct sfm_extension_record"s. */
/* File state. */
struct file_handle *fh; /* File handle. */
/* File state. */
struct file_handle *fh; /* File handle. */
pool_register (r->pool, free, r);
r->fh = fh_ref (fh);
r->opcode_idx = sizeof r->opcodes;
pool_register (r->pool, free, r);
r->fh = fh_ref (fh);
r->opcode_idx = sizeof r->opcodes;
+ ll_init (&r->var_attrs);
/* TRANSLATORS: this fragment will be interpolated into
messages in fh_lock() that identify types of files. */
/* TRANSLATORS: this fragment will be interpolated into
messages in fh_lock() that identify types of files. */
subtype, PACKAGE_BUGREPORT, PACKAGE_STRING);
return skip_extension_record (r, subtype);
}
subtype, PACKAGE_BUGREPORT, PACKAGE_STRING);
return skip_extension_record (r, subtype);
}
+ else if (subtype == 18)
+ {
+ /* System files written by "Stata 14.1/-savespss- 1.77 by S.Radyakin"
+ put each variable attribute into a separate record with subtype
+ 18. I'm surprised that SPSS puts up with this. */
+ struct sfm_extension_record *ext;
+ bool ok = read_extension_record (r, subtype, &ext);
+ if (ok)
+ ll_push_tail (&r->var_attrs, &ext->ll);
+ return ok;
+ }
else if (r->extensions[subtype] != NULL)
{
sys_warn (r, r->pos,
else if (r->extensions[subtype] != NULL)
{
sys_warn (r, r->pos,
/* data file attributes */
/* variable attributes */
/* long var map */
/* data file attributes */
/* variable attributes */
/* long var map */
parse_long_var_name_map (r, r->extensions[EXT_LONG_NAMES], dict);
/* The following records use long names, so they need to follow renaming. */
parse_long_var_name_map (r, r->extensions[EXT_LONG_NAMES], dict);
/* The following records use long names, so they need to follow renaming. */
- if (r->extensions[EXT_VAR_ATTRS] != NULL)
+ if (!ll_is_empty (&r->var_attrs))
- parse_variable_attributes (r, r->extensions[EXT_VAR_ATTRS], dict);
+ struct sfm_extension_record *ext;
+ ll_for_each (ext, struct sfm_extension_record, ll, &r->var_attrs)
+ parse_variable_attributes (r, ext, dict);
/* Roles use the $@Role attribute. */
assign_variable_roles (r, dict);
}
/* Roles use the $@Role attribute. */
assign_variable_roles (r, dict);
}
if (r->extensions[EXT_LONG_LABELS] != NULL)
parse_long_string_value_labels (r, r->extensions[EXT_LONG_LABELS], dict);
if (r->extensions[EXT_LONG_MISSING] != NULL)
if (r->extensions[EXT_LONG_LABELS] != NULL)
parse_long_string_value_labels (r, r->extensions[EXT_LONG_LABELS], dict);
if (r->extensions[EXT_LONG_MISSING] != NULL)
dnl File header.
"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
2; dnl Layout code
dnl File header.
"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
2; dnl Layout code
-2; dnl Nominal case size
+3; dnl Nominal case size
0; dnl Not compressed
0; dnl Not weighted
0; dnl 1 case.
0; dnl Not compressed
0; dnl Not weighted
0; dnl 1 case.
dnl Variables.
2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
2; 0; 0; 0; 0x050800 *2; s8 "SECONDVA";
dnl Variables.
2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
2; 0; 0; 0; 0x050800 *2; s8 "SECONDVA";
+2; 0; 0; 0; 0x050800 *2; s8 "THIRDVAR";
dnl Machine integer info record.
7; 3; 4; 8; 1; 2; 3; -1; 1; 1; ENDIAN; 1252;
dnl Machine integer info record.
7; 3; 4; 8; 1; 2; 3; -1; 1; 1; ENDIAN; 1252;
7; 13; 1; COUNT (
"FIRSTVAR=FirstVariable"; i8 9;
"SECONDVA=S"; i8 233; "condVariable"; i8 9;
7; 13; 1; COUNT (
"FIRSTVAR=FirstVariable"; i8 9;
"SECONDVA=S"; i8 233; "condVariable"; i8 9;
+"THIRDVAR=ThirdVariable"; i8 9
);
dnl Data file attributes record.
);
dnl Data file attributes record.
"xyzzy('quux'"; i8 10; ")";
);
"xyzzy('quux'"; i8 10; ")";
);
+dnl Another variable attributes record.
+dnl Only system files written by "Stata 14.1/-savespss- 1.77 by S.Radyakin"
+dnl include multiple variable attributes records.
+7; 18; 1; COUNT ("ThirdVariable:fizz('buzz'"; i8 10; ")";);
dnl Character encoding record.
7; 20; 1; 12; "windows-1252";
dnl Character encoding record.
7; 20; 1; 12; "windows-1252";
bert,123"
SécondVariable,"Attribute,Value
xyzzy,quux"
bert,123"
SécondVariable,"Attribute,Value
xyzzy,quux"
+ThirdVariable,"Attribute,Value
+fizz,buzz"
Table: Custom data file attributes.
Attribute,Value
Table: Custom data file attributes.
Attribute,Value
Attribute,Value
xyzzy,quux",2
Attribute,Value
xyzzy,quux",2
+ThirdVariable,"Format: F8.0
+Role: Input
+
+Attribute,Value
+fizz,buzz",3
Table: Custom data file attributes.
Attribute,Value
Table: Custom data file attributes.
Attribute,Value