/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 2009 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
#include <libpspp/str.h>
#include <libpspp/version.h>
+#include <data/attributes.h>
#include <data/case.h>
#include <data/casewriter-provider.h>
#include <data/casewriter.h>
for long string variables. */
};
-static struct casewriter_class sys_file_casewriter_class;
+static const struct casewriter_class sys_file_casewriter_class;
static void write_header (struct sfm_writer *, const struct dictionary *);
static void write_variable (struct sfm_writer *, const struct variable *);
static void write_documents (struct sfm_writer *, const struct dictionary *);
+static void write_data_file_attributes (struct sfm_writer *,
+ const struct dictionary *);
+static void write_variable_attributes (struct sfm_writer *,
+ const struct dictionary *);
+
static void write_int (struct sfm_writer *, int32_t);
static inline void convert_double_to_output_format (double, uint8_t[8]);
static void write_float (struct sfm_writer *, double);
static void write_spaces (struct sfm_writer *, size_t);
static void write_value (struct sfm_writer *, const union value *, int width);
-static void write_case_uncompressed (struct sfm_writer *, struct ccase *);
-static void write_case_compressed (struct sfm_writer *, struct ccase *);
+static void write_case_uncompressed (struct sfm_writer *,
+ const struct ccase *);
+static void write_case_compressed (struct sfm_writer *, const struct ccase *);
static void flush_compressed (struct sfm_writer *);
static void put_cmp_opcode (struct sfm_writer *, uint8_t);
static void put_cmp_number (struct sfm_writer *, double);
{
struct sfm_write_options opts;
opts.create_writeable = true;
- opts.compress = get_scompression ();
+ opts.compress = settings_get_scompression ();
opts.version = 3;
return opts;
}
write_vls_length_table (w, d);
+ if (attrset_count (dict_get_attributes (d)))
+ write_data_file_attributes (w, d);
+ write_variable_attributes (w, d);
+
/* Write end-of-headers record. */
write_int (w, 999);
write_int (w, 0);
}
else
{
- static const char *month_name[12] =
+ static const char *const month_name[12] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
/* Number of missing values. If there is a range, then the
range counts as 2 missing values and causes the number to be
negated. */
- write_int (w, mv_has_range (mv) ? 2 - mv_n_values (mv) : mv_n_values (mv));
+ write_int (w, mv_has_range (mv) ? -2 - mv_n_values (mv) : mv_n_values (mv));
/* Print and write formats. */
write_format (w, *var_get_print_format (v), seg0_width);
if (mv_has_range (mv))
{
double x, y;
- mv_peek_range (mv, &x, &y);
+ mv_get_range (mv, &x, &y);
write_float (w, x);
write_float (w, y);
}
for (i = 0; i < mv_n_values (mv); i++)
{
union value value;
- mv_peek_value (mv, &value, i);
+ mv_get_value (mv, &value, i);
write_value (w, &value, seg0_width);
}
write_bytes (w, dict_get_documents (d), line_cnt * DOC_LINE_LENGTH);
}
+static void
+put_attrset (struct string *string, const struct attrset *attrs)
+{
+ const struct attribute *attr;
+ struct attrset_iterator i;
+
+ for (attr = attrset_first (attrs, &i); attr != NULL;
+ attr = attrset_next (attrs, &i))
+ {
+ size_t n_values = attribute_get_n_values (attr);
+ size_t j;
+
+ ds_put_cstr (string, attribute_get_name (attr));
+ ds_put_char (string, '(');
+ for (j = 0; j < n_values; j++)
+ ds_put_format (string, "'%s'\n", attribute_get_value (attr, j));
+ ds_put_char (string, ')');
+ }
+}
+
+static void
+write_attribute_record (struct sfm_writer *w, const struct string *content,
+ int subtype)
+{
+ write_int (w, 7);
+ write_int (w, subtype);
+ write_int (w, 1);
+ write_int (w, ds_length (content));
+ write_bytes (w, ds_data (content), ds_length (content));
+}
+
+static void
+write_data_file_attributes (struct sfm_writer *w,
+ const struct dictionary *d)
+{
+ struct string s = DS_EMPTY_INITIALIZER;
+ put_attrset (&s, dict_get_attributes (d));
+ write_attribute_record (w, &s, 17);
+ ds_destroy (&s);
+}
+
+static void
+write_variable_attributes (struct sfm_writer *w, const struct dictionary *d)
+{
+ struct string s = DS_EMPTY_INITIALIZER;
+ size_t n_vars = dict_get_var_cnt (d);
+ size_t n_attrsets = 0;
+ size_t i;
+
+ for (i = 0; i < n_vars; i++)
+ {
+ struct variable *v = dict_get_var (d, i);
+ struct attrset *attrs = var_get_attributes (v);
+ if (attrset_count (attrs))
+ {
+ if (n_attrsets++)
+ ds_put_char (&s, '/');
+ ds_put_format (&s, "%s:", var_get_short_name (v, 0));
+ put_attrset (&s, attrs);
+ }
+ }
+ if (n_attrsets)
+ write_attribute_record (w, &s, 18);
+ ds_destroy (&s);
+}
+
/* Write the alignment, width and scale values. */
static void
write_variable_display_parameters (struct sfm_writer *w,
if (ferror (w->file))
{
casewriter_force_error (writer);
- case_destroy (c);
+ case_unref (c);
return;
}
else
write_case_compressed (w, c);
- case_destroy (c);
+ case_unref (c);
}
/* Destroys system file writer W. */
}
/* System file writer casewriter class. */
-static struct casewriter_class sys_file_casewriter_class =
+static const struct casewriter_class sys_file_casewriter_class =
{
sys_file_casewriter_write,
sys_file_casewriter_destroy,
\f
/* Writes case C to system file W, without compressing it. */
static void
-write_case_uncompressed (struct sfm_writer *w, struct ccase *c)
+write_case_uncompressed (struct sfm_writer *w, const struct ccase *c)
{
size_t i;
/* Writes case C to system file W, with compression. */
static void
-write_case_compressed (struct sfm_writer *w, struct ccase *c)
+write_case_compressed (struct sfm_writer *w, const struct ccase *c)
{
size_t i;